#W# Rework: Complete rework of ThiefPedestals.

This commit is contained in:
WarrentyExpired 2026-10-24 17:45:20 -04:00
parent a440cb72d1
commit bc3c5143b9
4 changed files with 443 additions and 221 deletions

View file

@ -8,35 +8,12 @@ using Server.Network;
namespace Server.Custom namespace Server.Custom
{ {
[SerializationGenerator(0)] [SerializationGenerator(0)]
public partial class ThiefPedestal1 : ThiefPedestal { [Constructible] public ThiefPedestal1() : base(1) { } public ThiefPedestal1(Serial serial) : base(serial) { } } public partial class ThiefPedestalProp : Item
[SerializationGenerator(0)]
public partial class ThiefPedestal2 : ThiefPedestal { [Constructible] public ThiefPedestal2() : base(2) { } public ThiefPedestal2(Serial serial) : base(serial) { } }
[SerializationGenerator(0)]
public partial class ThiefPedestal3 : ThiefPedestal { [Constructible] public ThiefPedestal3() : base(3) { } public ThiefPedestal3(Serial serial) : base(serial) { } }
[SerializationGenerator(0)]
public partial class ThiefPedestal4 : ThiefPedestal { [Constructible] public ThiefPedestal4() : base(4) { } public ThiefPedestal4(Serial serial) : base(serial) { } }
[SerializationGenerator(0)]
public partial class ThiefPedestal5 : ThiefPedestal { [Constructible] public ThiefPedestal5() : base(5) { } public ThiefPedestal5(Serial serial) : base(serial) { } }
[SerializationGenerator(0)]
public partial class ThiefPedestal6 : ThiefPedestal { [Constructible] public ThiefPedestal6() : base(6) { } public ThiefPedestal6(Serial serial) : base(serial) { } }
// ==========================================
// 1. THE CUSTOM BAG
// ==========================================
[SerializationGenerator(0)]
public partial class ThiefPedestalBag : Bag
{ {
// Links this bag to the pedestal that spawned it
[SerializableField(0)] [SerializableField(0)]
private ThiefPedestal m_Pedestal; private ThiefPedestal m_Pedestal;
private Timer m_DecayTimer; public ThiefPedestalProp(ThiefPedestal pedestal) : base(0xE76)
public ThiefPedestalBag(ThiefPedestal pedestal)
{ {
m_Pedestal = pedestal; m_Pedestal = pedestal;
Hue = 0x8A5; Hue = 0x8A5;
@ -44,99 +21,53 @@ namespace Server.Custom
Movable = false; Movable = false;
} }
// Called when the player successfully heists the entire bag public override void OnDoubleClick(Mobile from)
public void ClearTether()
{ {
m_Pedestal = null; if (m_Pedestal != null && !m_Pedestal.Deleted)
m_DecayTimer?.Stop();
m_DecayTimer = null;
}
// Triggers every time an item is removed from the bag
public override void OnItemRemoved(Item item)
{
base.OnItemRemoved(item); // Match the new single-parameter signature
// If the bag was already successfully stolen, act like a normal bag
if (m_Pedestal == null) return;
// Attempt to find the thief (if it went into their backpack, they are the RootParent)
Mobile from = item.RootParent as Mobile;
if (Items.Count == 0)
{ {
// Mechanic 1: The bag is empty. Destroy it immediately. m_Pedestal.OnDoubleClick(from);
if (from != null)
{
from.SendMessage(89, "As you take the last item, the bag crumbles to dust!");
}
m_Pedestal.SinkAndDestroy();
Delete();
}
else if (m_DecayTimer == null)
{
// Mechanic 2: The bag was disturbed but not emptied. Start a 5-minute decay.
if (from != null)
{
from.SendMessage(33, "The bag's magical tether has been disturbed! It begins to rapidly decay.");
}
m_DecayTimer = Timer.DelayCall(TimeSpan.FromMinutes(1), () =>
{
if (m_Pedestal != null && !Deleted)
{
m_Pedestal.SinkAndDestroy();
Delete();
}
});
} }
} }
public ThiefPedestalBag(Serial serial) : base(serial) { } public ThiefPedestalProp(Serial serial) : base(serial) { }
} }
// ==========================================
// 2. THE PEDESTAL
// ==========================================
[SerializationGenerator(0)] [SerializationGenerator(0)]
public partial class ThiefPedestal : Item public partial class ThiefPedestal : Item
{ {
[SerializableField(0)] [SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)] private int m_TrapDifficulty;
private int m_Level;
[SerializableField(1)] [SerializableField(1)]
private ThiefPedestalBag m_LootBag; private ThiefPedestalProp m_PropBag;
// Tracks how many times a player has failed
[SerializableField(2)]
private int m_Tries;
[Constructible] [Constructible]
public ThiefPedestal() : this(1) { } public ThiefPedestal() : base(0x32F2)
[Constructible]
public ThiefPedestal(int level) : base(0x32F2)
{ {
Movable = false; Movable = false;
m_Level = level;
Name = "an ancient pedestal"; Name = "an ancient pedestal";
//SpawnBag();
m_TrapDifficulty = Utility.RandomMinMax(1, 6);
} }
public void SinkAndDestroy() public void SinkAndDestroy()
{ {
if (Deleted) return; if (Deleted) return;
Effects.SendLocationEffect(Location, Map, 0x3728, 10); // Puff of smoke Effects.SendLocationEffect(Location, Map, 0x3728, 10);
Effects.PlaySound(Location, Map, 0x247); // Sound of grinding stone Effects.PlaySound(Location, Map, 0x247);
Delete(); Delete();
} }
public override void OnDelete() public override void OnDelete()
{ {
// If the pedestal is deleted by a GM or Spawner, clean up the tethered bag if (m_PropBag != null && !m_PropBag.Deleted)
if (m_LootBag != null && !m_LootBag.Deleted)
{ {
m_LootBag.Delete(); m_PropBag.Delete();
} }
base.OnDelete(); base.OnDelete();
@ -148,14 +79,13 @@ namespace Server.Custom
if (Map != null && Map != Map.Internal) if (Map != null && Map != Map.Internal)
{ {
if (m_LootBag == null || m_LootBag.Deleted) if (m_PropBag == null || m_PropBag.Deleted)
{ {
SpawnBag(); SpawnPropBag();
} }
else else
{ {
// If a GM changes the facet, move the bag with it m_PropBag.MoveToWorld(new Point3D(X, Y, Z + 6), Map);
m_LootBag.MoveToWorld(new Point3D(X, Y, Z + 6), Map);
} }
} }
} }
@ -164,119 +94,104 @@ namespace Server.Custom
{ {
base.OnLocationChange(oldLocation); base.OnLocationChange(oldLocation);
// If a GM uses the [Move command, drag the bag with the pedestal if (Map != null && Map != Map.Internal && m_PropBag != null && !m_PropBag.Deleted)
if (Map != null && Map != Map.Internal && m_LootBag != null && !m_LootBag.Deleted)
{ {
m_LootBag.MoveToWorld(new Point3D(X, Y, Z + ItemData.Height), Map); m_PropBag.MoveToWorld(new Point3D(X, Y, Z + 6), Map);
} }
} }
public void SpawnBag() public void SpawnPropBag()
{ {
if (m_LootBag != null && !m_LootBag.Deleted) return; if (m_PropBag != null && !m_PropBag.Deleted) return;
if (Map == null || Map == Map.Internal) return; if (Map == null || Map == Map.Internal) return;
m_LootBag = new ThiefPedestalBag(this);
// Fill it with scaling gold and gems m_PropBag = new ThiefPedestalProp(this);
m_LootBag.DropItem(new Gold(m_Level * 500, m_Level * 1000)); m_PropBag.MoveToWorld(new Point3D(X, Y, Z + 6), Map);
for (int i = 0; i < m_Level; i++)
{
m_LootBag.DropItem(Loot.RandomGem());
}
// Move the bag to the exact top of the pedestal dynamically
m_LootBag.MoveToWorld(new Point3D(X, Y, Z + 6), Map);
} }
public override void OnDoubleClick(Mobile from) public override void OnDoubleClick(Mobile from)
{ {
if (!from.InRange(GetWorldLocation(), 1)) if (!from.InRange(GetWorldLocation(), 1))
{ {
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that. from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045);
return; return;
} }
if (m_LootBag == null || m_LootBag.Deleted) if (m_PropBag == null || m_PropBag.Deleted)
{ {
from.SendMessage("The pedestal is currently empty. The mechanism is resetting."); from.SendMessage("The pedestal is currently empty. The mechanism is resetting.");
return; return;
} }
// Calculate max tries: Base 5 attempts, +1 attempt for every 200 Luck
int playerLuck = Math.Max(0, from.Luck);
int maxTries = 5 + (playerLuck / 200);
if (m_Tries >= maxTries)
{
from.SendMessage(33, "Your fingers were not nimble enough and the counterweight slams down! The mechanism destroys the loot.");
m_PropBag.Delete();
m_PropBag = null;
Timer.DelayCall(TimeSpan.FromSeconds(3), SinkAndDestroy);
return;
}
from.SendMessage("You attempt to carefully swap the bag with a counterweight..."); from.SendMessage("You attempt to carefully swap the bag with a counterweight...");
// --- THE UNIFIED TIER MATH --- // 1. Snooping / Trap Check (Linear 0-125 Chance)
double minSkill = m_Level switch if (!from.CheckSkill(SkillName.Snooping, 0, 125))
{ {
1 => 15.0, m_Tries++;
2 => 35.0,
3 => 55.0,
4 => 75.0,
5 => 90.0,
6 => 100.1,
_ => m_Level * 16.7
};
double maxSkill = minSkill + 25.0; // If Snooping fails, roll RemoveTrap to see if they dodge the explosion/poison
if (from.CheckSkill(SkillName.RemoveTrap, 0, 125))
// 1. Snooping Check {
if (from.Skills.Snooping.Value < minSkill) from.SendMessage(54, "You trigger a pressure plate, but your knowledge of traps allows you to pull your hands back just in time!");
{ }
from.SendMessage(33, "You don't even understand how this pressure plate works!"); else
TriggerTrap(from); {
from.SendMessage(33, "You miscalculate the exact weight needed for the pressure plate!");
TriggerTrap(from);
}
return; return;
} }
if (!from.CheckSkill(SkillName.Snooping, minSkill, maxSkill)) // 2. Stealing Check (Linear 0-125 Chance)
if (!from.CheckSkill(SkillName.Stealing, 0, 125))
{ {
from.SendMessage(33, "You miscalculate the exact weight needed for the pressure plate!"); m_Tries++;
TriggerTrap(from); from.SendMessage(33, "Your hand slips during the swap! You carefully reset your grip to try again.");
return; return;
} }
// 2. Stealing Check // 3. Success
if (from.Skills.Stealing.Value < minSkill)
{
from.SendMessage(33, "Your hands aren't fast enough for a heist of this caliber!");
TriggerTrap(from);
return;
}
if (!from.CheckSkill(SkillName.Stealing, minSkill, maxSkill))
{
from.SendMessage(33, "Your hand slips during the swap!");
TriggerTrap(from);
return;
}
// 3. Success!
from.SendMessage(89, "In a blur of motion, you swap the bag with a stone! The trap remains silent."); from.SendMessage(89, "In a blur of motion, you swap the bag with a stone! The trap remains silent.");
from.PlaySound(0x248); from.PlaySound(0x248);
m_LootBag.ClearTether(); // Untether the bag so it stops decaying m_PropBag.Delete();
m_LootBag.Movable = true; m_PropBag = null;
from.AddToBackpack(m_LootBag);
m_LootBag = null; ThiefPedestalLootBag loot = new ThiefPedestalLootBag();
from.AddToBackpack(loot);
Timer.DelayCall(TimeSpan.FromSeconds(3), SinkAndDestroy); Timer.DelayCall(TimeSpan.FromSeconds(3), SinkAndDestroy);
} }
private void TriggerTrap(Mobile m) private void TriggerTrap(Mobile m)
{ {
// 50/50 chance to either deal physical damage or apply poison // Note: The trap no longer deletes the bag! It only punishes the player's health.
if (Utility.RandomBool()) if (Utility.RandomBool())
{ {
// --- POISON TRAP --- m.PlaySound(0x22F);
m.PlaySound(0x22F); // Poison gas sound Effects.SendLocationEffect(Location, Map, 0x3728, 15);
Effects.SendLocationEffect(Location, Map, 0x3728, 15); // Puff of smoke visual
Poison trapPoison = m_Level switch Poison trapPoison = m_TrapDifficulty switch
{ {
1 => Poison.Lesser, 1 => Poison.Lesser,
2 => Poison.Regular, 2 => Poison.Regular,
3 => Poison.Greater, 3 => Poison.Greater,
4 => Poison.Deadly, 4 => Poison.Deadly,
_ => Poison.Lethal // Level 5 and 6 apply Lethal poison _ => Poison.Lethal
}; };
m.ApplyPoison(m, trapPoison); m.ApplyPoison(m, trapPoison);
@ -284,26 +199,13 @@ namespace Server.Custom
} }
else else
{ {
// --- EXPLOSION TRAP --- m.PlaySound(0x207);
m.PlaySound(0x207); // Explosion sound Effects.SendLocationEffect(Location, Map, 0x36BD, 15);
Effects.SendLocationEffect(Location, Map, 0x36BD, 15); // Large explosion visual
int damage = Utility.RandomMinMax(20, 35); int damage = Utility.RandomMinMax(20, 35);
// 100% Physical damage to respect UOR armor ratings
AOS.Damage(m, damage, 100, 0, 0, 0, 0); AOS.Damage(m, damage, 100, 0, 0, 0, 0);
m.SendMessage(33, "The pedestal detonates, blasting you with shrapnel!"); m.SendMessage(33, "The pedestal detonates, blasting you with shrapnel!");
} }
// Destroy the bag so players cannot just tank the hit and grab the loot
if (m_LootBag != null && !m_LootBag.Deleted)
{
m_LootBag.Delete();
m_LootBag = null;
m.SendMessage(33, "The trap's mechanism destroys the loot in the process!");
Timer.DelayCall(TimeSpan.FromSeconds(3), SinkAndDestroy);
}
} }
public ThiefPedestal(Serial serial) : base(serial) { } public ThiefPedestal(Serial serial) : base(serial) { }
@ -311,9 +213,9 @@ namespace Server.Custom
[AfterDeserialization] [AfterDeserialization]
private void AfterDeserialization() private void AfterDeserialization()
{ {
if (m_LootBag == null || m_LootBag.Deleted) if (m_PropBag == null || m_PropBag.Deleted)
{ {
SpawnBag(); SpawnPropBag();
} }
} }
} }

View file

@ -0,0 +1,255 @@
using System;
using ModernUO.Serialization;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class ThiefPedestalLootBag : Bag
{
private static int GetWeightedTier()
{
var roll = Utility.Random(100);
if (roll < 25) return 0; // 25% chance (Rolls 0-24)
else if (roll < 55) return 1; // 30% chance (Rolls 25-54)
else if (roll < 75) return 2; // 20% chance (Rolls 55-74)
else if (roll < 90) return 3; // 15% chance (Rolls 75-89)
else if (roll < 96) return 4; // 6% chance (Rolls 90-95)
else if (roll < 99) return 5; // 3% chance (Rolls 96-98)
else return 6; // 1% chance (Rolls 99)
}
private static void GetRandomLevel(out int attributeCount, out int min, out int max)
{
var pwr = GetWeightedTier();
if (pwr == 1)
{
attributeCount = 1;
min = 10;
max = 20;
}
else if (pwr == 2)
{
attributeCount = Utility.RandomMinMax(1, 2);
min = 20;
max = 40;
}
else if (pwr == 3)
{
attributeCount = Utility.RandomMinMax(2, 3);
min = 30;
max = 60;
}
else if (pwr == 4)
{
attributeCount = Utility.RandomMinMax(2, 4);
min = 40;
max = 80;
}
else if (pwr == 5)
{
attributeCount = Utility.RandomMinMax(3, 5);
min = 60;
max = 80;
}
else if (pwr == 6)
{
attributeCount = Utility.RandomMinMax(4, 5);
min = 60;
max = 100;
}
else
{
attributeCount = 1;
min = 5;
max = 10;
}
}
private static void GetRandomResists(out int phy, out int fire, out int cold, out int poison, out int energy)
{
var pwr = GetWeightedTier();
if (pwr == 1)
{
phy = Utility.RandomMinMax(1, 3);
fire = Utility.RandomMinMax(1, 3);
cold = Utility.RandomMinMax(1, 3);
poison = Utility.RandomMinMax(1, 3);
energy = Utility.RandomMinMax(1, 3);
}
else if (pwr == 2)
{
phy = Utility.RandomMinMax(2, 5);
fire = Utility.RandomMinMax(2, 5);
cold = Utility.RandomMinMax(2, 5);
poison = Utility.RandomMinMax(2, 5);
energy = Utility.RandomMinMax(2, 5);
}
else if (pwr == 3)
{
phy = Utility.RandomMinMax(4, 7);
fire = Utility.RandomMinMax(4, 7);
cold = Utility.RandomMinMax(4, 7);
poison = Utility.RandomMinMax(4, 7);
energy = Utility.RandomMinMax(4, 7);
}
else if (pwr == 4)
{
phy = Utility.RandomMinMax(6, 10);
fire = Utility.RandomMinMax(6, 10);
cold = Utility.RandomMinMax(6, 10);
poison = Utility.RandomMinMax(6, 10);
energy = Utility.RandomMinMax(6, 10);
}
else if (pwr == 5)
{
phy = Utility.RandomMinMax(9, 12);
fire = Utility.RandomMinMax(9, 12);
cold = Utility.RandomMinMax(9, 12);
poison = Utility.RandomMinMax(9, 12);
energy = Utility.RandomMinMax(9, 12);
}
else if (pwr == 6)
{
phy = Utility.RandomMinMax(12, 15);
fire = Utility.RandomMinMax(12, 15);
cold = Utility.RandomMinMax(12, 15);
poison = Utility.RandomMinMax(12, 15);
energy = Utility.RandomMinMax(12, 15);
}
else
{
phy = 0;
fire = 0;
cold = 0;
poison = 0;
energy = 0;
}
}
[Constructible]
public ThiefPedestalLootBag()
{
int bagTier = GetWeightedTier();
int weaponCount = Utility.RandomMinMax(0, bagTier);
for (var i = 0; i < weaponCount; i++)
{
var weapon = Loot.RandomWeapon();
GetRandomLevel(out var attributeCount, out var min, out var max);
BaseRunicTool.ApplyAttributesTo(weapon, attributeCount, min, max);
DropItem(weapon);
}
int armorCount = Utility.RandomMinMax(0, bagTier);
for (var i = 0; i < armorCount; i++)
{
var armor = Loot.RandomArmorOrShield();
GetRandomLevel(out var attributeCount, out var min, out var max);
BaseRunicTool.ApplyAttributesTo(armor, attributeCount, min, max);
GetRandomResists(out var phy, out var fire, out var cold, out var poison, out var energy);
armor.PhysicalBonus = phy;
armor.FireBonus = fire;
armor.ColdBonus = cold;
armor.PoisonBonus = poison;
armor.EnergyBonus = energy;
DropItem(armor);
}
int jewelryCount = Utility.RandomMinMax(0, bagTier);
for (var i = 0; i < jewelryCount; i++)
{
var jewelry = Loot.RandomJewelry();
GetRandomLevel(out var attributeCount, out var min, out var max);
BaseRunicTool.ApplyAttributesTo(jewelry, attributeCount, min, max);
DropItem(jewelry);
}
int reagentCount = Utility.RandomMinMax(0, bagTier);
for (var i = 0; i < reagentCount; i++)
{
var reagents = Loot.RandomReagent();
reagents.Amount = Math.Max(1, GetWeightedTier() * 2);
DropItem(reagents);
}
int necroreagentCount = Utility.RandomMinMax(0, bagTier);
for (var i = 0; i < necroreagentCount; i++)
{
var necroreagents = Loot.RandomNecromancyReagent();
necroreagents.Amount = Math.Max(1, GetWeightedTier() * 2);
DropItem(necroreagents);
}
int gemCount = Utility.RandomMinMax(0, bagTier);
for (var i = 0; i < gemCount; i++)
{
var gems = Loot.RandomGem();
gems.Amount = Math.Max(1, bagTier * 2);
DropItem(gems);
}
int mageScrollCount = Utility.RandomMinMax(0, bagTier);
int mlevel = 0;
if (bagTier < 3)
{
mlevel = 42;
}
else
{
mlevel = 63;
}
for (var i = 0; i < mageScrollCount; i++)
{
var scroll = Loot.RandomScroll(0, mlevel, SpellbookType.Regular);
scroll.Amount = Math.Max(1, bagTier);
DropItem(scroll);
}
int necroScrollCount = Utility.RandomMinMax(0, bagTier);
int nlevel = 0;
if (bagTier < 3)
{
nlevel = 6;
}
else
{
nlevel = 15;
}
for (var i = 0; i < necroScrollCount; i++)
{
var scroll = Loot.RandomScroll(0, nlevel, SpellbookType.Necromancer);
scroll.Amount = Math.Max(1, bagTier);
DropItem(scroll);
}
for (var i = Math.Max(1, bagTier); i > 0; i--)
{
DropItem(Loot.RandomPotion());
}
for (var i = Math.Max(1, bagTier); i > 0; i--)
{
DropItem(Loot.RandomClothing());
}
if (bagTier > 3)
{
if (Utility.RandomBool())
{
DropItem(new Arrow((bagTier + (Utility.RandomMinMax(10, 20)))));
}
else
{
DropItem(new Bolt((bagTier + (Utility.RandomMinMax(10, 20)))));
}
DropItem(new BlankScroll(Math.Max(1, GetWeightedTier())));
}
int minGold = 100 + (bagTier * 100);
int maxGold = minGold + 99;
DropItem(new Gold(Utility.RandomMinMax(minGold, maxGold)));
}
}

View file

@ -3,60 +3,130 @@ using ModernUO.Serialization;
namespace Server.Items; namespace Server.Items;
// ==============================================================
// LEVEL 4: 99% Trapped / 99% Locked (1% Lottery Ticket!)
// ==============================================================
[SerializationGenerator(0, false)] [SerializationGenerator(0, false)]
public partial class RandomLootBag : Bag public partial class RandomLootBag : Bag
{ {
private static void GetRandomAOSStats(out int attributeCount, out int min, out int max) private static int GetWeightedTier()
{ {
var rnd = Utility.Random(15); var roll = Utility.Random(100);
if (rnd < 1) if (roll < 25) return 0; // 25% chance (Rolls 0-24)
{ else if (roll < 55) return 1; // 30% chance (Rolls 25-54)
attributeCount = Utility.RandomMinMax(2, 5); else if (roll < 75) return 2; // 20% chance (Rolls 55-74)
min = 20; else if (roll < 90) return 3; // 15% chance (Rolls 75-89)
max = 70; else if (roll < 96) return 4; // 6% chance (Rolls 90-95)
} else if (roll < 99) return 5; // 3% chance (Rolls 96-98)
else if (rnd < 3) else return 6; // 1% chance (Rolls 99)
{ }
attributeCount = Utility.RandomMinMax(2, 4);
min = 20; private static void GetRandomLevel(out int attributeCount, out int min, out int max)
max = 50; {
} var pwr = GetWeightedTier();
else if (rnd < 6)
{ if (pwr == 1)
attributeCount = Utility.RandomMinMax(2, 3);
min = 20;
max = 40;
}
else if (rnd < 10)
{
attributeCount = Utility.RandomMinMax(1, 2);
min = 10;
max = 30;
}
else
{ {
attributeCount = 1; attributeCount = 1;
min = 10; min = 10;
max = 20; max = 20;
} }
else if (pwr == 2)
{
attributeCount = Utility.RandomMinMax(1, 2);
min = 20;
max = 40;
}
else if (pwr == 3)
{
attributeCount = Utility.RandomMinMax(2, 3);
min = 30;
max = 60;
}
else if (pwr == 4)
{
attributeCount = Utility.RandomMinMax(2, 4);
min = 40;
max = 80;
}
else if (pwr == 5)
{
attributeCount = Utility.RandomMinMax(3, 5);
min = 60;
max = 80;
}
else if (pwr == 6)
{
attributeCount = Utility.RandomMinMax(4, 5);
min = 60;
max = 100;
}
else
{
attributeCount = 1;
min = 5;
max = 10;
}
} }
private static void GetRandomResists(out int phy, out int fire, out int cold, out int poison, out int energy) private static void GetRandomResists(out int phy, out int fire, out int cold, out int poison, out int energy)
{ {
var phyR = Utility.Random(1, 15); var pwr = GetWeightedTier();
phy = phyR;
var fireR = Utility.Random(1, 15); if (pwr == 1)
fire = fireR; {
var coldR = Utility.Random(1, 15); phy = Utility.RandomMinMax(1, 3);
cold = coldR; fire = Utility.RandomMinMax(1, 3);
var poisonR = Utility.Random(1, 15); cold = Utility.RandomMinMax(1, 3);
poison = poisonR; poison = Utility.RandomMinMax(1, 3);
var energyR = Utility.Random(1, 15); energy = Utility.RandomMinMax(1, 3);
energy = energyR; }
else if (pwr == 2)
{
phy = Utility.RandomMinMax(2, 5);
fire = Utility.RandomMinMax(2, 5);
cold = Utility.RandomMinMax(2, 5);
poison = Utility.RandomMinMax(2, 5);
energy = Utility.RandomMinMax(2, 5);
}
else if (pwr == 3)
{
phy = Utility.RandomMinMax(4, 7);
fire = Utility.RandomMinMax(4, 7);
cold = Utility.RandomMinMax(4, 7);
poison = Utility.RandomMinMax(4, 7);
energy = Utility.RandomMinMax(4, 7);
}
else if (pwr == 4)
{
phy = Utility.RandomMinMax(6, 10);
fire = Utility.RandomMinMax(6, 10);
cold = Utility.RandomMinMax(6, 10);
poison = Utility.RandomMinMax(6, 10);
energy = Utility.RandomMinMax(6, 10);
}
else if (pwr == 5)
{
phy = Utility.RandomMinMax(9, 12);
fire = Utility.RandomMinMax(9, 12);
cold = Utility.RandomMinMax(9, 12);
poison = Utility.RandomMinMax(9, 12);
energy = Utility.RandomMinMax(9, 12);
}
else if (pwr == 6)
{
phy = Utility.RandomMinMax(12, 15);
fire = Utility.RandomMinMax(12, 15);
cold = Utility.RandomMinMax(12, 15);
poison = Utility.RandomMinMax(12, 15);
energy = Utility.RandomMinMax(12, 15);
}
else
{
phy = 0;
fire = 0;
cold = 0;
poison = 0;
energy = 0;
}
} }
[Constructible] [Constructible]
@ -65,7 +135,7 @@ public partial class RandomLootBag : Bag
for (var i = Utility.Random(10) + 1; i > 0; i--) for (var i = Utility.Random(10) + 1; i > 0; i--)
{ {
var weapon = Loot.RandomWeapon(); var weapon = Loot.RandomWeapon();
GetRandomAOSStats(out var attributeCount, out var min, out var max); GetRandomLevel(out var attributeCount, out var min, out var max);
BaseRunicTool.ApplyAttributesTo(weapon, attributeCount, min, max); BaseRunicTool.ApplyAttributesTo(weapon, attributeCount, min, max);
DropItem(weapon); DropItem(weapon);
} }
@ -73,7 +143,7 @@ public partial class RandomLootBag : Bag
for ( var i = Utility.Random(10) + 1; i > 0; i--) for ( var i = Utility.Random(10) + 1; i > 0; i--)
{ {
var armor = Loot.RandomArmorOrShield(); var armor = Loot.RandomArmorOrShield();
GetRandomAOSStats(out var attributeCount, out var min, out var max); GetRandomLevel(out var attributeCount, out var min, out var max);
BaseRunicTool.ApplyAttributesTo(armor, attributeCount, min, max); BaseRunicTool.ApplyAttributesTo(armor, attributeCount, min, max);
GetRandomResists(out var phy, out var fire, out var cold, out var poison, out var energy); GetRandomResists(out var phy, out var fire, out var cold, out var poison, out var energy);
armor.PhysicalBonus = phy; armor.PhysicalBonus = phy;
@ -87,7 +157,7 @@ public partial class RandomLootBag : Bag
for (var i = Utility.Random(10) + 1; i > 0; i--) for (var i = Utility.Random(10) + 1; i > 0; i--)
{ {
var jewelry = Loot.RandomJewelry(); var jewelry = Loot.RandomJewelry();
GetRandomAOSStats(out var attributeCount, out var min, out var max); GetRandomLevel(out var attributeCount, out var min, out var max);
BaseRunicTool.ApplyAttributesTo(jewelry, attributeCount, min, max); BaseRunicTool.ApplyAttributesTo(jewelry, attributeCount, min, max);
DropItem(jewelry); DropItem(jewelry);
} }

5
Run.sh
View file

@ -5,11 +5,6 @@ then
echo "| A Server is already running!! " echo "| A Server is already running!! "
echo "--------------------------------" echo "--------------------------------"
else else
echo "________________________________"
echo "| Compiling server files."
echo "--------------------------------"
dotnet publish Projects/Application/Application.csproj -c Release -r linux-x64 --self-contained=false
echo ""
echo "" echo ""
echo "________________________________" echo "________________________________"
echo "| Starting Server...." echo "| Starting Server...."