fix: Codegens and fixes bugs with plant system (#1490)

This commit is contained in:
Kamron Batman 2023-09-05 19:20:03 -07:00 committed by GitHub
parent 01b864f955
commit 6820efe0ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 2305 additions and 2228 deletions

View file

@ -1836,7 +1836,7 @@ namespace Server.Engines.ConPVP
mob.RemoveStatMod("Holy Bless"); mob.RemoveStatMod("Holy Bless");
mob.RemoveStatMod("Holy Curse"); mob.RemoveStatMod("Holy Curse");
OrangePetals.RemoveContext(mob); OrangePetals.RemoveEffect(mob);
mob.Paralyzed = false; mob.Paralyzed = false;
mob.Hidden = false; mob.Hidden = false;

View file

@ -1,31 +1,15 @@
namespace Server.Items using ModernUO.Serialization;
namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class FertileDirt : Item
{ {
public class FertileDirt : Item [Constructible]
public FertileDirt(int amount = 1) : base(0xF81)
{ {
[Constructible] Stackable = true;
public FertileDirt(int amount = 1) : base(0xF81) Weight = 1.0;
{ Amount = amount;
Stackable = true;
Weight = 1.0;
Amount = amount;
}
public FertileDirt(Serial serial) : base(serial)
{
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -1,133 +1,89 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using ModernUO.Serialization;
namespace Server.Items namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class OrangePetals : Item
{ {
public class OrangePetals : Item private static readonly Dictionary<Mobile, Timer> _table =
new();
[Constructible]
public OrangePetals(int amount = 1) : base(0x1021)
{ {
private static readonly Dictionary<Mobile, OrangePetalsContext> m_Table = Stackable = true;
new(); Hue = 0x2B;
Amount = amount;
}
[Constructible] public override int LabelNumber => 1053122; // orange petals
public OrangePetals(int amount = 1) : base(0x1021)
public override double DefaultWeight => 0.1;
public override bool CheckItemUse(Mobile from, Item item)
{
if (item != this)
{ {
Stackable = true;
Hue = 0x2B;
Amount = amount;
}
public OrangePetals(Serial serial) : base(serial)
{
}
public override int LabelNumber => 1053122; // orange petals
public override double DefaultWeight => 0.1;
public override bool CheckItemUse(Mobile from, Item item)
{
if (item != this)
{
return base.CheckItemUse(from, item);
}
if (from != RootParent)
{
from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
return false;
}
return base.CheckItemUse(from, item); return base.CheckItemUse(from, item);
} }
public override void OnDoubleClick(Mobile from) if (from != RootParent)
{ {
var context = GetContext(from); from.SendLocalizedMessage(1042038); // You must have the object in your backpack to use it.
return false;
}
if (context != null) return base.CheckItemUse(from, item);
}
public override void OnDoubleClick(Mobile from)
{
if (UnderEffect(from))
{
// * You already feel resilient! You decide to save the petal for later *
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061904);
return;
}
// * You eat the orange petal. You feel more resilient! *
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061905);
from.PlaySound(0x3B);
Timer timer = new OrangePetalsTimer(from);
timer.Start();
_table[from] = timer;
Consume();
}
public static void RemoveEffect(Mobile m)
{
if (_table.Remove(m, out var timer))
{
timer.Stop();
}
}
public static bool UnderEffect(Mobile m) => _table.ContainsKey(m);
private class OrangePetalsTimer : Timer
{
private readonly Mobile _mobile;
public OrangePetalsTimer(Mobile from) : base(TimeSpan.FromMinutes(5.0)) => _mobile = from;
protected override void OnTick()
{
if (!_mobile.Deleted)
{ {
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061904); // * You feel the effects of your poison resistance wearing off *
return; _mobile.LocalOverheadMessage(MessageType.Regular, 0x3F, 1053091);
} }
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061905); RemoveEffect(_mobile);
from.PlaySound(0x3B);
Timer timer = new OrangePetalsTimer(from);
timer.Start();
AddContext(from, new OrangePetalsContext(timer));
Consume();
}
private static void AddContext(Mobile m, OrangePetalsContext context)
{
m_Table[m] = context;
}
public static void RemoveContext(Mobile m)
{
var context = GetContext(m);
if (context != null)
{
RemoveContext(m, context);
}
}
private static void RemoveContext(Mobile m, OrangePetalsContext context)
{
m_Table.Remove(m);
context.Timer.Stop();
}
private static OrangePetalsContext GetContext(Mobile m)
{
m_Table.TryGetValue(m, out var context);
return context;
}
public static bool UnderEffect(Mobile m) => m_Table.ContainsKey(m);
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
private class OrangePetalsTimer : Timer
{
private readonly Mobile m_Mobile;
public OrangePetalsTimer(Mobile from) : base(TimeSpan.FromMinutes(5.0)) => m_Mobile = from;
protected override void OnTick()
{
if (!m_Mobile.Deleted)
{
// * You feel the effects of your poison resistance wearing off *
m_Mobile.LocalOverheadMessage(MessageType.Regular, 0x3F, 1053091);
}
RemoveContext(m_Mobile);
}
}
private class OrangePetalsContext
{
public OrangePetalsContext(Timer timer) => Timer = timer;
public Timer Timer { get; }
} }
} }
} }

View file

@ -1,94 +1,72 @@
using ModernUO.Serialization;
using Server.Targeting; using Server.Targeting;
namespace Server.Items namespace Server.Items;
[SerializationGenerator(0, false)]
public partial class RedLeaves : Item
{ {
public class RedLeaves : Item [Constructible]
public RedLeaves(int amount = 1) : base(0x1E85)
{ {
[Constructible] Stackable = true;
public RedLeaves(int amount = 1) : base(0x1E85) Hue = 0x21;
Amount = amount;
}
public override int LabelNumber => 1053123; // red leaves
public override double DefaultWeight => 0.1;
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{ {
Stackable = true; from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
Hue = 0x21; return;
Amount = amount;
} }
public RedLeaves(Serial serial) : base(serial) from.Target = new InternalTarget(this);
from.SendLocalizedMessage(1061907); // Choose a book you wish to seal with the wax from the red leaf.
}
private class InternalTarget : Target
{
private readonly RedLeaves _redLeaves;
public InternalTarget(RedLeaves redLeaves) : base(3, false, TargetFlags.None) => _redLeaves = redLeaves;
protected override void OnTarget(Mobile from, object targeted)
{ {
} if (_redLeaves.Deleted)
{
return;
}
public override int LabelNumber => 1053123; // red leaves if (!_redLeaves.IsChildOf(from.Backpack))
public override double DefaultWeight => 0.1;
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{ {
from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it. from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
return; return;
} }
from.Target = new InternalTarget(this); if (targeted is not Item item || !item.IsChildOf(from.Backpack))
from.SendLocalizedMessage(1061907); // Choose a book you wish to seal with the wax from the red leaf.
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
private class InternalTarget : Target
{
private readonly RedLeaves m_RedLeaves;
public InternalTarget(RedLeaves redLeaves) : base(3, false, TargetFlags.None) => m_RedLeaves = redLeaves;
protected override void OnTarget(Mobile from, object targeted)
{ {
if (m_RedLeaves.Deleted) from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
{ }
return; else if (item is not BaseBook book)
} {
item.LabelTo(from, 1061911); // You can only use red leaves to seal the ink into book pages!
}
else if (!book.Writable)
{
book.LabelTo(from, 1061909); // The ink in this book has already been sealed.
}
else
{
_redLeaves.Consume();
book.Writable = false;
if (!m_RedLeaves.IsChildOf(from.Backpack)) book.LabelTo(from, 1061910); // You seal the ink to the page using wax from the red leaf.
{
from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
return;
}
if (targeted is not Item item || !item.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
}
else if (item is not BaseBook)
{
item.LabelTo(from, 1061911); // You can only use red leaves to seal the ink into book pages!
}
else
{
var book = (BaseBook)item;
if (!book.Writable)
{
book.LabelTo(from, 1061909); // The ink in this book has already been sealed.
}
else
{
m_RedLeaves.Consume();
book.Writable = false;
book.LabelTo(from, 1061910); // You seal the ink to the page using wax from the red leaf.
}
}
} }
} }
} }

View file

@ -1,71 +1,55 @@
namespace Server.Mobiles using ModernUO.Serialization;
namespace Server.Mobiles;
[SerializationGenerator(0, false)]
public partial class GiantIceWorm : BaseCreature
{ {
public class GiantIceWorm : BaseCreature [Constructible]
public GiantIceWorm() : base(AIType.AI_Melee)
{ {
[Constructible] Body = 89;
public GiantIceWorm() : base(AIType.AI_Melee) BaseSoundID = 0xDC;
{
Body = 89;
BaseSoundID = 0xDC;
SetStr(216, 245); SetStr(216, 245);
SetDex(76, 100); SetDex(76, 100);
SetInt(66, 85); SetInt(66, 85);
SetHits(130, 147); SetHits(130, 147);
SetDamage(7, 17); SetDamage(7, 17);
SetDamageType(ResistanceType.Physical, 10); SetDamageType(ResistanceType.Physical, 10);
SetDamageType(ResistanceType.Cold, 90); SetDamageType(ResistanceType.Cold, 90);
SetResistance(ResistanceType.Physical, 30, 35); SetResistance(ResistanceType.Physical, 30, 35);
SetResistance(ResistanceType.Fire, 0); SetResistance(ResistanceType.Fire, 0);
SetResistance(ResistanceType.Cold, 80, 90); SetResistance(ResistanceType.Cold, 80, 90);
SetResistance(ResistanceType.Poison, 15, 25); SetResistance(ResistanceType.Poison, 15, 25);
SetResistance(ResistanceType.Energy, 10, 20); SetResistance(ResistanceType.Energy, 10, 20);
SetSkill(SkillName.Poisoning, 75.1, 95.0); SetSkill(SkillName.Poisoning, 75.1, 95.0);
SetSkill(SkillName.MagicResist, 45.1, 60.0); SetSkill(SkillName.MagicResist, 45.1, 60.0);
SetSkill(SkillName.Tactics, 75.1, 80.0); SetSkill(SkillName.Tactics, 75.1, 80.0);
SetSkill(SkillName.Wrestling, 60.1, 80.0); SetSkill(SkillName.Wrestling, 60.1, 80.0);
Fame = 4500; Fame = 4500;
Karma = -4500; Karma = -4500;
VirtualArmor = 40; VirtualArmor = 40;
Tamable = true; Tamable = true;
ControlSlots = 1; ControlSlots = 1;
MinTameSkill = 71.1; MinTameSkill = 71.1;
}
public GiantIceWorm(Serial serial) : base(serial)
{
}
public override string CorpseName => "a giant ice worm corpse";
public override bool SubdueBeforeTame => true;
public override string DefaultName => "a giant ice worm";
public override Poison PoisonImmune => Poison.Greater;
public override Poison HitPoison => Poison.Greater;
public override FoodType FavoriteFood => FoodType.Meat;
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
} }
public override string CorpseName => "a giant ice worm corpse";
public override bool SubdueBeforeTame => true;
public override string DefaultName => "a giant ice worm";
public override Poison PoisonImmune => Poison.Greater;
public override Poison HitPoison => Poison.Greater;
public override FoodType FavoriteFood => FoodType.Meat;
} }

View file

@ -1,190 +1,155 @@
using ModernUO.Serialization;
using Server.Items; using Server.Items;
using Server.Targeting; using Server.Targeting;
namespace Server.Engines.Plants namespace Server.Engines.Plants;
[SerializationGenerator(0, false)]
public partial class PlantBowl : Item
{ {
public class PlantBowl : Item private static readonly int[] _dirtPatchLandTiles =
{ {
private static readonly int[] _dirtPatchLandTiles = 0x9, 0x15,
{ 0x71, 0x7C,
0x9, 0x15, 0x82, 0xA7,
0x71, 0x7C, 0xDC, 0xE3,
0x82, 0xA7, 0xE8, 0xEB,
0xDC, 0xE3, 0x141, 0x144,
0xE8, 0xEB, 0x14C, 0x15C,
0x141, 0x144, 0x169, 0x174,
0x14C, 0x15C, 0x1DC, 0x1EF,
0x169, 0x174, 0x272, 0x275,
0x1DC, 0x1EF, 0x27E, 0x281,
0x272, 0x275, 0x2D0, 0x2D7,
0x27E, 0x281, 0x2E5, 0x2FF,
0x2D0, 0x2D7, 0x303, 0x31F,
0x2E5, 0x2FF, 0x32C, 0x32F,
0x303, 0x31F, 0x33D, 0x340,
0x32C, 0x32F, 0x345, 0x34C,
0x33D, 0x340, 0x355, 0x358,
0x345, 0x34C, 0x367, 0x36E,
0x355, 0x358, 0x377, 0x37A,
0x367, 0x36E, 0x38D, 0x390,
0x377, 0x37A, 0x395, 0x39C,
0x38D, 0x390, 0x3A5, 0x3A8,
0x395, 0x39C, 0x3F6, 0x405,
0x3A5, 0x3A8, 0x547, 0x54E,
0x3F6, 0x405, 0x553, 0x556,
0x547, 0x54E, 0x597, 0x59E,
0x553, 0x556, 0x623, 0x63A,
0x597, 0x59E, 0x6F3, 0x6FA,
0x623, 0x63A, 0x777, 0x791,
0x6F3, 0x6FA, 0x79A, 0x7A9,
0x777, 0x791, 0x7AE, 0x7B1,
0x79A, 0x7A9, 0x98C, 0x99F,
0x7AE, 0x7B1, 0x9AC, 0x9BF,
0x98C, 0x99F, 0x5B27, 0x5B3E,
0x9AC, 0x9BF, 0x71F4, 0x71FB,
0x5B27, 0x5B3E, 0x72C9, 0x72CA
0x71F4, 0x71FB, };
0x72C9, 0x72CA
};
private static readonly int[] _dirtPatchStaticTiles = private static readonly int[] _dirtPatchStaticTiles =
{ {
0x1B27, 0x1B3E, 0x1B27, 0x1B3E,
0x31F4, 0x31FB, 0x31F4, 0x31FB,
0x32C9, 0x32CA 0x32C9, 0x32CA
}; };
[Constructible] [Constructible]
public PlantBowl() : base(0x15FD) => Weight = 1.0; public PlantBowl() : base(0x15FD) => Weight = 1.0;
public PlantBowl(Serial serial) : base(serial) public override int LabelNumber => 1060834; // a plant bowl
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{ {
from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
return;
} }
public override int LabelNumber => 1060834; // a plant bowl from.Target = new InternalTarget(this);
from.SendLocalizedMessage(1061897); // Choose a patch of dirt to scoop up.
}
public override void OnDoubleClick(Mobile from) public static bool IsDirtPatch(object obj)
{
int tileID;
int[] tiles;
if (obj is Static staticObj && !staticObj.Movable)
{ {
if (!IsChildOf(from.Backpack)) tileID = staticObj.ItemID;
tiles = _dirtPatchStaticTiles;
}
else if (obj is StaticTarget staticTarget)
{
tileID = staticTarget.ItemID;
tiles = _dirtPatchStaticTiles;
}
else if (obj is LandTarget landTarget)
{
tileID = landTarget.TileID;
tiles = _dirtPatchLandTiles;
}
else
{
return false;
}
var contains = false;
for (var i = 0; !contains && i < tiles.Length; i += 2)
{
contains = tileID >= tiles[i] && tileID <= tiles[i + 1];
}
return contains;
}
private class InternalTarget : Target
{
private readonly PlantBowl _plantBowl;
public InternalTarget(PlantBowl plantBowl) : base(3, true, TargetFlags.None) => _plantBowl = plantBowl;
protected override void OnTarget(Mobile from, object targeted)
{
if (_plantBowl.Deleted)
{
return;
}
if (!_plantBowl.IsChildOf(from.Backpack))
{ {
from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it. from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
return; return;
} }
from.Target = new InternalTarget(this); if (targeted is FertileDirt dirt)
from.SendLocalizedMessage(1061897); // Choose a patch of dirt to scoop up.
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
}
public static bool IsDirtPatch(object obj)
{
int tileID;
int[] tiles;
if (obj is Static staticObj && !staticObj.Movable)
{ {
tileID = staticObj.ItemID; var _dirtNeeded = Core.ML ? 20 : 40;
tiles = _dirtPatchStaticTiles;
}
else if (obj is StaticTarget staticTarget)
{
tileID = staticTarget.ItemID;
tiles = _dirtPatchStaticTiles;
}
else if (obj is LandTarget landTarget)
{
tileID = landTarget.TileID;
tiles = _dirtPatchLandTiles;
}
else
{
return false;
}
var contains = false; if (!dirt.IsChildOf(from.Backpack))
for (var i = 0; !contains && i < tiles.Length; i += 2)
{
contains = tileID >= tiles[i] && tileID <= tiles[i + 1];
}
return contains;
}
private class InternalTarget : Target
{
private readonly PlantBowl m_PlantBowl;
public InternalTarget(PlantBowl plantBowl) : base(3, true, TargetFlags.None) => m_PlantBowl = plantBowl;
protected override void OnTarget(Mobile from, object targeted)
{
if (m_PlantBowl.Deleted)
{
return;
}
if (!m_PlantBowl.IsChildOf(from.Backpack))
{ {
from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it. from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
return;
} }
else if (dirt.Amount < _dirtNeeded)
if (targeted is FertileDirt dirt)
{ {
var _dirtNeeded = Core.ML ? 20 : 40; // You need more dirt to fill a plant bowl!
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061896);
if (!dirt.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
}
else if (dirt.Amount < _dirtNeeded)
{
// You need more dirt to fill a plant bowl!
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061896);
}
else
{
var fullBowl = new PlantItem(true);
if (from.PlaceInBackpack(fullBowl))
{
dirt.Consume(_dirtNeeded);
m_PlantBowl.Delete();
// You fill the bowl with fresh dirt.
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061895);
}
else
{
fullBowl.Delete();
// There is no room in your backpack for a bowl full of dirt!
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061894);
}
}
} }
else if (IsDirtPatch(targeted)) else
{ {
var fullBowl = new PlantItem(); var fullBowl = new PlantItem(true);
if (from.PlaceInBackpack(fullBowl)) if (from.PlaceInBackpack(fullBowl))
{ {
m_PlantBowl.Delete(); dirt.Consume(_dirtNeeded);
_plantBowl.Delete();
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061895); // You fill the bowl with fresh dirt. // You fill the bowl with fresh dirt.
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061895);
} }
else else
{ {
@ -194,17 +159,35 @@ namespace Server.Engines.Plants
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061894); from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061894);
} }
} }
}
else if (IsDirtPatch(targeted))
{
var fullBowl = new PlantItem();
if (from.PlaceInBackpack(fullBowl))
{
_plantBowl.Delete();
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061895); // You fill the bowl with fresh dirt.
}
else else
{ {
// You'll want to gather fresh dirt in order to raise a healthy plant! fullBowl.Delete();
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061893);
// There is no room in your backpack for a bowl full of dirt!
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061894);
} }
} }
else
protected override void OnTargetOutOfRange(Mobile from, object targeted)
{ {
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 502825); // That location is too far away // You'll want to gather fresh dirt in order to raise a healthy plant!
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1061893);
} }
} }
protected override void OnTargetOutOfRange(Mobile from, object targeted)
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 502825); // That location is too far away
}
} }
} }

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,5 @@
using System; using System;
using ModernUO.Serialization;
using Server.Misc; using Server.Misc;
namespace Server.Engines.Plants namespace Server.Engines.Plants
@ -21,298 +22,350 @@ namespace Server.Engines.Plants
DoubleGrown DoubleGrown
} }
public class PlantSystem [SerializationGenerator(3, false)]
public partial class PlantSystem
{ {
public static readonly TimeSpan CheckDelay = TimeSpan.FromHours(23.0); public static readonly TimeSpan CheckDelay = TimeSpan.FromHours(23.0);
private int m_AvailableResources; [DirtyTrackingEntity]
private int m_AvailableSeeds; private PlantItem _plant;
private int m_CurePotion;
private int m_Disease;
private int m_Fungus;
private int m_HealPotion;
private int m_Hits; [SerializableField(0)]
private int m_Infestation; private bool _fertileDirt;
private int m_LeftResources;
private int m_LeftSeeds;
private int m_Poison;
private int m_PoisonPotion;
private PlantHue m_SeedHue;
private PlantType m_SeedType; [SerializableFieldSaveFlag(0)]
private int m_StrengthPotion; private bool ShouldSerializeFertileDirt() => _fertileDirt;
private int m_Water; [SerializableField(1)]
private DateTime _nextGrowth;
public PlantSystem(PlantItem plant, bool fertileDirt) [SerializableField(2, setter: "private")]
private PlantGrowthIndicator _growthIndicator;
[SerializableFieldSaveFlag(2)]
private bool ShouldSerializeGrowthIndicator() => _growthIndicator != PlantGrowthIndicator.None;
[SerializableField(13)]
private bool _pollinated;
[SerializableFieldSaveFlag(13)]
private bool ShouldSerializePollinated() => _pollinated;
public PlantSystem(PlantItem plant)
{ {
Plant = plant; _plant = plant;
FertileDirt = fertileDirt;
NextGrowth = Core.Now + CheckDelay; _nextGrowth = Core.Now + CheckDelay;
GrowthIndicator = PlantGrowthIndicator.None; _growthIndicator = PlantGrowthIndicator.None;
m_Hits = MaxHits; _hits = MaxHits;
m_LeftSeeds = 8; _leftSeeds = 8;
m_LeftResources = 8; _leftResources = 8;
} }
public PlantSystem(PlantItem plant, IGenericReader reader) private void Deserialize(IGenericReader reader, int version)
{ {
Plant = plant; _fertileDirt = reader.ReadBool();
NextGrowth = reader.ReadDateTime();
var version = reader.ReadInt();
FertileDirt = reader.ReadBool();
if (version >= 1)
{
NextGrowth = reader.ReadDateTime();
}
else
{
NextGrowth = reader.ReadDeltaTime();
}
GrowthIndicator = (PlantGrowthIndicator)reader.ReadInt(); GrowthIndicator = (PlantGrowthIndicator)reader.ReadInt();
m_Water = reader.ReadInt(); _water = reader.ReadInt();
m_Hits = reader.ReadInt(); _hits = reader.ReadInt();
m_Infestation = reader.ReadInt(); _infestation = reader.ReadInt();
m_Fungus = reader.ReadInt(); _fungus = reader.ReadInt();
m_Poison = reader.ReadInt(); _poison = reader.ReadInt();
m_Disease = reader.ReadInt(); _disease = reader.ReadInt();
m_PoisonPotion = reader.ReadInt(); _poisonPotion = reader.ReadInt();
m_CurePotion = reader.ReadInt(); _curePotion = reader.ReadInt();
m_HealPotion = reader.ReadInt(); _healPotion = reader.ReadInt();
m_StrengthPotion = reader.ReadInt(); _strengthPotion = reader.ReadInt();
Pollinated = reader.ReadBool(); Pollinated = reader.ReadBool();
m_SeedType = (PlantType)reader.ReadInt(); _seedType = (PlantType)reader.ReadInt();
m_SeedHue = (PlantHue)reader.ReadInt(); _seedHue = (PlantHue)reader.ReadInt();
m_AvailableSeeds = reader.ReadInt(); _availableSeeds = reader.ReadInt();
m_LeftSeeds = reader.ReadInt(); _leftSeeds = reader.ReadInt();
m_AvailableResources = reader.ReadInt(); _availableResources = reader.ReadInt();
m_LeftResources = reader.ReadInt(); _leftResources = reader.ReadInt();
if (version < 2 && PlantHueInfo.IsCrossable(m_SeedHue))
{
m_SeedHue |= PlantHue.Reproduces;
}
} }
public PlantItem Plant { get; } public PlantItem Plant => _plant;
public bool FertileDirt { get; set; } public bool IsFullWater => _water >= 4;
public DateTime NextGrowth { get; private set; }
public PlantGrowthIndicator GrowthIndicator { get; private set; }
public bool IsFullWater => m_Water >= 4;
[SerializableProperty(3)]
public int Water public int Water
{ {
get => m_Water; get => _water;
set set
{ {
m_Water = Math.Clamp(value, 0, 4); _water = Math.Clamp(value, 0, 4);
Plant.InvalidateProperties(); Plant.InvalidateProperties();
MarkDirty();
} }
} }
[SerializableFieldSaveFlag(3)]
private bool ShouldSerializeWater() => _water != 0;
[SerializableProperty(4)]
public int Hits public int Hits
{ {
get => m_Hits; get => _hits;
set set
{ {
if (m_Hits == value) if (_hits == value)
{ {
return; return;
} }
m_Hits = Math.Clamp(value, 0, MaxHits); _hits = Math.Clamp(value, 0, MaxHits);
if (m_Hits == 0) if (_hits == 0)
{ {
Plant.Die(); Plant.Die();
} }
Plant.InvalidateProperties(); Plant.InvalidateProperties();
MarkDirty();
} }
} }
[SerializableFieldSaveFlag(4)]
private bool ShouldSerializeHits() => _hits != 0;
public int MaxHits => 10 + (int)Plant.PlantStatus * 2; public int MaxHits => 10 + (int)Plant.PlantStatus * 2;
public PlantHealth Health public PlantHealth Health
{ {
get get => (_hits * 100 / MaxHits) switch
{ {
var perc = m_Hits * 100 / MaxHits; < 33 => PlantHealth.Dying,
< 66 => PlantHealth.Wilted,
< 100 => PlantHealth.Healthy,
_ => PlantHealth.Vibrant
};
}
if (perc < 33) [SerializableProperty(5)]
{ public int Infestation
return PlantHealth.Dying; {
} get => _infestation;
set
if (perc < 66) {
{ _infestation = Math.Clamp(value, 0, 2);
return PlantHealth.Wilted; MarkDirty();
}
return perc < 100 ? PlantHealth.Healthy : PlantHealth.Vibrant;
} }
} }
public int Infestation [SerializableFieldSaveFlag(5)]
{ private bool ShouldSerializeInfestation() => _infestation != 0;
get => m_Infestation;
set => m_Infestation = Math.Clamp(value, 0, 2);
}
[SerializableProperty(6)]
public int Fungus public int Fungus
{ {
get => m_Fungus; get => _fungus;
set => m_Fungus = Math.Clamp(value, 0, 2); set
{
_fungus = Math.Clamp(value, 0, 2);
MarkDirty();
}
} }
[SerializableFieldSaveFlag(6)]
private bool ShouldSerializeFungus() => _fungus != 0;
[SerializableProperty(7)]
public int Poison public int Poison
{ {
get => m_Poison; get => _poison;
set => m_Poison = Math.Clamp(value, 0, 2); set
{
_poison = Math.Clamp(value, 0, 2);
MarkDirty();
}
} }
[SerializableFieldSaveFlag(7)]
private bool ShouldSerializePoison() => _poison != 0;
[SerializableProperty(8)]
public int Disease public int Disease
{ {
get => m_Disease; get => _disease;
set => m_Disease = Math.Clamp(value, 0, 2); set
{
_disease = Math.Clamp(value, 0, 2);
MarkDirty();
}
} }
public bool IsFullPoisonPotion => m_PoisonPotion >= 2; [SerializableFieldSaveFlag(8)]
private bool ShouldSerializeDisease() => _disease != 0;
public bool IsFullPoisonPotion => _poisonPotion >= 2;
[SerializableProperty(9)]
public int PoisonPotion public int PoisonPotion
{ {
get => m_PoisonPotion; get => _poisonPotion;
set => m_PoisonPotion = Math.Clamp(value, 0, 2); set
{
_poisonPotion = Math.Clamp(value, 0, 2);
MarkDirty();
}
} }
public bool IsFullCurePotion => m_CurePotion >= 2; [SerializableFieldSaveFlag(9)]
private bool ShouldSerializePoisonPotion() => _poisonPotion != 0;
public bool IsFullCurePotion => _curePotion >= 2;
[SerializableProperty(10)]
public int CurePotion public int CurePotion
{ {
get => m_CurePotion; get => _curePotion;
set => m_CurePotion = Math.Clamp(value, 0, 2); set
{
_curePotion = Math.Clamp(value, 0, 2);
MarkDirty();
}
} }
public bool IsFullHealPotion => m_HealPotion >= 2; [SerializableFieldSaveFlag(10)]
private bool ShouldSerializeCurePotion() => _curePotion != 0;
public bool IsFullHealPotion => _healPotion >= 2;
[SerializableProperty(11)]
public int HealPotion public int HealPotion
{ {
get => m_HealPotion; get => _healPotion;
set => m_HealPotion = Math.Clamp(value, 0, 2); set
{
_healPotion = Math.Clamp(value, 0, 2);
MarkDirty();
}
} }
public bool IsFullStrengthPotion => m_StrengthPotion >= 2; [SerializableFieldSaveFlag(11)]
private bool ShouldSerializeHealPotion() => _healPotion != 0;
public bool IsFullStrengthPotion => _strengthPotion >= 2;
[SerializableProperty(12)]
public int StrengthPotion public int StrengthPotion
{ {
get => m_StrengthPotion; get => _strengthPotion;
set => m_StrengthPotion = Math.Clamp(value, 0, 2); set
{
_strengthPotion = Math.Clamp(value, 0, 2);
MarkDirty();
}
} }
[SerializableFieldSaveFlag(12)]
private bool ShouldSerializeStrengthPotion() => _strengthPotion != 0;
public bool HasMaladies => Infestation > 0 || Fungus > 0 || Poison > 0 || Disease > 0 || Water != 2; public bool HasMaladies => Infestation > 0 || Fungus > 0 || Poison > 0 || Disease > 0 || Water != 2;
public bool PollenProducing => Plant.IsCrossable && Plant.PlantStatus >= PlantStatus.FullGrownPlant; public bool PollenProducing => Plant.IsCrossable && Plant.PlantStatus >= PlantStatus.FullGrownPlant;
public bool Pollinated { get; set; } [SerializableProperty(14)]
public PlantType SeedType public PlantType SeedType
{ {
get => Pollinated ? m_SeedType : Plant.PlantType; get => Pollinated ? _seedType : Plant.PlantType;
set => m_SeedType = value; set
{
_seedType = value;
MarkDirty();
}
} }
[SerializableFieldSaveFlag(14)]
private bool ShouldSerializeSeedType() => _pollinated;
[SerializableProperty(15)]
public PlantHue SeedHue public PlantHue SeedHue
{ {
get => Pollinated ? m_SeedHue : Plant.PlantHue; get => Pollinated ? _seedHue : Plant.PlantHue;
set => m_SeedHue = value; set
{
_seedHue = value;
MarkDirty();
}
} }
[SerializableFieldSaveFlag(15)]
private bool ShouldSerializeSeedHue() => _pollinated;
[SerializableProperty(16)]
public int AvailableSeeds public int AvailableSeeds
{ {
get => m_AvailableSeeds; get => _availableSeeds;
set set => _availableSeeds = Math.Max(value, 0);
{
if (value >= 0)
{
m_AvailableSeeds = value;
}
}
} }
[SerializableFieldSaveFlag(16)]
private bool ShouldSerializeAvailableSeeds() => _availableSeeds != 0;
[SerializableProperty(17)]
public int LeftSeeds public int LeftSeeds
{ {
get => m_LeftSeeds; get => _leftSeeds;
set set => _leftSeeds = Math.Max(value, 0);
{
if (value >= 0)
{
m_LeftSeeds = value;
}
}
} }
[SerializableFieldSaveFlag(17)]
private bool ShouldSerializeLeftSeeds() => _leftSeeds != 0;
[SerializableProperty(18)]
public int AvailableResources public int AvailableResources
{ {
get => m_AvailableResources; get => _availableResources;
set set => _availableResources = Math.Max(value, 0);
{
if (value >= 0)
{
m_AvailableResources = value;
}
}
} }
[SerializableFieldSaveFlag(18)]
private bool ShouldSerializeAvailableResources() => _availableResources != 0;
[SerializableProperty(19)]
public int LeftResources public int LeftResources
{ {
get => m_LeftResources; get => _leftResources;
set set => _leftResources = Math.Max(value, 0);
{
if (value >= 0)
{
m_LeftResources = value;
}
}
} }
[SerializableFieldSaveFlag(19)]
private bool ShouldSerializeLeftResources() => _leftResources != 0;
public void Reset(bool potions) public void Reset(bool potions)
{ {
NextGrowth = Core.Now + CheckDelay; NextGrowth = Core.Now + CheckDelay;
GrowthIndicator = PlantGrowthIndicator.None; GrowthIndicator = PlantGrowthIndicator.None;
Hits = MaxHits; Hits = MaxHits;
m_Infestation = 0; Infestation = 0;
m_Fungus = 0; Fungus = 0;
m_Poison = 0; Poison = 0;
m_Disease = 0; Disease = 0;
if (potions) if (potions)
{ {
m_PoisonPotion = 0; PoisonPotion = 0;
m_CurePotion = 0; CurePotion = 0;
m_HealPotion = 0; HealPotion = 0;
m_StrengthPotion = 0; StrengthPotion = 0;
} }
Pollinated = false; Pollinated = false;
m_AvailableSeeds = 0; AvailableSeeds = 0;
m_LeftSeeds = 8; LeftSeeds = 8;
m_AvailableResources = 0; AvailableResources = 0;
m_LeftResources = 8; LeftResources = 8;
} }
public int GetLocalizedDirtStatus() => public int GetLocalizedDirtStatus() =>
@ -634,36 +687,5 @@ namespace Server.Engines.Plants
StrengthPotion = 0; StrengthPotion = 0;
} }
public void Save(IGenericWriter writer)
{
writer.Write(2); // version
writer.Write(FertileDirt);
writer.Write(NextGrowth);
writer.Write((int)GrowthIndicator);
writer.Write(m_Water);
writer.Write(m_Hits);
writer.Write(m_Infestation);
writer.Write(m_Fungus);
writer.Write(m_Poison);
writer.Write(m_Disease);
writer.Write(m_PoisonPotion);
writer.Write(m_CurePotion);
writer.Write(m_HealPotion);
writer.Write(m_StrengthPotion);
writer.Write(Pollinated);
writer.Write((int)m_SeedType);
writer.Write((int)m_SeedHue);
writer.Write(m_AvailableSeeds);
writer.Write(m_LeftSeeds);
writer.Write(m_AvailableResources);
writer.Write(m_LeftResources);
}
} }
} }

View file

@ -1,271 +1,224 @@
using ModernUO.Serialization;
using Server.Targeting; using Server.Targeting;
namespace Server.Engines.Plants namespace Server.Engines.Plants;
[SerializationGenerator(3, false)]
public partial class Seed : Item
{ {
public class Seed : Item [InvalidateProperties]
[SerializableField(0)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private PlantType _plantType;
[InvalidateProperties]
[SerializableField(2)]
[SerializedCommandProperty(AccessLevel.GameMaster)]
private bool _showType;
[Constructible]
public Seed() : this(PlantTypeInfo.RandomFirstGeneration(), PlantHueInfo.RandomFirstGeneration())
{ {
private PlantHue m_PlantHue; }
private PlantType m_PlantType;
private bool m_ShowType;
[Constructible] [Constructible]
public Seed() : this(PlantTypeInfo.RandomFirstGeneration(), PlantHueInfo.RandomFirstGeneration()) public Seed(PlantType plantType, PlantHue plantHue, bool showType = false) : base(0xDCF)
{
Weight = 1.0;
Stackable = Core.SA;
_plantType = plantType;
_plantHue = plantHue;
_showType = showType;
Hue = PlantHueInfo.GetInfo(plantHue).Hue;
}
[CommandProperty(AccessLevel.GameMaster)]
[SerializableProperty(1)]
public PlantHue PlantHue
{
get => _plantHue;
set
{ {
_plantHue = value;
Hue = PlantHueInfo.GetInfo(value).Hue;
InvalidateProperties();
this.MarkDirty();
}
}
public override int LabelNumber => 1060810; // seed
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public static Seed RandomBonsaiSeed() => RandomBonsaiSeed(0.5);
public static Seed RandomBonsaiSeed(double increaseRatio) => new(
PlantTypeInfo.RandomBonsai(increaseRatio),
PlantHue.Plain
);
public static Seed RandomPeculiarSeed(int group)
{
return group switch
{
1 => new Seed(PlantTypeInfo.RandomPeculiarGroupOne(), PlantHue.Plain),
2 => new Seed(PlantTypeInfo.RandomPeculiarGroupTwo(), PlantHue.Plain),
3 => new Seed(PlantTypeInfo.RandomPeculiarGroupThree(), PlantHue.Plain),
_ => new Seed(PlantTypeInfo.RandomPeculiarGroupFour(), PlantHue.Plain)
};
}
private int GetLabel(out string args)
{
var typeInfo = PlantTypeInfo.GetInfo(_plantType);
var hueInfo = PlantHueInfo.GetInfo(_plantHue);
int title;
if (_showType || typeInfo.PlantCategory == PlantCategory.Default)
{
title = hueInfo.Name;
}
else
{
title = (int)typeInfo.PlantCategory;
} }
[Constructible] if (Amount == 1)
public Seed(PlantType plantType, PlantHue plantHue, bool showType = false) : base(0xDCF)
{ {
Weight = 1.0; if (_showType)
Stackable = Core.SA; {
args = $"#{title}\t#{typeInfo.Name}";
return typeInfo.GetSeedLabel(hueInfo);
}
m_PlantType = plantType; args = $"#{title}";
m_PlantHue = plantHue; return hueInfo.IsBright() ? 1060839 : 1060838; // [bright] ~1_val~ seed
m_ShowType = showType;
Hue = PlantHueInfo.GetInfo(plantHue).Hue;
} }
public Seed(Serial serial) : base(serial) if (_showType)
{ {
args = $"{Amount}\t#{title}\t#{typeInfo.Name}";
return typeInfo.GetSeedLabelPlural(hueInfo);
} }
[CommandProperty(AccessLevel.GameMaster)] args = $"{Amount}\t#{title}";
public PlantType PlantType return hueInfo.IsBright() ? 1113491 : 1113490; // ~1_amount~ [bright] ~2_val~ seeds
}
public override void AddNameProperty(IPropertyList list)
{
var typeInfo = PlantTypeInfo.GetInfo(_plantType);
var hueInfo = PlantHueInfo.GetInfo(_plantHue);
int title;
if (_showType || typeInfo.PlantCategory == PlantCategory.Default)
{ {
get => m_PlantType; title = hueInfo.Name;
set }
{ else
m_PlantType = value; {
InvalidateProperties(); title = (int)typeInfo.PlantCategory;
}
} }
[CommandProperty(AccessLevel.GameMaster)] if (Amount == 1)
public PlantHue PlantHue
{ {
get => m_PlantHue; if (_showType)
set
{ {
m_PlantHue = value; list.Add(typeInfo.GetSeedLabel(hueInfo), $"{title:#}\t{typeInfo.Name:#}");
Hue = PlantHueInfo.GetInfo(value).Hue;
InvalidateProperties();
}
}
[CommandProperty(AccessLevel.GameMaster)]
public bool ShowType
{
get => m_ShowType;
set
{
m_ShowType = value;
InvalidateProperties();
}
}
public override int LabelNumber => 1060810; // seed
public override bool ForceShowProperties => ObjectPropertyList.Enabled;
public static Seed RandomBonsaiSeed() => RandomBonsaiSeed(0.5);
public static Seed RandomBonsaiSeed(double increaseRatio) => new(
PlantTypeInfo.RandomBonsai(increaseRatio),
PlantHue.Plain
);
public static Seed RandomPeculiarSeed(int group)
{
return group switch
{
1 => new Seed(PlantTypeInfo.RandomPeculiarGroupOne(), PlantHue.Plain),
2 => new Seed(PlantTypeInfo.RandomPeculiarGroupTwo(), PlantHue.Plain),
3 => new Seed(PlantTypeInfo.RandomPeculiarGroupThree(), PlantHue.Plain),
_ => new Seed(PlantTypeInfo.RandomPeculiarGroupFour(), PlantHue.Plain)
};
}
private int GetLabel(out string args)
{
var typeInfo = PlantTypeInfo.GetInfo(m_PlantType);
var hueInfo = PlantHueInfo.GetInfo(m_PlantHue);
int title;
if (m_ShowType || typeInfo.PlantCategory == PlantCategory.Default)
{
title = hueInfo.Name;
}
else
{
title = (int)typeInfo.PlantCategory;
}
if (Amount == 1)
{
if (m_ShowType)
{
args = $"#{title}\t#{typeInfo.Name}";
return typeInfo.GetSeedLabel(hueInfo);
}
args = $"#{title}";
return hueInfo.IsBright() ? 1060839 : 1060838; // [bright] ~1_val~ seed
}
if (m_ShowType)
{
args = $"{Amount}\t#{title}\t#{typeInfo.Name}";
return typeInfo.GetSeedLabelPlural(hueInfo);
}
args = $"{Amount}\t#{title}";
return hueInfo.IsBright() ? 1113491 : 1113490; // ~1_amount~ [bright] ~2_val~ seeds
}
public override void AddNameProperty(IPropertyList list)
{
var typeInfo = PlantTypeInfo.GetInfo(m_PlantType);
var hueInfo = PlantHueInfo.GetInfo(m_PlantHue);
int title;
if (m_ShowType || typeInfo.PlantCategory == PlantCategory.Default)
{
title = hueInfo.Name;
}
else
{
title = (int)typeInfo.PlantCategory;
}
if (Amount == 1)
{
if (m_ShowType)
{
list.Add(typeInfo.GetSeedLabel(hueInfo), $"{title:#}\t{typeInfo.Name:#}");
return;
}
list.Add(hueInfo.IsBright() ? 1060839 : 1060838, $"{title:#}");
return; return;
} }
if (m_ShowType) list.Add(hueInfo.IsBright() ? 1060839 : 1060838, $"{title:#}");
return;
}
if (_showType)
{
list.Add(typeInfo.GetSeedLabelPlural(hueInfo), $"{Amount}\t{title:#}\t{typeInfo.Name:#}");
return;
}
list.Add(hueInfo.IsBright() ? 1113491 : 1113490, $"{Amount}\t{title:#}");
}
public override void OnSingleClick(Mobile from)
{
LabelTo(from, GetLabel(out var args), args);
}
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
return;
}
from.Target = new InternalTarget(this);
LabelTo(from, 1061916); // Choose a bowl of dirt to plant this seed in.
}
public override bool StackWith(Mobile from, Item dropped, bool playSound) =>
dropped is Seed other && other.PlantType == _plantType && other.PlantHue == _plantHue &&
other.ShowType == _showType && base.StackWith(from, other, playSound);
public override void OnAfterDuped(Item newItem)
{
if (newItem is not Seed newSeed)
{
return;
}
newSeed.PlantType = _plantType;
newSeed.PlantHue = _plantHue;
newSeed.ShowType = _showType;
}
private void Deserialize(IGenericReader reader, int version)
{
_plantType = (PlantType)reader.ReadInt();
_plantHue = (PlantHue)reader.ReadInt();
_showType = reader.ReadBool();
}
private class InternalTarget : Target
{
private readonly Seed _seed;
public InternalTarget(Seed seed) : base(-1, false, TargetFlags.None)
{
_seed = seed;
CheckLOS = false;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (_seed.Deleted)
{ {
list.Add(typeInfo.GetSeedLabelPlural(hueInfo), $"{Amount}\t{title:#}\t{typeInfo.Name:#}");
return; return;
} }
list.Add(hueInfo.IsBright() ? 1113491 : 1113490, $"{Amount}\t{title:#}"); if (!_seed.IsChildOf(from.Backpack))
}
public override void OnSingleClick(Mobile from)
{
LabelTo(from, GetLabel(out var args), args);
}
public override void OnDoubleClick(Mobile from)
{
if (!IsChildOf(from.Backpack))
{ {
from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it. from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
return; return;
} }
from.Target = new InternalTarget(this); if (targeted is PlantItem plant)
LabelTo(from, 1061916); // Choose a bowl of dirt to plant this seed in.
}
public override bool StackWith(Mobile from, Item dropped, bool playSound) =>
dropped is Seed other && other.PlantType == m_PlantType && other.PlantHue == m_PlantHue &&
other.ShowType == m_ShowType && base.StackWith(from, other, playSound);
public override void OnAfterDuped(Item newItem)
{
if (newItem is not Seed newSeed)
{ {
return; plant.PlantSeed(from, _seed);
} }
else if (targeted is Item item)
newSeed.PlantType = m_PlantType;
newSeed.PlantHue = m_PlantHue;
newSeed.ShowType = m_ShowType;
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(2); // version
writer.Write((int)m_PlantType);
writer.Write((int)m_PlantHue);
writer.Write(m_ShowType);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m_PlantType = (PlantType)reader.ReadInt();
m_PlantHue = (PlantHue)reader.ReadInt();
m_ShowType = reader.ReadBool();
if (Weight != 1.0)
{ {
Weight = 1.0; item.LabelTo(from, 1061919); // You must use a seed on a bowl of dirt!
} }
else
if (version < 1)
{ {
Stackable = Core.SA; from.SendLocalizedMessage(1061919); // You must use a seed on a bowl of dirt!
}
if (version < 2 && PlantHueInfo.IsCrossable(m_PlantHue))
{
m_PlantHue |= PlantHue.Reproduces;
}
}
private class InternalTarget : Target
{
private readonly Seed m_Seed;
public InternalTarget(Seed seed) : base(-1, false, TargetFlags.None)
{
m_Seed = seed;
CheckLOS = false;
}
protected override void OnTarget(Mobile from, object targeted)
{
if (m_Seed.Deleted)
{
return;
}
if (!m_Seed.IsChildOf(from.Backpack))
{
from.SendLocalizedMessage(1042664); // You must have the object in your backpack to use it.
return;
}
if (targeted is PlantItem plant)
{
plant.PlantSeed(from, m_Seed);
}
else if (targeted is Item item)
{
item.LabelTo(from, 1061919); // You must use a seed on a bowl of dirt!
}
else
{
from.SendLocalizedMessage(1061919); // You must use a seed on a bowl of dirt!
}
} }
} }
} }

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Engines.Plants.PlantBowl"
}

View file

@ -0,0 +1,48 @@
{
"version": 3,
"type": "Server.Engines.Plants.PlantItem",
"properties": [
{
"name": "Level",
"type": "Server.Multis.SecureLevel",
"usesSaveFlag": true,
"rule": "EnumMigrationRule"
},
{
"name": "PlantStatus",
"type": "Server.Engines.Plants.PlantStatus",
"usesSaveFlag": true,
"rule": "EnumMigrationRule"
},
{
"name": "PlantType",
"type": "Server.Engines.Plants.PlantType",
"usesSaveFlag": true,
"rule": "EnumMigrationRule"
},
{
"name": "PlantHue",
"type": "Server.Engines.Plants.PlantHue",
"usesSaveFlag": true,
"rule": "EnumMigrationRule"
},
{
"name": "ShowType",
"type": "bool",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "PlantSystem",
"type": "Server.Engines.Plants.PlantSystem",
"usesSaveFlag": true,
"rule": "RawSerializableMigrationRule",
"ruleArguments": [
"DeserializationRequiresParent"
]
}
]
}

View file

@ -0,0 +1,176 @@
{
"version": 3,
"type": "Server.Engines.Plants.PlantSystem",
"properties": [
{
"name": "FertileDirt",
"type": "bool",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "NextGrowth",
"type": "System.DateTime",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "GrowthIndicator",
"type": "Server.Engines.Plants.PlantGrowthIndicator",
"usesSaveFlag": true,
"rule": "EnumMigrationRule"
},
{
"name": "Water",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Hits",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Infestation",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Fungus",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Poison",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Disease",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "PoisonPotion",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "CurePotion",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "HealPotion",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "StrengthPotion",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "Pollinated",
"type": "bool",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "SeedType",
"type": "Server.Engines.Plants.PlantType",
"usesSaveFlag": true,
"rule": "EnumMigrationRule"
},
{
"name": "SeedHue",
"type": "Server.Engines.Plants.PlantHue",
"usesSaveFlag": true,
"rule": "EnumMigrationRule"
},
{
"name": "AvailableSeeds",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "LeftSeeds",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "AvailableResources",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
},
{
"name": "LeftResources",
"type": "int",
"usesSaveFlag": true,
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,24 @@
{
"version": 3,
"type": "Server.Engines.Plants.Seed",
"properties": [
{
"name": "PlantType",
"type": "Server.Engines.Plants.PlantType",
"rule": "EnumMigrationRule"
},
{
"name": "PlantHue",
"type": "Server.Engines.Plants.PlantHue",
"rule": "EnumMigrationRule"
},
{
"name": "ShowType",
"type": "bool",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.FertileDirt"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.GreenThorns"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.GreenThornsSHTeleporter"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.OrangePetals"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Items.RedLeaves"
}

View file

@ -0,0 +1,4 @@
{
"version": 0,
"type": "Server.Mobiles.GiantIceWorm"
}