fix: Codegens fillable containers (#862)
- [X] Fillable containers now relock/retrap after respawn. - [X] Optimized the lookup and serialization.
This commit is contained in:
parent
db20722711
commit
59e1793c2d
16 changed files with 1435 additions and 1612 deletions
|
|
@ -0,0 +1,254 @@
|
|||
using System;
|
||||
using ModernUO.Serialization;
|
||||
|
||||
namespace Server.Items;
|
||||
|
||||
[SerializationGenerator(2, false)]
|
||||
public abstract partial class FillableContainer : LockableContainer
|
||||
{
|
||||
[SerializableField(0)]
|
||||
protected FillableContentType _rawContentType;
|
||||
|
||||
[TimerDrift]
|
||||
[SerializableField(1)]
|
||||
private Timer _respawnTimer;
|
||||
|
||||
[DeserializeTimerField(1)]
|
||||
private void DeserializeRespawnTimer(TimeSpan delay)
|
||||
{
|
||||
if (delay > TimeSpan.MinValue)
|
||||
{
|
||||
_respawnTimer = Timer.DelayCall(delay, Respawn);
|
||||
}
|
||||
}
|
||||
|
||||
public FillableContainer(int itemID) : base(itemID) => Movable = false;
|
||||
|
||||
public virtual int MinRespawnMinutes => 60;
|
||||
public virtual int MaxRespawnMinutes => 90;
|
||||
|
||||
public virtual bool IsLockable => true;
|
||||
public virtual bool IsTrappable => IsLockable;
|
||||
|
||||
public virtual int SpawnThreshold => 2;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime NextRespawnTime => _respawnTimer?.Next ?? DateTime.MinValue;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public FillableContentType ContentType
|
||||
{
|
||||
get => _rawContentType;
|
||||
set
|
||||
{
|
||||
if (_rawContentType == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ClearContents();
|
||||
_rawContentType = value;
|
||||
Respawn();
|
||||
}
|
||||
}
|
||||
|
||||
protected void ClearContents()
|
||||
{
|
||||
for (var i = Items.Count - 1; i >= 0; --i)
|
||||
{
|
||||
if (i < Items.Count)
|
||||
{
|
||||
Items[i].Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnMapChange()
|
||||
{
|
||||
base.OnMapChange();
|
||||
AcquireContent();
|
||||
}
|
||||
|
||||
public override void OnLocationChange(Point3D oldLocation)
|
||||
{
|
||||
base.OnLocationChange(oldLocation);
|
||||
AcquireContent();
|
||||
}
|
||||
|
||||
public virtual void AcquireContent()
|
||||
{
|
||||
if (_rawContentType != FillableContentType.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RawContentType = FillableContent.Acquire(GetWorldLocation(), Map);
|
||||
|
||||
if (_rawContentType != FillableContentType.None)
|
||||
{
|
||||
Respawn();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnItemRemoved(Item item)
|
||||
{
|
||||
CheckRespawn();
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
|
||||
_respawnTimer?.Stop();
|
||||
_respawnTimer = null;
|
||||
}
|
||||
|
||||
public int GetItemsCount()
|
||||
{
|
||||
var count = 0;
|
||||
|
||||
foreach (var item in Items)
|
||||
{
|
||||
count += item.Amount;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public void CheckRespawn()
|
||||
{
|
||||
var canSpawn =
|
||||
_rawContentType != FillableContentType.None &&
|
||||
!Deleted && !Movable && Parent == null && !IsLockedDown && !IsSecure &&
|
||||
(
|
||||
GetItemsCount() <= SpawnThreshold ||
|
||||
IsLockable && !Locked ||
|
||||
IsTrappable && TrapType == TrapType.None
|
||||
);
|
||||
|
||||
if (canSpawn)
|
||||
{
|
||||
if (_respawnTimer?.Running != true)
|
||||
{
|
||||
var mins = Utility.RandomMinMax(MinRespawnMinutes, MaxRespawnMinutes);
|
||||
var delay = TimeSpan.FromMinutes(mins);
|
||||
_respawnTimer = Timer.DelayCall(delay, Respawn);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_respawnTimer?.Stop();
|
||||
_respawnTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void Respawn()
|
||||
{
|
||||
_respawnTimer?.Stop();
|
||||
_respawnTimer = null;
|
||||
|
||||
if (_rawContentType == FillableContentType.None || Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GenerateContent();
|
||||
|
||||
var level = FillableContent.Lookup(_rawContentType).Level;
|
||||
|
||||
if (IsLockable)
|
||||
{
|
||||
Locked = true;
|
||||
|
||||
var difficulty = (level - 1) * 30;
|
||||
|
||||
LockLevel = difficulty - 10;
|
||||
MaxLockLevel = difficulty + 30;
|
||||
RequiredSkill = difficulty;
|
||||
}
|
||||
|
||||
if (IsTrappable && (level > 1 || Utility.Random(5) < 4))
|
||||
{
|
||||
TrapType = level > Utility.Random(5) ? TrapType.PoisonTrap : TrapType.ExplosionTrap;
|
||||
TrapPower = level * Utility.RandomMinMax(10, 30);
|
||||
TrapLevel = level;
|
||||
}
|
||||
else
|
||||
{
|
||||
TrapType = TrapType.None;
|
||||
TrapPower = 0;
|
||||
TrapLevel = 0;
|
||||
}
|
||||
|
||||
CheckRespawn();
|
||||
}
|
||||
|
||||
protected virtual int GetSpawnCount()
|
||||
{
|
||||
var itemsCount = GetItemsCount();
|
||||
|
||||
if (itemsCount > SpawnThreshold)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var maxSpawnCount = (1 + SpawnThreshold - itemsCount) * 2;
|
||||
|
||||
return Utility.RandomMinMax(0, maxSpawnCount);
|
||||
}
|
||||
|
||||
public virtual void GenerateContent()
|
||||
{
|
||||
if (_rawContentType == FillableContentType.None || Deleted)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var content = FillableContent.Lookup(_rawContentType);
|
||||
|
||||
var toSpawn = GetSpawnCount();
|
||||
|
||||
for (var i = 0; i < toSpawn; ++i)
|
||||
{
|
||||
var item = content.Construct();
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var list = Items;
|
||||
|
||||
for (var j = 0; j < list.Count; ++j)
|
||||
{
|
||||
var subItem = list[j];
|
||||
|
||||
if (subItem is not Container && subItem.StackWith(null, item, false))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!item.Deleted)
|
||||
{
|
||||
DropItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Deserialize(IGenericReader reader, int version)
|
||||
{
|
||||
_rawContentType = (FillableContentType)reader.ReadInt();
|
||||
var respawnTimerNext = reader.ReadDeltaTime();
|
||||
DeserializeRespawnTimer(respawnTimerNext == DateTime.MinValue ? TimeSpan.MinValue : respawnTimerNext - Core.Now);
|
||||
}
|
||||
|
||||
[AfterDeserialization]
|
||||
private void AfterDeserialization()
|
||||
{
|
||||
if (_respawnTimer?.Running != true)
|
||||
{
|
||||
CheckRespawn();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
using ModernUO.Serialization;
|
||||
|
||||
namespace Server.Items;
|
||||
|
||||
[Flippable(0xA97, 0xA99, 0xA98, 0xA9A, 0xA9B, 0xA9C)]
|
||||
[SerializationGenerator(0)]
|
||||
public partial class LibraryBookcase : FillableContainer
|
||||
{
|
||||
[Constructible]
|
||||
public LibraryBookcase() : base(0xA97) => Weight = 1.0;
|
||||
|
||||
public override bool IsLockable => false;
|
||||
public override int SpawnThreshold => 5;
|
||||
|
||||
protected override int GetSpawnCount() => 5 - GetItemsCount();
|
||||
|
||||
public override void AcquireContent()
|
||||
{
|
||||
if (_rawContentType != FillableContentType.None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RawContentType = FillableContentType.Library;
|
||||
Respawn();
|
||||
}
|
||||
}
|
||||
|
||||
[Flippable(0xE3D, 0xE3C)]
|
||||
[SerializationGenerator(0)]
|
||||
public partial class FillableLargeCrate : FillableContainer
|
||||
{
|
||||
[Constructible]
|
||||
public FillableLargeCrate() : base(0xE3D) => Weight = 1.0;
|
||||
}
|
||||
|
||||
[Flippable(0x9A9, 0xE7E)]
|
||||
[SerializationGenerator(0)]
|
||||
public partial class FillableSmallCrate : FillableContainer
|
||||
{
|
||||
[Constructible]
|
||||
public FillableSmallCrate() : base(0x9A9) => Weight = 1.0;
|
||||
}
|
||||
|
||||
[Flippable(0x9AA, 0xE7D)]
|
||||
[SerializationGenerator(0)]
|
||||
public partial class FillableWoodenBox : FillableContainer
|
||||
{
|
||||
[Constructible]
|
||||
public FillableWoodenBox() : base(0x9AA) => Weight = 4.0;
|
||||
}
|
||||
|
||||
[Flippable(0x9A8, 0xE80)]
|
||||
[SerializationGenerator(0)]
|
||||
public partial class FillableMetalBox : FillableContainer
|
||||
{
|
||||
[Constructible]
|
||||
public FillableMetalBox() : base(0x9A8)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[SerializationGenerator(0)]
|
||||
public partial class FillableBarrel : FillableContainer
|
||||
{
|
||||
[Constructible]
|
||||
public FillableBarrel() : base(0xE77)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Flippable(0x9AB, 0xE7C)]
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class FillableMetalChest : FillableContainer
|
||||
{
|
||||
[Constructible]
|
||||
public FillableMetalChest() : base(0x9AB)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Flippable(0xE41, 0xE40)]
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class FillableMetalGoldenChest : FillableContainer
|
||||
{
|
||||
[Constructible]
|
||||
public FillableMetalGoldenChest() : base(0xE41)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[Flippable(0xE43, 0xE42)]
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class FillableWoodenChest : FillableContainer
|
||||
{
|
||||
[Constructible]
|
||||
public FillableWoodenChest() : base(0xE43)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,810 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Items;
|
||||
|
||||
public enum FillableContentType
|
||||
{
|
||||
None = -1,
|
||||
Weaponsmith,
|
||||
Provisioner,
|
||||
Mage,
|
||||
Alchemist,
|
||||
Armorer,
|
||||
ArtisanGuild,
|
||||
Baker,
|
||||
Bard,
|
||||
Blacksmith,
|
||||
Bowyer,
|
||||
Butcher,
|
||||
Carpenter,
|
||||
Clothier,
|
||||
Cobbler,
|
||||
Docks,
|
||||
Farm,
|
||||
FighterGuild,
|
||||
Guard,
|
||||
Healer,
|
||||
Herbalist,
|
||||
Inn,
|
||||
Jeweler,
|
||||
Library,
|
||||
Merchant,
|
||||
Mill,
|
||||
Mine,
|
||||
Observatory,
|
||||
Painter,
|
||||
Ranger,
|
||||
Stables,
|
||||
Tanner,
|
||||
Tavern,
|
||||
ThiefGuild,
|
||||
Tinker,
|
||||
Veterinarian
|
||||
}
|
||||
|
||||
public partial class FillableContent
|
||||
{
|
||||
private static readonly FillableContent Alchemist = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Alchemist)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(typeof(NightSightPotion)),
|
||||
new FillableEntry(typeof(LesserCurePotion)),
|
||||
new FillableEntry(typeof(AgilityPotion)),
|
||||
new FillableEntry(typeof(StrengthPotion)),
|
||||
new FillableEntry(typeof(LesserPoisonPotion)),
|
||||
new FillableEntry(typeof(RefreshPotion)),
|
||||
new FillableEntry(typeof(LesserHealPotion)),
|
||||
new FillableEntry(typeof(LesserExplosionPotion)),
|
||||
new FillableEntry(typeof(MortarPestle))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Armorer = new(
|
||||
2,
|
||||
new[]
|
||||
{
|
||||
typeof(Armorer)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(2, typeof(ChainCoif)),
|
||||
new FillableEntry(1, typeof(PlateGorget)),
|
||||
new FillableEntry(1, typeof(BronzeShield)),
|
||||
new FillableEntry(1, typeof(Buckler)),
|
||||
new FillableEntry(2, typeof(MetalKiteShield)),
|
||||
new FillableEntry(2, typeof(HeaterShield)),
|
||||
new FillableEntry(1, typeof(WoodenShield)),
|
||||
new FillableEntry(1, typeof(MetalShield))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent ArtisanGuild = new(
|
||||
1,
|
||||
Array.Empty<Type>(),
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(PaintsAndBrush)),
|
||||
new FillableEntry(1, typeof(SledgeHammer)),
|
||||
new FillableEntry(2, typeof(SmithHammer)),
|
||||
new FillableEntry(2, typeof(Tongs)),
|
||||
new FillableEntry(4, typeof(Lockpick)),
|
||||
new FillableEntry(4, typeof(TinkerTools)),
|
||||
new FillableEntry(1, typeof(MalletAndChisel)),
|
||||
new FillableEntry(1, typeof(StatueEast2)),
|
||||
new FillableEntry(1, typeof(StatueSouth)),
|
||||
new FillableEntry(1, typeof(StatueSouthEast)),
|
||||
new FillableEntry(1, typeof(StatueWest)),
|
||||
new FillableEntry(1, typeof(StatueNorth)),
|
||||
new FillableEntry(1, typeof(StatueEast)),
|
||||
new FillableEntry(1, typeof(BustEast)),
|
||||
new FillableEntry(1, typeof(BustSouth)),
|
||||
new FillableEntry(1, typeof(BearMask)),
|
||||
new FillableEntry(1, typeof(DeerMask)),
|
||||
new FillableEntry(4, typeof(OrcHelm)),
|
||||
new FillableEntry(1, typeof(TribalMask)),
|
||||
new FillableEntry(1, typeof(HornedTribalMask))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Baker = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Baker)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(RollingPin)),
|
||||
new FillableEntry(2, typeof(SackFlour)),
|
||||
new FillableEntry(2, typeof(BreadLoaf)),
|
||||
new FillableEntry(1, typeof(FrenchBread))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Bard = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Bard),
|
||||
typeof(BardGuildmaster)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(LapHarp)),
|
||||
new FillableEntry(2, typeof(Lute)),
|
||||
new FillableEntry(1, typeof(Drums)),
|
||||
new FillableEntry(1, typeof(Tambourine)),
|
||||
new FillableEntry(1, typeof(TambourineTassel))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Blacksmith = new(
|
||||
2,
|
||||
new[]
|
||||
{
|
||||
typeof(Blacksmith),
|
||||
typeof(BlacksmithGuildmaster)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(8, typeof(SmithHammer)),
|
||||
new FillableEntry(8, typeof(Tongs)),
|
||||
new FillableEntry(8, typeof(SledgeHammer)),
|
||||
// new FillableEntry( 8, typeof( IronOre ) ), TODO: Smaller ore
|
||||
new FillableEntry(8, typeof(IronIngot)),
|
||||
new FillableEntry(1, typeof(IronWire)),
|
||||
new FillableEntry(1, typeof(SilverWire)),
|
||||
new FillableEntry(1, typeof(GoldWire)),
|
||||
new FillableEntry(1, typeof(CopperWire)),
|
||||
new FillableEntry(1, typeof(HorseShoes)),
|
||||
new FillableEntry(1, typeof(ForgedMetal))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Bowyer = new(
|
||||
2,
|
||||
new[]
|
||||
{
|
||||
typeof(Bowyer)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(2, typeof(Bow)),
|
||||
new FillableEntry(2, typeof(Crossbow)),
|
||||
new FillableEntry(1, typeof(Arrow))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Butcher = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Butcher)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(2, typeof(Cleaver)),
|
||||
new FillableEntry(2, typeof(SlabOfBacon)),
|
||||
new FillableEntry(2, typeof(Bacon)),
|
||||
new FillableEntry(1, typeof(RawFishSteak)),
|
||||
new FillableEntry(1, typeof(FishSteak)),
|
||||
new FillableEntry(2, typeof(CookedBird)),
|
||||
new FillableEntry(2, typeof(RawBird)),
|
||||
new FillableEntry(2, typeof(Ham)),
|
||||
new FillableEntry(1, typeof(RawLambLeg)),
|
||||
new FillableEntry(1, typeof(LambLeg)),
|
||||
new FillableEntry(1, typeof(Ribs)),
|
||||
new FillableEntry(1, typeof(RawRibs)),
|
||||
new FillableEntry(2, typeof(Sausage)),
|
||||
new FillableEntry(1, typeof(RawChickenLeg)),
|
||||
new FillableEntry(1, typeof(ChickenLeg))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Carpenter = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Carpenter),
|
||||
typeof(Architect),
|
||||
typeof(RealEstateBroker)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(ChiselsNorth)),
|
||||
new FillableEntry(1, typeof(ChiselsWest)),
|
||||
new FillableEntry(2, typeof(DovetailSaw)),
|
||||
new FillableEntry(2, typeof(Hammer)),
|
||||
new FillableEntry(2, typeof(MouldingPlane)),
|
||||
new FillableEntry(2, typeof(Nails)),
|
||||
new FillableEntry(2, typeof(JointingPlane)),
|
||||
new FillableEntry(2, typeof(SmoothingPlane)),
|
||||
new FillableEntry(2, typeof(Saw)),
|
||||
new FillableEntry(2, typeof(DrawKnife)),
|
||||
new FillableEntry(1, typeof(Log)),
|
||||
new FillableEntry(1, typeof(Froe)),
|
||||
new FillableEntry(1, typeof(Inshave)),
|
||||
new FillableEntry(1, typeof(Scorp))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Clothier = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Tailor),
|
||||
typeof(Weaver),
|
||||
typeof(TailorGuildmaster)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(Cotton)),
|
||||
new FillableEntry(1, typeof(Wool)),
|
||||
new FillableEntry(1, typeof(DarkYarn)),
|
||||
new FillableEntry(1, typeof(LightYarn)),
|
||||
new FillableEntry(1, typeof(LightYarnUnraveled)),
|
||||
new FillableEntry(1, typeof(SpoolOfThread)),
|
||||
// Four different types
|
||||
// new FillableEntry( 1, typeof( FoldedCloth ) ),
|
||||
// new FillableEntry( 1, typeof( FoldedCloth ) ),
|
||||
// new FillableEntry( 1, typeof( FoldedCloth ) ),
|
||||
// new FillableEntry( 1, typeof( FoldedCloth ) ),
|
||||
new FillableEntry(1, typeof(Dyes)),
|
||||
new FillableEntry(2, typeof(Leather))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Cobbler = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Cobbler)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(Boots)),
|
||||
new FillableEntry(2, typeof(Shoes)),
|
||||
new FillableEntry(2, typeof(Sandals)),
|
||||
new FillableEntry(1, typeof(ThighBoots))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Docks = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Fisherman),
|
||||
typeof(FisherGuildmaster)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(FishingPole)),
|
||||
// Two different types
|
||||
// new FillableEntry( 1, typeof( SmallFish ) ),
|
||||
// new FillableEntry( 1, typeof( SmallFish ) ),
|
||||
new FillableEntry(4, typeof(Fish))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Farm = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Farmer),
|
||||
typeof(Rancher)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(Shirt)),
|
||||
new FillableEntry(1, typeof(ShortPants)),
|
||||
new FillableEntry(1, typeof(Skirt)),
|
||||
new FillableEntry(1, typeof(PlainDress)),
|
||||
new FillableEntry(1, typeof(Cap)),
|
||||
new FillableEntry(2, typeof(Sandals)),
|
||||
new FillableEntry(2, typeof(GnarledStaff)),
|
||||
new FillableEntry(2, typeof(Pitchfork)),
|
||||
new FillableEntry(1, typeof(Bag)),
|
||||
new FillableEntry(1, typeof(Kindling)),
|
||||
new FillableEntry(1, typeof(Lettuce)),
|
||||
new FillableEntry(1, typeof(Onion)),
|
||||
new FillableEntry(1, typeof(Turnip)),
|
||||
new FillableEntry(1, typeof(Ham)),
|
||||
new FillableEntry(1, typeof(Bacon)),
|
||||
new FillableEntry(1, typeof(RawLambLeg)),
|
||||
new FillableEntry(1, typeof(SheafOfHay)),
|
||||
new FillableBvrge(1, typeof(Pitcher), BeverageType.Milk)
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent FighterGuild = new(
|
||||
3,
|
||||
new[]
|
||||
{
|
||||
typeof(WarriorGuildmaster)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(12, Loot.ArmorTypes),
|
||||
new FillableEntry(8, Loot.WeaponTypes),
|
||||
new FillableEntry(3, Loot.ShieldTypes),
|
||||
new FillableEntry(1, typeof(Arrow))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Guard = new(
|
||||
3,
|
||||
Array.Empty<Type>(),
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(12, Loot.ArmorTypes),
|
||||
new FillableEntry(8, Loot.WeaponTypes),
|
||||
new FillableEntry(3, Loot.ShieldTypes),
|
||||
new FillableEntry(1, typeof(Arrow))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Healer = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Healer),
|
||||
typeof(HealerGuildmaster)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(Bandage)),
|
||||
new FillableEntry(1, typeof(MortarPestle)),
|
||||
new FillableEntry(1, typeof(LesserHealPotion))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Herbalist = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Herbalist)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(10, typeof(Garlic)),
|
||||
new FillableEntry(10, typeof(Ginseng)),
|
||||
new FillableEntry(10, typeof(MandrakeRoot)),
|
||||
new FillableEntry(1, typeof(DeadWood)),
|
||||
new FillableEntry(1, typeof(WhiteDriedFlowers)),
|
||||
new FillableEntry(1, typeof(GreenDriedFlowers)),
|
||||
new FillableEntry(1, typeof(DriedOnions)),
|
||||
new FillableEntry(1, typeof(DriedHerbs))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Inn = new(
|
||||
1,
|
||||
Array.Empty<Type>(),
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(Candle)),
|
||||
new FillableEntry(1, typeof(Torch)),
|
||||
new FillableEntry(1, typeof(Lantern))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Jeweler = new(
|
||||
2,
|
||||
new[]
|
||||
{
|
||||
typeof(Jeweler)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(GoldRing)),
|
||||
new FillableEntry(1, typeof(GoldBracelet)),
|
||||
new FillableEntry(1, typeof(GoldEarrings)),
|
||||
new FillableEntry(1, typeof(GoldNecklace)),
|
||||
new FillableEntry(1, typeof(GoldBeadNecklace)),
|
||||
new FillableEntry(1, typeof(Necklace)),
|
||||
new FillableEntry(1, typeof(Beads)),
|
||||
new FillableEntry(9, Loot.GemTypes)
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Library = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Scribe)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(8, Loot.LibraryBookTypes),
|
||||
new FillableEntry(1, typeof(RedBook)),
|
||||
new FillableEntry(1, typeof(BlueBook))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Mage = new(
|
||||
2,
|
||||
new[]
|
||||
{
|
||||
typeof(Mage),
|
||||
typeof(HolyMage),
|
||||
typeof(MageGuildmaster)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(16, typeof(BlankScroll)),
|
||||
new FillableEntry(14, typeof(Spellbook)),
|
||||
new FillableEntry(12, Loot.RegularScrollTypes, 0, 8),
|
||||
new FillableEntry(11, Loot.RegularScrollTypes, 8, 8),
|
||||
new FillableEntry(10, Loot.RegularScrollTypes, 16, 8),
|
||||
new FillableEntry(9, Loot.RegularScrollTypes, 24, 8),
|
||||
new FillableEntry(8, Loot.RegularScrollTypes, 32, 8),
|
||||
new FillableEntry(7, Loot.RegularScrollTypes, 40, 8),
|
||||
new FillableEntry(6, Loot.RegularScrollTypes, 48, 8),
|
||||
new FillableEntry(5, Loot.RegularScrollTypes, 56, 8)
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Merchant = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(MerchantGuildmaster)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(CheeseWheel)),
|
||||
new FillableEntry(1, typeof(CheeseWedge)),
|
||||
new FillableEntry(1, typeof(CheeseSlice)),
|
||||
new FillableEntry(1, typeof(Eggs)),
|
||||
new FillableEntry(4, typeof(Fish)),
|
||||
new FillableEntry(2, typeof(RawFishSteak)),
|
||||
new FillableEntry(2, typeof(FishSteak)),
|
||||
new FillableEntry(1, typeof(Apple)),
|
||||
new FillableEntry(2, typeof(Banana)),
|
||||
new FillableEntry(2, typeof(Bananas)),
|
||||
new FillableEntry(2, typeof(OpenCoconut)),
|
||||
new FillableEntry(1, typeof(SplitCoconut)),
|
||||
new FillableEntry(1, typeof(Coconut)),
|
||||
new FillableEntry(1, typeof(Dates)),
|
||||
new FillableEntry(1, typeof(Grapes)),
|
||||
new FillableEntry(1, typeof(Lemon)),
|
||||
new FillableEntry(1, typeof(Lemons)),
|
||||
new FillableEntry(1, typeof(Lime)),
|
||||
new FillableEntry(1, typeof(Limes)),
|
||||
new FillableEntry(1, typeof(Peach)),
|
||||
new FillableEntry(1, typeof(Pear)),
|
||||
new FillableEntry(2, typeof(SlabOfBacon)),
|
||||
new FillableEntry(2, typeof(Bacon)),
|
||||
new FillableEntry(2, typeof(CookedBird)),
|
||||
new FillableEntry(2, typeof(RawBird)),
|
||||
new FillableEntry(2, typeof(Ham)),
|
||||
new FillableEntry(1, typeof(RawLambLeg)),
|
||||
new FillableEntry(1, typeof(LambLeg)),
|
||||
new FillableEntry(1, typeof(Ribs)),
|
||||
new FillableEntry(1, typeof(RawRibs)),
|
||||
new FillableEntry(2, typeof(Sausage)),
|
||||
new FillableEntry(1, typeof(RawChickenLeg)),
|
||||
new FillableEntry(1, typeof(ChickenLeg)),
|
||||
new FillableEntry(1, typeof(Watermelon)),
|
||||
new FillableEntry(1, typeof(SmallWatermelon)),
|
||||
new FillableEntry(3, typeof(Turnip)),
|
||||
new FillableEntry(2, typeof(YellowGourd)),
|
||||
new FillableEntry(2, typeof(GreenGourd)),
|
||||
new FillableEntry(2, typeof(Pumpkin)),
|
||||
new FillableEntry(1, typeof(SmallPumpkin)),
|
||||
new FillableEntry(2, typeof(Onion)),
|
||||
new FillableEntry(2, typeof(Lettuce)),
|
||||
new FillableEntry(2, typeof(Squash)),
|
||||
new FillableEntry(2, typeof(HoneydewMelon)),
|
||||
new FillableEntry(1, typeof(Carrot)),
|
||||
new FillableEntry(2, typeof(Cantaloupe)),
|
||||
new FillableEntry(2, typeof(Cabbage)),
|
||||
new FillableEntry(4, typeof(EarOfCorn))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Mill = new(
|
||||
1,
|
||||
Array.Empty<Type>(),
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(SackFlour))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Mine = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Miner)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(2, typeof(Pickaxe)),
|
||||
new FillableEntry(2, typeof(Shovel)),
|
||||
new FillableEntry(2, typeof(IronIngot)),
|
||||
// new FillableEntry( 2, typeof( IronOre ) ), TODO: Smaller Ore
|
||||
new FillableEntry(1, typeof(ForgedMetal))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Observatory = new(
|
||||
1,
|
||||
Array.Empty<Type>(),
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(2, typeof(Sextant)),
|
||||
new FillableEntry(2, typeof(Clock)),
|
||||
new FillableEntry(1, typeof(Spyglass))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Painter = new(
|
||||
1,
|
||||
Array.Empty<Type>(),
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(PaintsAndBrush)),
|
||||
new FillableEntry(2, typeof(PenAndInk))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Provisioner = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Provisioner)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(CheeseWheel)),
|
||||
new FillableEntry(1, typeof(CheeseWedge)),
|
||||
new FillableEntry(1, typeof(CheeseSlice)),
|
||||
new FillableEntry(1, typeof(Eggs)),
|
||||
new FillableEntry(4, typeof(Fish)),
|
||||
new FillableEntry(1, typeof(DirtyFrypan)),
|
||||
new FillableEntry(1, typeof(DirtyPan)),
|
||||
new FillableEntry(1, typeof(DirtyKettle)),
|
||||
new FillableEntry(1, typeof(DirtySmallRoundPot)),
|
||||
new FillableEntry(1, typeof(DirtyRoundPot)),
|
||||
new FillableEntry(1, typeof(DirtySmallPot)),
|
||||
new FillableEntry(1, typeof(DirtyPot)),
|
||||
new FillableEntry(1, typeof(Apple)),
|
||||
new FillableEntry(2, typeof(Banana)),
|
||||
new FillableEntry(2, typeof(Bananas)),
|
||||
new FillableEntry(2, typeof(OpenCoconut)),
|
||||
new FillableEntry(1, typeof(SplitCoconut)),
|
||||
new FillableEntry(1, typeof(Coconut)),
|
||||
new FillableEntry(1, typeof(Dates)),
|
||||
new FillableEntry(1, typeof(Grapes)),
|
||||
new FillableEntry(1, typeof(Lemon)),
|
||||
new FillableEntry(1, typeof(Lemons)),
|
||||
new FillableEntry(1, typeof(Lime)),
|
||||
new FillableEntry(1, typeof(Limes)),
|
||||
new FillableEntry(1, typeof(Peach)),
|
||||
new FillableEntry(1, typeof(Pear)),
|
||||
new FillableEntry(2, typeof(SlabOfBacon)),
|
||||
new FillableEntry(2, typeof(Bacon)),
|
||||
new FillableEntry(1, typeof(RawFishSteak)),
|
||||
new FillableEntry(1, typeof(FishSteak)),
|
||||
new FillableEntry(2, typeof(CookedBird)),
|
||||
new FillableEntry(2, typeof(RawBird)),
|
||||
new FillableEntry(2, typeof(Ham)),
|
||||
new FillableEntry(1, typeof(RawLambLeg)),
|
||||
new FillableEntry(1, typeof(LambLeg)),
|
||||
new FillableEntry(1, typeof(Ribs)),
|
||||
new FillableEntry(1, typeof(RawRibs)),
|
||||
new FillableEntry(2, typeof(Sausage)),
|
||||
new FillableEntry(1, typeof(RawChickenLeg)),
|
||||
new FillableEntry(1, typeof(ChickenLeg)),
|
||||
new FillableEntry(1, typeof(Watermelon)),
|
||||
new FillableEntry(1, typeof(SmallWatermelon)),
|
||||
new FillableEntry(3, typeof(Turnip)),
|
||||
new FillableEntry(2, typeof(YellowGourd)),
|
||||
new FillableEntry(2, typeof(GreenGourd)),
|
||||
new FillableEntry(2, typeof(Pumpkin)),
|
||||
new FillableEntry(1, typeof(SmallPumpkin)),
|
||||
new FillableEntry(2, typeof(Onion)),
|
||||
new FillableEntry(2, typeof(Lettuce)),
|
||||
new FillableEntry(2, typeof(Squash)),
|
||||
new FillableEntry(2, typeof(HoneydewMelon)),
|
||||
new FillableEntry(1, typeof(Carrot)),
|
||||
new FillableEntry(2, typeof(Cantaloupe)),
|
||||
new FillableEntry(2, typeof(Cabbage)),
|
||||
new FillableEntry(4, typeof(EarOfCorn))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Ranger = new(
|
||||
2,
|
||||
new[]
|
||||
{
|
||||
typeof(Ranger),
|
||||
typeof(RangerGuildmaster)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(2, typeof(StuddedChest)),
|
||||
new FillableEntry(2, typeof(StuddedLegs)),
|
||||
new FillableEntry(2, typeof(StuddedArms)),
|
||||
new FillableEntry(2, typeof(StuddedGloves)),
|
||||
new FillableEntry(1, typeof(StuddedGorget)),
|
||||
|
||||
new FillableEntry(2, typeof(LeatherChest)),
|
||||
new FillableEntry(2, typeof(LeatherLegs)),
|
||||
new FillableEntry(2, typeof(LeatherArms)),
|
||||
new FillableEntry(2, typeof(LeatherGloves)),
|
||||
new FillableEntry(1, typeof(LeatherGorget)),
|
||||
|
||||
new FillableEntry(2, typeof(FeatheredHat)),
|
||||
new FillableEntry(1, typeof(CloseHelm)),
|
||||
new FillableEntry(1, typeof(TallStrawHat)),
|
||||
new FillableEntry(1, typeof(Bandana)),
|
||||
new FillableEntry(1, typeof(Cloak)),
|
||||
new FillableEntry(2, typeof(Boots)),
|
||||
new FillableEntry(2, typeof(ThighBoots)),
|
||||
|
||||
new FillableEntry(2, typeof(GnarledStaff)),
|
||||
new FillableEntry(1, typeof(Whip)),
|
||||
|
||||
new FillableEntry(2, typeof(Bow)),
|
||||
new FillableEntry(2, typeof(Crossbow)),
|
||||
new FillableEntry(2, typeof(HeavyCrossbow)),
|
||||
new FillableEntry(4, typeof(Arrow))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Stables = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(AnimalTrainer),
|
||||
typeof(GypsyAnimalTrainer)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
// new FillableEntry( 1, typeof( Wheat ) ),
|
||||
new FillableEntry(1, typeof(Carrot))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Tanner = new(
|
||||
2,
|
||||
new[]
|
||||
{
|
||||
typeof(Tanner),
|
||||
typeof(LeatherWorker),
|
||||
typeof(Furtrader)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(FeatheredHat)),
|
||||
new FillableEntry(1, typeof(LeatherArms)),
|
||||
new FillableEntry(2, typeof(LeatherLegs)),
|
||||
new FillableEntry(2, typeof(LeatherChest)),
|
||||
new FillableEntry(2, typeof(LeatherGloves)),
|
||||
new FillableEntry(1, typeof(LeatherGorget)),
|
||||
new FillableEntry(2, typeof(Leather))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Tavern = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(TavernKeeper),
|
||||
typeof(Barkeeper),
|
||||
typeof(Waiter),
|
||||
typeof(Cook)
|
||||
},
|
||||
new FillableEntry[]
|
||||
{
|
||||
new FillableBvrge(1, typeof(BeverageBottle), BeverageType.Ale),
|
||||
new FillableBvrge(1, typeof(BeverageBottle), BeverageType.Wine),
|
||||
new FillableBvrge(1, typeof(BeverageBottle), BeverageType.Liquor),
|
||||
new FillableBvrge(1, typeof(Jug), BeverageType.Cider)
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent ThiefGuild = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Thief),
|
||||
typeof(ThiefGuildmaster)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(Lockpick)),
|
||||
new FillableEntry(1, typeof(BearMask)),
|
||||
new FillableEntry(1, typeof(DeerMask)),
|
||||
new FillableEntry(1, typeof(TribalMask)),
|
||||
new FillableEntry(1, typeof(HornedTribalMask)),
|
||||
new FillableEntry(4, typeof(OrcHelm))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Tinker = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Tinker),
|
||||
typeof(TinkerGuildmaster)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(Lockpick)),
|
||||
// new FillableEntry( 1, typeof( KeyRing ) ),
|
||||
new FillableEntry(2, typeof(Clock)),
|
||||
new FillableEntry(2, typeof(ClockParts)),
|
||||
new FillableEntry(2, typeof(AxleGears)),
|
||||
new FillableEntry(2, typeof(Gears)),
|
||||
new FillableEntry(2, typeof(Hinge)),
|
||||
// new FillableEntry( 1, typeof( ArrowShafts ) ),
|
||||
new FillableEntry(2, typeof(Sextant)),
|
||||
new FillableEntry(2, typeof(SextantParts)),
|
||||
new FillableEntry(2, typeof(Axle)),
|
||||
new FillableEntry(2, typeof(Springs)),
|
||||
new FillableEntry(5, typeof(TinkerTools)),
|
||||
new FillableEntry(4, typeof(Key)),
|
||||
new FillableEntry(1, typeof(DecoArrowShafts)),
|
||||
new FillableEntry(1, typeof(Lockpicks)),
|
||||
new FillableEntry(1, typeof(ToolKit))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Veterinarian = new(
|
||||
1,
|
||||
new[]
|
||||
{
|
||||
typeof(Veterinarian)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(1, typeof(Bandage)),
|
||||
new FillableEntry(1, typeof(MortarPestle)),
|
||||
new FillableEntry(1, typeof(LesserHealPotion)),
|
||||
// new FillableEntry( 1, typeof( Wheat ) ),
|
||||
new FillableEntry(1, typeof(Carrot))
|
||||
}
|
||||
);
|
||||
|
||||
private static readonly FillableContent Weaponsmith = new(
|
||||
2,
|
||||
new[]
|
||||
{
|
||||
typeof(Weaponsmith)
|
||||
},
|
||||
new[]
|
||||
{
|
||||
new FillableEntry(8, Loot.WeaponTypes),
|
||||
new FillableEntry(1, typeof(Arrow))
|
||||
}
|
||||
);
|
||||
|
||||
private static Dictionary<Type, FillableContentType> _acquireTable;
|
||||
|
||||
// This should match the FillableContentType enum
|
||||
private static readonly FillableContent[] ContentTypes =
|
||||
{
|
||||
Weaponsmith, Provisioner, Mage,
|
||||
Alchemist, Armorer, ArtisanGuild,
|
||||
Baker, Bard, Blacksmith,
|
||||
Bowyer, Butcher, Carpenter,
|
||||
Clothier, Cobbler, Docks,
|
||||
Farm, FighterGuild, Guard,
|
||||
Healer, Herbalist, Inn,
|
||||
Jeweler, Library, Merchant,
|
||||
Mill, Mine, Observatory,
|
||||
Painter, Ranger, Stables,
|
||||
Tanner, Tavern, ThiefGuild,
|
||||
Tinker, Veterinarian
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items;
|
||||
|
||||
public partial class FillableContent
|
||||
{
|
||||
private readonly FillableEntry[] _entries;
|
||||
private readonly int _weight;
|
||||
|
||||
public FillableContent(int level, Type[] vendors, FillableEntry[] entries)
|
||||
{
|
||||
Level = level;
|
||||
Vendors = vendors;
|
||||
_entries = entries;
|
||||
|
||||
for (var i = 0; i < entries.Length; ++i)
|
||||
{
|
||||
_weight += entries[i].Weight;
|
||||
}
|
||||
}
|
||||
|
||||
public int Level { get; }
|
||||
|
||||
public Type[] Vendors { get; }
|
||||
|
||||
public FillableContentType TypeID => Lookup(this);
|
||||
|
||||
public virtual Item Construct()
|
||||
{
|
||||
var index = Utility.Random(_weight);
|
||||
|
||||
for (var i = 0; i < _entries.Length; ++i)
|
||||
{
|
||||
var entry = _entries[i];
|
||||
|
||||
if (index < entry.Weight)
|
||||
{
|
||||
return entry.Construct();
|
||||
}
|
||||
|
||||
index -= entry.Weight;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static FillableContent Lookup(FillableContentType type)
|
||||
{
|
||||
var v = (int)type;
|
||||
|
||||
if (v >= 0 && v < ContentTypes.Length)
|
||||
{
|
||||
return ContentTypes[v];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static FillableContentType Lookup(FillableContent content)
|
||||
{
|
||||
if (content == null)
|
||||
{
|
||||
return FillableContentType.None;
|
||||
}
|
||||
|
||||
return (FillableContentType)Array.IndexOf(ContentTypes, content);
|
||||
}
|
||||
|
||||
public static FillableContentType Acquire(Point3D loc, Map map)
|
||||
{
|
||||
FillableContentType content = FillableContentType.None;
|
||||
|
||||
if (map == null || map == Map.Internal)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
if (_acquireTable == null)
|
||||
{
|
||||
_acquireTable = new Dictionary<Type, FillableContentType>();
|
||||
|
||||
for (var i = 0; i < ContentTypes.Length; ++i)
|
||||
{
|
||||
var fill = ContentTypes[i];
|
||||
|
||||
for (var j = 0; j < fill.Vendors.Length; ++j)
|
||||
{
|
||||
_acquireTable[fill.Vendors[j]] = fill.TypeID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Mobile nearest = null;
|
||||
|
||||
// TODO: Replace with vendor shop regions and a fallback override.
|
||||
foreach (var mob in map.GetMobilesInRange(loc, 20))
|
||||
{
|
||||
if (nearest != null && mob.GetDistanceToSqrt(loc) > nearest.GetDistanceToSqrt(loc) &&
|
||||
!(nearest is Mobiles.Cobbler && mob is Mobiles.Provisioner))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_acquireTable.TryGetValue(mob.GetType(), out var check))
|
||||
{
|
||||
nearest = mob;
|
||||
content = check;
|
||||
}
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items;
|
||||
|
||||
public class FillableEntry
|
||||
{
|
||||
protected Type[] _types;
|
||||
protected int _weight;
|
||||
|
||||
public FillableEntry(Type type) : this(1, new[] { type })
|
||||
{
|
||||
}
|
||||
|
||||
public FillableEntry(int weight, Type type) : this(weight, new[] { type })
|
||||
{
|
||||
}
|
||||
|
||||
public FillableEntry(Type[] types) : this(1, types)
|
||||
{
|
||||
}
|
||||
|
||||
public FillableEntry(int weight, Type[] types)
|
||||
{
|
||||
_weight = weight;
|
||||
_types = types;
|
||||
}
|
||||
|
||||
public FillableEntry(int weight, Type[] types, int offset, int count)
|
||||
{
|
||||
_weight = weight;
|
||||
_types = new Type[count];
|
||||
Array.Copy(types, offset, _types, 0, count);
|
||||
}
|
||||
|
||||
public Type[] Types => _types;
|
||||
public int Weight => _weight;
|
||||
|
||||
public virtual Item Construct()
|
||||
{
|
||||
var item = Loot.Construct(_types);
|
||||
|
||||
if (item is Key key)
|
||||
{
|
||||
key.ItemID = Utility.RandomList(
|
||||
(int)KeyType.Copper,
|
||||
(int)KeyType.Gold,
|
||||
(int)KeyType.Iron,
|
||||
(int)KeyType.Rusty
|
||||
);
|
||||
}
|
||||
else if (item is Arrow or Bolt)
|
||||
{
|
||||
item.Amount = Utility.RandomMinMax(2, 6);
|
||||
}
|
||||
else if (item is Bandage or Lockpick)
|
||||
{
|
||||
item.Amount = Utility.RandomMinMax(1, 3);
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
public class FillableBvrge : FillableEntry
|
||||
{
|
||||
public FillableBvrge(Type type, BeverageType content) : this(1, type, content)
|
||||
{
|
||||
}
|
||||
|
||||
public FillableBvrge(int weight, Type type, BeverageType content) : base(weight, type) =>
|
||||
Content = content;
|
||||
|
||||
public BeverageType Content { get; }
|
||||
|
||||
public override Item Construct()
|
||||
{
|
||||
Item item;
|
||||
|
||||
var index = Utility.Random(_types.Length);
|
||||
|
||||
if (_types[index] == typeof(BeverageBottle))
|
||||
{
|
||||
item = new BeverageBottle(Content);
|
||||
}
|
||||
else if (_types[index] == typeof(Jug))
|
||||
{
|
||||
item = new Jug(Content);
|
||||
}
|
||||
else
|
||||
{
|
||||
item = base.Construct();
|
||||
|
||||
if (item is BaseBeverage bev)
|
||||
{
|
||||
bev.Content = Content;
|
||||
bev.Quantity = bev.MaxQuantity;
|
||||
}
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.FillableBarrel"
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"version": 2,
|
||||
"type": "Server.Items.FillableContainer",
|
||||
"properties": [
|
||||
{
|
||||
"name": "RawContentType",
|
||||
"type": "Server.Items.FillableContentType",
|
||||
"rule": "EnumMigrationRule"
|
||||
},
|
||||
{
|
||||
"name": "RespawnTimer",
|
||||
"type": "Server.Timer",
|
||||
"rule": "TimerMigrationRule",
|
||||
"ruleArguments": [
|
||||
"@TimerDrift"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.FillableLargeCrate"
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.FillableMetalBox"
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.FillableMetalChest"
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.FillableMetalGoldenChest"
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.FillableSmallCrate"
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.FillableWoodenBox"
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.FillableWoodenChest"
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"version": 0,
|
||||
"type": "Server.Items.LibraryBookcase"
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue