From 2423950cca0b96b19544070e448bc3eb34073e51 Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 25 Apr 2026 16:46:37 -0700 Subject: [PATCH] perf: Migrate Plant gumps to DynamicGump/StaticGump (#2411) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Second PR in the player-facing legacy gump migration. Converts the four Plants system gumps: - `MainPlantGump`, `ReproductionGump`, `EmptyTheBowlGump` → `DynamicGump`. Layout varies by plant status, growth stage, health, and pollination/resource availability — cannot use cached `StaticGump`. - `SetToDecorativeGump` → `StaticGump`. Pure confirmation dialog with no per-instance variation. All four: - `Singleton => true` (auto-replace previous plant gump on re-open instead of stacking) - Constructor `private`; entry is static `DisplayTo(Mobile, PlantItem)` per the empty-gump rule (CLAUDE.md §13) - `OnResponse` self-refresh paths converted from `from.SendGump(new XGump(_plant))` to `from.SendGump(this)` — saves an allocation on every help/info button click and on every "gather resources/seeds/pollen" action - Helper draw methods take `ref DynamicGumpBuilder builder` instead of mutating instance state - Renamed legacy `m_Plant` to `_plant` per CLAUDE.md §12 Updated external callers to use the new entry points: - `PlantItem.OnDoubleClick` → `MainPlantGump.DisplayTo(from, this)` - `PlantPourTarget.OnTargetFinish` → `MainPlantGump.DisplayTo(from, m_Plant)` (also drops the now-redundant legacy `singleton: true` flag — `Singleton` property handles it) - `PollinateTarget.OnTargetFinish` → `ReproductionGump.DisplayTo(from, m_Plant)` --- .../Engines/Plants/EmptyTheBowlGump.cs | 182 ++-- .../UOContent/Engines/Plants/MainPlantGump.cs | 865 +++++++++--------- .../UOContent/Engines/Plants/PlantItem.cs | 2 +- .../Engines/Plants/PlantPourTarget.cs | 2 +- .../Engines/Plants/PollinateTarget.cs | 2 +- .../Engines/Plants/ReproductionGump.cs | 541 ++++++----- .../Engines/Plants/SetToDecorativeGump.cs | 145 +-- 7 files changed, 867 insertions(+), 872 deletions(-) diff --git a/Projects/UOContent/Engines/Plants/EmptyTheBowlGump.cs b/Projects/UOContent/Engines/Plants/EmptyTheBowlGump.cs index 1447c7070..539cf3036 100644 --- a/Projects/UOContent/Engines/Plants/EmptyTheBowlGump.cs +++ b/Projects/UOContent/Engines/Plants/EmptyTheBowlGump.cs @@ -2,125 +2,125 @@ using Server.Engines.Help; using Server.Gumps; using Server.Network; -namespace Server.Engines.Plants +namespace Server.Engines.Plants; + +public class EmptyTheBowlGump : DynamicGump { - public class EmptyTheBowlGump : Gump + private readonly PlantItem _plant; + + public override bool Singleton => true; + + private EmptyTheBowlGump(PlantItem plant) : base(20, 20) { - private readonly PlantItem m_Plant; + _plant = plant; + } - public EmptyTheBowlGump(PlantItem plant) : base(20, 20) + public static void DisplayTo(Mobile from, PlantItem plant) + { + if (from?.NetState == null || plant == null || plant.Deleted) { - m_Plant = plant; - - DrawBackground(); - - AddLabel(90, 70, 0x44, "Empty the bowl?"); - - DrawPicture(); - - AddButton(98, 150, 0x47E, 0x480, 1); // Cancel - - AddButton(138, 151, 0xD2, 0xD2, 2); // Help - AddLabel(143, 151, 0x835, "?"); - - AddButton(168, 150, 0x481, 0x483, 3); // Ok + return; } - private void DrawBackground() + from.SendGump(new EmptyTheBowlGump(plant)); + } + + protected override void BuildLayout(ref DynamicGumpBuilder builder) + { + builder.AddPage(); + + builder.AddBackground(50, 50, 200, 150, 0xE10); + + builder.AddItem(45, 45, 0xCEF); + builder.AddItem(45, 118, 0xCF0); + + builder.AddItem(211, 45, 0xCEB); + builder.AddItem(211, 118, 0xCEC); + + builder.AddLabel(90, 70, 0x44, "Empty the bowl?"); + + builder.AddItem(90, 100, 0x1602); + builder.AddImage(140, 102, 0x15E1); + builder.AddItem(160, 100, 0x15FD); + + if (_plant.PlantStatus != PlantStatus.BowlOfDirt && _plant.PlantStatus < PlantStatus.Plant) { - AddBackground(50, 50, 200, 150, 0xE10); - - AddItem(45, 45, 0xCEF); - AddItem(45, 118, 0xCF0); - - AddItem(211, 45, 0xCEB); - AddItem(211, 118, 0xCEC); + builder.AddItem(156, 130, 0xDCF); // Seed } - private void DrawPicture() - { - AddItem(90, 100, 0x1602); - AddImage(140, 102, 0x15E1); - AddItem(160, 100, 0x15FD); + builder.AddButton(98, 150, 0x47E, 0x480, 1); // Cancel - if (m_Plant.PlantStatus != PlantStatus.BowlOfDirt && m_Plant.PlantStatus < PlantStatus.Plant) - { - AddItem(156, 130, 0xDCF); // Seed - } + builder.AddButton(138, 151, 0xD2, 0xD2, 2); // Help + builder.AddLabel(143, 151, 0x835, "?"); + + builder.AddButton(168, 150, 0x481, 0x483, 3); // Ok + } + + public override void OnResponse(NetState sender, in RelayInfo info) + { + var from = sender.Mobile; + + if (info.ButtonID == 0 || _plant.Deleted || _plant.PlantStatus >= PlantStatus.DecorativePlant) + { + return; } - public override void OnResponse(NetState sender, in RelayInfo info) + if (info.ButtonID == 3 && !from.InRange(_plant.GetWorldLocation(), 3)) { - var from = sender.Mobile; + from.LocalOverheadMessage(MessageType.Regular, 0x3E9, 500446); // That is too far away. + return; + } - if (info.ButtonID == 0 || m_Plant.Deleted || m_Plant.PlantStatus >= PlantStatus.DecorativePlant) - { - return; - } + if (!_plant.IsUsableBy(from)) + { + _plant.LabelTo(from, 1061856); // You must have the item in your backpack or locked down in order to use it. + return; + } - if (info.ButtonID == 3 && !from.InRange(m_Plant.GetWorldLocation(), 3)) - { - from.LocalOverheadMessage(MessageType.Regular, 0x3E9, 500446); // That is too far away. - return; - } + switch (info.ButtonID) + { + case 1: // Cancel + { + MainPlantGump.DisplayTo(from, _plant); + break; + } + case 2: // Help + { + from.NetState.SendDisplayHelpTopic(HelpTopic.EmptyingBowl); + from.SendGump(this); + break; + } + case 3: // Ok + { + var bowl = new PlantBowl(); - if (!m_Plant.IsUsableBy(from)) - { - m_Plant.LabelTo(from, 1061856); // You must have the item in your backpack or locked down in order to use it. - return; - } - - switch (info.ButtonID) - { - case 1: // Cancel + if (!from.PlaceInBackpack(bowl)) { - from.SendGump(new MainPlantGump(m_Plant)); + bowl.Delete(); + _plant.LabelTo(from, 1053047); // You cannot empty a bowl with a full pack! + MainPlantGump.DisplayTo(from, _plant); break; } - case 2: // Help + + if (_plant.PlantStatus != PlantStatus.BowlOfDirt && _plant.PlantStatus < PlantStatus.Plant) { - from.NetState.SendDisplayHelpTopic(HelpTopic.EmptyingBowl); + var seed = new Seed(_plant.PlantType, _plant.PlantHue, _plant.ShowType); - from.SendGump(new EmptyTheBowlGump(m_Plant)); - - break; - } - case 3: // Ok - { - var bowl = new PlantBowl(); - - if (!from.PlaceInBackpack(bowl)) + if (!from.PlaceInBackpack(seed)) { bowl.Delete(); + seed.Delete(); - m_Plant.LabelTo(from, 1053047); // You cannot empty a bowl with a full pack! - from.SendGump(new MainPlantGump(m_Plant)); - + _plant.LabelTo(from, 1053047); // You cannot empty a bowl with a full pack! + MainPlantGump.DisplayTo(from, _plant); break; } - - if (m_Plant.PlantStatus != PlantStatus.BowlOfDirt && m_Plant.PlantStatus < PlantStatus.Plant) - { - var seed = new Seed(m_Plant.PlantType, m_Plant.PlantHue, m_Plant.ShowType); - - if (!from.PlaceInBackpack(seed)) - { - bowl.Delete(); - seed.Delete(); - - m_Plant.LabelTo(from, 1053047); // You cannot empty a bowl with a full pack! - from.SendGump(new MainPlantGump(m_Plant)); - - break; - } - } - - m_Plant.Delete(); - - break; } - } + + _plant.Delete(); + break; + } } } } diff --git a/Projects/UOContent/Engines/Plants/MainPlantGump.cs b/Projects/UOContent/Engines/Plants/MainPlantGump.cs index 0e831898b..464886ca5 100644 --- a/Projects/UOContent/Engines/Plants/MainPlantGump.cs +++ b/Projects/UOContent/Engines/Plants/MainPlantGump.cs @@ -1,475 +1,468 @@ using System; +using System.Runtime.CompilerServices; using Server.Engines.Help; using Server.Gumps; using Server.Items; using Server.Network; -namespace Server.Engines.Plants +namespace Server.Engines.Plants; + +public class MainPlantGump : DynamicGump { - public class MainPlantGump : Gump + private readonly PlantItem _plant; + + public override bool Singleton => true; + + private MainPlantGump(PlantItem plant) : base(20, 20) { - private readonly PlantItem m_Plant; + _plant = plant; + } - public MainPlantGump(PlantItem plant) : base(20, 20) + public static void DisplayTo(Mobile from, PlantItem plant) + { + if (from?.NetState == null || plant == null || plant.Deleted) { - m_Plant = plant; - - DrawBackground(); - - DrawPlant(); - - AddButton(71, 67, 0xD4, 0xD4, 1); // Reproduction menu - AddItem(59, 68, 0xD08); - - var system = plant.PlantSystem; - - AddButton(71, 91, 0xD4, 0xD4, 2); // Infestation - AddItem(8, 96, 0x372); - AddPlus(95, 92, system.Infestation); - - AddButton(71, 115, 0xD4, 0xD4, 3); // Fungus - AddItem(58, 115, 0xD16); - AddPlus(95, 116, system.Fungus); - - AddButton(71, 139, 0xD4, 0xD4, 4); // Poison - AddItem(59, 143, 0x1AE4); - AddPlus(95, 140, system.Poison); - - AddButton(71, 163, 0xD4, 0xD4, 5); // Disease - AddItem(55, 167, 0x1727); - AddPlus(95, 164, system.Disease); - - AddButton(209, 67, 0xD2, 0xD2, 6); // Water - AddItem(193, 67, 0x1F9D); - AddPlusMinus(196, 67, system.Water); - - AddButton(209, 91, 0xD4, 0xD4, 7); // Poison potion - AddItem(201, 91, 0xF0A); - AddLevel(196, 91, system.PoisonPotion); - - AddButton(209, 115, 0xD4, 0xD4, 8); // Cure potion - AddItem(201, 115, 0xF07); - AddLevel(196, 115, system.CurePotion); - - AddButton(209, 139, 0xD4, 0xD4, 9); // Heal potion - AddItem(201, 139, 0xF0C); - AddLevel(196, 139, system.HealPotion); - - AddButton(209, 163, 0xD4, 0xD4, 10); // Strength potion - AddItem(201, 163, 0xF09); - AddLevel(196, 163, system.StrengthPotion); - - AddImage(48, 47, 0xD2); - AddLevel(54, 47, (int)m_Plant.PlantStatus); - - AddImage(232, 47, 0xD2); - AddGrowthIndicator(239, 47); - - AddButton(48, 183, 0xD2, 0xD2, 11); // Help - AddLabel(54, 183, 0x835, "?"); - - AddButton(232, 183, 0xD4, 0xD4, 12); // Empty the bowl - AddItem(219, 180, 0x15FD); + return; } - private void DrawBackground() + from.SendGump(new MainPlantGump(plant)); + } + + protected override void BuildLayout(ref DynamicGumpBuilder builder) + { + builder.AddPage(); + + DrawBackground(ref builder); + DrawPlant(ref builder); + + builder.AddButton(71, 67, 0xD4, 0xD4, 1); // Reproduction menu + builder.AddItem(59, 68, 0xD08); + + var system = _plant.PlantSystem; + + builder.AddButton(71, 91, 0xD4, 0xD4, 2); // Infestation + builder.AddItem(8, 96, 0x372); + AddPlus(ref builder, 95, 92, system.Infestation); + + builder.AddButton(71, 115, 0xD4, 0xD4, 3); // Fungus + builder.AddItem(58, 115, 0xD16); + AddPlus(ref builder, 95, 116, system.Fungus); + + builder.AddButton(71, 139, 0xD4, 0xD4, 4); // Poison + builder.AddItem(59, 143, 0x1AE4); + AddPlus(ref builder, 95, 140, system.Poison); + + builder.AddButton(71, 163, 0xD4, 0xD4, 5); // Disease + builder.AddItem(55, 167, 0x1727); + AddPlus(ref builder, 95, 164, system.Disease); + + builder.AddButton(209, 67, 0xD2, 0xD2, 6); // Water + builder.AddItem(193, 67, 0x1F9D); + AddPlusMinus(ref builder, 196, 67, system.Water); + + builder.AddButton(209, 91, 0xD4, 0xD4, 7); // Poison potion + builder.AddItem(201, 91, 0xF0A); + AddLevel(ref builder, 196, 91, system.PoisonPotion); + + builder.AddButton(209, 115, 0xD4, 0xD4, 8); // Cure potion + builder.AddItem(201, 115, 0xF07); + AddLevel(ref builder, 196, 115, system.CurePotion); + + builder.AddButton(209, 139, 0xD4, 0xD4, 9); // Heal potion + builder.AddItem(201, 139, 0xF0C); + AddLevel(ref builder, 196, 139, system.HealPotion); + + builder.AddButton(209, 163, 0xD4, 0xD4, 10); // Strength potion + builder.AddItem(201, 163, 0xF09); + AddLevel(ref builder, 196, 163, system.StrengthPotion); + + builder.AddImage(48, 47, 0xD2); + AddLevel(ref builder, 54, 47, (int)_plant.PlantStatus); + + builder.AddImage(232, 47, 0xD2); + AddGrowthIndicator(ref builder, 239, 47); + + builder.AddButton(48, 183, 0xD2, 0xD2, 11); // Help + builder.AddLabel(54, 183, 0x835, "?"); + + builder.AddButton(232, 183, 0xD4, 0xD4, 12); // Empty the bowl + builder.AddItem(219, 180, 0x15FD); + } + + private static void DrawBackground(ref DynamicGumpBuilder builder) + { + builder.AddBackground(50, 50, 200, 150, 0xE10); + + builder.AddItem(45, 45, 0xCEF); + builder.AddItem(45, 118, 0xCF0); + + builder.AddItem(211, 45, 0xCEB); + builder.AddItem(211, 118, 0xCEC); + } + + private void DrawPlant(ref DynamicGumpBuilder builder) + { + var status = _plant.PlantStatus; + + if (status < PlantStatus.FullGrownPlant) { - AddBackground(50, 50, 200, 150, 0xE10); + builder.AddImage(110, 85, 0x589); - AddItem(45, 45, 0xCEF); - AddItem(45, 118, 0xCF0); + builder.AddItem(122, 94, 0x914); + builder.AddItem(135, 94, 0x914); + builder.AddItem(120, 112, 0x914); + builder.AddItem(135, 112, 0x914); - AddItem(211, 45, 0xCEB); - AddItem(211, 118, 0xCEC); - } - - private void DrawPlant() - { - var status = m_Plant.PlantStatus; - - if (status < PlantStatus.FullGrownPlant) + if (status >= PlantStatus.Stage2) { - AddImage(110, 85, 0x589); + builder.AddItem(127, 112, 0xC62); + } - AddItem(122, 94, 0x914); - AddItem(135, 94, 0x914); - AddItem(120, 112, 0x914); - AddItem(135, 112, 0x914); + if (status is PlantStatus.Stage3 or PlantStatus.Stage4) + { + builder.AddItem(129, 85, 0xC7E); + } - if (status >= PlantStatus.Stage2) - { - AddItem(127, 112, 0xC62); - } + if (status >= PlantStatus.Stage4) + { + builder.AddItem(121, 117, 0xC62); + builder.AddItem(133, 117, 0xC62); + } - if (status is PlantStatus.Stage3 or PlantStatus.Stage4) - { - AddItem(129, 85, 0xC7E); - } + if (status >= PlantStatus.Stage5) + { + builder.AddItem(110, 100, 0xC62); + builder.AddItem(140, 100, 0xC62); + builder.AddItem(110, 130, 0xC62); + builder.AddItem(140, 130, 0xC62); + } - if (status >= PlantStatus.Stage4) - { - AddItem(121, 117, 0xC62); - AddItem(133, 117, 0xC62); - } + if (status >= PlantStatus.Stage6) + { + builder.AddItem(105, 115, 0xC62); + builder.AddItem(145, 115, 0xC62); + builder.AddItem(125, 90, 0xC62); + builder.AddItem(125, 135, 0xC62); + } + } + else + { + var typeInfo = PlantTypeInfo.GetInfo(_plant.PlantType); + var hueInfo = PlantHueInfo.GetInfo(_plant.PlantHue); - if (status >= PlantStatus.Stage5) - { - AddItem(110, 100, 0xC62); - AddItem(140, 100, 0xC62); - AddItem(110, 130, 0xC62); - AddItem(140, 130, 0xC62); - } - - if (status >= PlantStatus.Stage6) - { - AddItem(105, 115, 0xC62); - AddItem(145, 115, 0xC62); - AddItem(125, 90, 0xC62); - AddItem(125, 135, 0xC62); - } + // The large images for these trees trigger a client crash, so use a smaller, generic tree. + if (_plant.PlantType is PlantType.CypressTwisted or PlantType.CypressStraight) + { + builder.AddItem(130 + typeInfo.OffsetX, 96 + typeInfo.OffsetY, 0x0CCA, hueInfo.Hue); } else { - var typeInfo = PlantTypeInfo.GetInfo(m_Plant.PlantType); - var hueInfo = PlantHueInfo.GetInfo(m_Plant.PlantHue); - - // The large images for these trees trigger a client crash, so use a smaller, generic tree. - if (m_Plant.PlantType is PlantType.CypressTwisted or PlantType.CypressStraight) - { - AddItem(130 + typeInfo.OffsetX, 96 + typeInfo.OffsetY, 0x0CCA, hueInfo.Hue); - } - else - { - AddItem(130 + typeInfo.OffsetX, 96 + typeInfo.OffsetY, typeInfo.ItemID, hueInfo.Hue); - } - } - - if (status != PlantStatus.BowlOfDirt) - { - var message = m_Plant.PlantSystem.GetLocalizedHealth(); - - switch (m_Plant.PlantSystem.Health) - { - case PlantHealth.Dying: - { - AddItem(92, 167, 0x1B9D); - AddItem(161, 167, 0x1B9D); - - AddHtmlLocalized(136, 167, 42, 20, message, 0xFC00); - - break; - } - case PlantHealth.Wilted: - { - AddItem(91, 164, 0x18E6); - AddItem(161, 164, 0x18E6); - - AddHtmlLocalized(132, 167, 42, 20, message, 0xC207); - - break; - } - case PlantHealth.Healthy: - { - AddItem(96, 168, 0xC61); - AddItem(162, 168, 0xC61); - - AddHtmlLocalized(129, 167, 42, 20, message, 0x8200); - - break; - } - case PlantHealth.Vibrant: - { - AddItem(93, 162, 0x1A99); - AddItem(162, 162, 0x1A99); - - AddHtmlLocalized(129, 167, 42, 20, message, 0x83E0); - - break; - } - } + builder.AddItem(130 + typeInfo.OffsetX, 96 + typeInfo.OffsetY, typeInfo.ItemID, hueInfo.Hue); } } - private void AddPlus(int x, int y, int value) + if (status != PlantStatus.BowlOfDirt) { - switch (value) + var message = _plant.PlantSystem.GetLocalizedHealth(); + + switch (_plant.PlantSystem.Health) { - case 1: + case PlantHealth.Dying: { - AddLabel(x, y, 0x35, "+"); + builder.AddItem(92, 167, 0x1B9D); + builder.AddItem(161, 167, 0x1B9D); + + builder.AddHtmlLocalized(136, 167, 42, 20, message, 0xFC00); break; } - case 2: + case PlantHealth.Wilted: { - AddLabel(x, y, 0x21, "+"); + builder.AddItem(91, 164, 0x18E6); + builder.AddItem(161, 164, 0x18E6); + + builder.AddHtmlLocalized(132, 167, 42, 20, message, 0xC207); + break; + } + case PlantHealth.Healthy: + { + builder.AddItem(96, 168, 0xC61); + builder.AddItem(162, 168, 0xC61); + + builder.AddHtmlLocalized(129, 167, 42, 20, message, 0x8200); + break; + } + case PlantHealth.Vibrant: + { + builder.AddItem(93, 162, 0x1A99); + builder.AddItem(162, 162, 0x1A99); + + builder.AddHtmlLocalized(129, 167, 42, 20, message, 0x83E0); break; } } } - - private void AddPlusMinus(int x, int y, int value) - { - switch (value) - { - case 0: - { - AddLabel(x, y, 0x21, "-"); - break; - } - case 1: - { - AddLabel(x, y, 0x35, "-"); - break; - } - case 3: - { - AddLabel(x, y, 0x35, "+"); - break; - } - case 4: - { - AddLabel(x, y, 0x21, "+"); - break; - } - } - } - - private void AddLevel(int x, int y, int value) - { - AddLabel(x, y, 0x835, value.ToString()); - } - - private void AddGrowthIndicator(int x, int y) - { - if (!m_Plant.IsGrowable) - { - return; - } - - switch (m_Plant.PlantSystem.GrowthIndicator) - { - default: - case PlantGrowthIndicator.None: - case PlantGrowthIndicator.InvalidLocation: - { - AddLabel(x, y, 0x21, "!"); - break; - } - case PlantGrowthIndicator.NotHealthy: - { - AddLabel(x, y, 0x21, "-"); - break; - } - case PlantGrowthIndicator.Delay: - { - AddLabel(x, y, 0x35, "-"); - break; - } - case PlantGrowthIndicator.Grown: - { - AddLabel(x, y, 0x3, "+"); - break; - } - case PlantGrowthIndicator.DoubleGrown: - { - AddLabel(x, y, 0x3F, "+"); - break; - } - } - } - - public override void OnResponse(NetState sender, in RelayInfo info) - { - var from = sender.Mobile; - - if (info.ButtonID == 0 || m_Plant.Deleted || m_Plant.PlantStatus >= PlantStatus.DecorativePlant) - { - return; - } - - if ((info.ButtonID >= 6 && info.ButtonID <= 10 || info.ButtonID == 12) && - !from.InRange(m_Plant.GetWorldLocation(), 3)) - { - from.LocalOverheadMessage(MessageType.Regular, 0x3E9, 500446); // That is too far away. - return; - } - - if (!m_Plant.IsUsableBy(from)) - { - m_Plant.LabelTo(from, 1061856); // You must have the item in your backpack or locked down in order to use it. - return; - } - - switch (info.ButtonID) - { - case 1: // Reproduction menu - { - if (m_Plant.PlantStatus > PlantStatus.BowlOfDirt) - { - from.SendGump(new ReproductionGump(m_Plant)); - } - else - { - from.SendLocalizedMessage(1061885); // You need to plant a seed in the bowl first. - - from.SendGump(new MainPlantGump(m_Plant)); - } - - break; - } - case 2: // Infestation - { - from.NetState.SendDisplayHelpTopic(HelpTopic.InfestationLevel); - - from.SendGump(new MainPlantGump(m_Plant)); - - break; - } - case 3: // Fungus - { - from.NetState.SendDisplayHelpTopic(HelpTopic.FungusLevel); - - from.SendGump(new MainPlantGump(m_Plant)); - - break; - } - case 4: // Poison - { - from.NetState.SendDisplayHelpTopic(HelpTopic.PoisonLevel); - - from.SendGump(new MainPlantGump(m_Plant)); - - break; - } - case 5: // Disease - { - from.NetState.SendDisplayHelpTopic(HelpTopic.DiseaseLevel); - - from.SendGump(new MainPlantGump(m_Plant)); - - break; - } - case 6: // Water - { - BaseBeverage bev = null; - - foreach (var beverage in from.Backpack.FindItemsByType()) - { - if (beverage.IsEmpty && beverage.Pourable && beverage.Content == BeverageType.Water) - { - bev = beverage; - break; - } - } - - if (bev == null) - { - from.Target = new PlantPourTarget(m_Plant); - - // Target the container you wish to use to water the ~1_val~. - from.SendLocalizedMessage(1060808, $"#{m_Plant.GetLocalizedPlantStatus()}"); - } - else - { - m_Plant.Pour(from, bev); - } - - from.SendGump(new MainPlantGump(m_Plant)); - - break; - } - case 7: // Poison potion - { - AddPotion(from, PotionEffect.PoisonGreater, PotionEffect.PoisonDeadly); - - break; - } - case 8: // Cure potion - { - AddPotion(from, PotionEffect.CureGreater); - - break; - } - case 9: // Heal potion - { - AddPotion(from, PotionEffect.HealGreater); - - break; - } - case 10: // Strength potion - { - AddPotion(from, PotionEffect.StrengthGreater); - - break; - } - case 11: // Help - { - from.NetState.SendDisplayHelpTopic(HelpTopic.PlantGrowing); - - from.SendGump(new MainPlantGump(m_Plant)); - - break; - } - case 12: // Empty the bowl - { - from.SendGump(new EmptyTheBowlGump(m_Plant)); - - break; - } - } - } - - private void AddPotion(Mobile from, params PotionEffect[] effects) - { - var item = GetPotion(from, effects); - - if (item != null) - { - m_Plant.Pour(from, item); - } - else - { - if (m_Plant.ApplyPotion(effects[0], true, out var message)) - { - from.SendLocalizedMessage(1061884); // You don't have any strong potions of that type in your pack. - - from.Target = new PlantPourTarget(m_Plant); - - // Target the container you wish to use to water the ~1_val~. - from.SendLocalizedMessage(1060808, $"#{m_Plant.GetLocalizedPlantStatus()}"); - - return; - } - - m_Plant.LabelTo(from, message); - } - - from.SendGump(new MainPlantGump(m_Plant)); - } - - public static Item GetPotion(Mobile from, PotionEffect[] effects) - { - if (from.Backpack == null) - { - return null; - } - - foreach (var item in from.Backpack.FindItems()) - { - if (item is BasePotion potion) - { - if (Array.IndexOf(effects, potion.PotionEffect) >= 0) - { - return potion; - } - } - else if (item is PotionKeg keg && keg.Held > 0 && Array.IndexOf(effects, keg.Type) >= 0) - { - return keg; - } - } - - return null; - } + } + + private static void AddPlus(ref DynamicGumpBuilder builder, int x, int y, int value) + { + switch (value) + { + case 1: + { + builder.AddLabel(x, y, 0x35, "+"); + break; + } + case 2: + { + builder.AddLabel(x, y, 0x21, "+"); + break; + } + } + } + + private static void AddPlusMinus(ref DynamicGumpBuilder builder, int x, int y, int value) + { + switch (value) + { + case 0: + { + builder.AddLabel(x, y, 0x21, "-"); + break; + } + case 1: + { + builder.AddLabel(x, y, 0x35, "-"); + break; + } + case 3: + { + builder.AddLabel(x, y, 0x35, "+"); + break; + } + case 4: + { + builder.AddLabel(x, y, 0x21, "+"); + break; + } + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + private static void AddLevel(ref DynamicGumpBuilder builder, int x, int y, int value) => + builder.AddLabel(x, y, 0x835, $"{value}"); + + private void AddGrowthIndicator(ref DynamicGumpBuilder builder, int x, int y) + { + if (!_plant.IsGrowable) + { + return; + } + + switch (_plant.PlantSystem.GrowthIndicator) + { + default: + case PlantGrowthIndicator.None: + case PlantGrowthIndicator.InvalidLocation: + { + builder.AddLabel(x, y, 0x21, "!"); + break; + } + case PlantGrowthIndicator.NotHealthy: + { + builder.AddLabel(x, y, 0x21, "-"); + break; + } + case PlantGrowthIndicator.Delay: + { + builder.AddLabel(x, y, 0x35, "-"); + break; + } + case PlantGrowthIndicator.Grown: + { + builder.AddLabel(x, y, 0x3, "+"); + break; + } + case PlantGrowthIndicator.DoubleGrown: + { + builder.AddLabel(x, y, 0x3F, "+"); + break; + } + } + } + + public override void OnResponse(NetState sender, in RelayInfo info) + { + var from = sender.Mobile; + + if (info.ButtonID == 0 || _plant.Deleted || _plant.PlantStatus >= PlantStatus.DecorativePlant) + { + return; + } + + if ((info.ButtonID >= 6 && info.ButtonID <= 10 || info.ButtonID == 12) && + !from.InRange(_plant.GetWorldLocation(), 3)) + { + from.LocalOverheadMessage(MessageType.Regular, 0x3E9, 500446); // That is too far away. + return; + } + + if (!_plant.IsUsableBy(from)) + { + _plant.LabelTo(from, 1061856); // You must have the item in your backpack or locked down in order to use it. + return; + } + + switch (info.ButtonID) + { + case 1: // Reproduction menu + { + if (_plant.PlantStatus > PlantStatus.BowlOfDirt) + { + ReproductionGump.DisplayTo(from, _plant); + } + else + { + from.SendLocalizedMessage(1061885); // You need to plant a seed in the bowl first. + from.SendGump(this); + } + break; + } + case 2: // Infestation + { + from.NetState.SendDisplayHelpTopic(HelpTopic.InfestationLevel); + from.SendGump(this); + break; + } + case 3: // Fungus + { + from.NetState.SendDisplayHelpTopic(HelpTopic.FungusLevel); + from.SendGump(this); + break; + } + case 4: // Poison + { + from.NetState.SendDisplayHelpTopic(HelpTopic.PoisonLevel); + from.SendGump(this); + break; + } + case 5: // Disease + { + from.NetState.SendDisplayHelpTopic(HelpTopic.DiseaseLevel); + from.SendGump(this); + break; + } + case 6: // Water + { + BaseBeverage bev = null; + + foreach (var beverage in from.Backpack.FindItemsByType()) + { + if (beverage.IsEmpty && beverage.Pourable && beverage.Content == BeverageType.Water) + { + bev = beverage; + break; + } + } + + if (bev == null) + { + from.Target = new PlantPourTarget(_plant); + + // Target the container you wish to use to water the ~1_val~. + from.SendLocalizedMessage(1060808, $"#{_plant.GetLocalizedPlantStatus()}"); + } + else + { + _plant.Pour(from, bev); + } + + from.SendGump(this); + break; + } + case 7: // Poison potion + { + AddPotion(from, PotionEffect.PoisonGreater, PotionEffect.PoisonDeadly); + break; + } + case 8: // Cure potion + { + AddPotion(from, PotionEffect.CureGreater); + break; + } + case 9: // Heal potion + { + AddPotion(from, PotionEffect.HealGreater); + break; + } + case 10: // Strength potion + { + AddPotion(from, PotionEffect.StrengthGreater); + break; + } + case 11: // Help + { + from.NetState.SendDisplayHelpTopic(HelpTopic.PlantGrowing); + from.SendGump(this); + break; + } + case 12: // Empty the bowl + { + EmptyTheBowlGump.DisplayTo(from, _plant); + break; + } + } + } + + private void AddPotion(Mobile from, params PotionEffect[] effects) + { + var item = GetPotion(from, effects); + + if (item != null) + { + _plant.Pour(from, item); + } + else + { + if (_plant.ApplyPotion(effects[0], true, out var message)) + { + from.SendLocalizedMessage(1061884); // You don't have any strong potions of that type in your pack. + + from.Target = new PlantPourTarget(_plant); + + // Target the container you wish to use to water the ~1_val~. + from.SendLocalizedMessage(1060808, $"#{_plant.GetLocalizedPlantStatus()}"); + + return; + } + + _plant.LabelTo(from, message); + } + + from.SendGump(this); + } + + public static Item GetPotion(Mobile from, PotionEffect[] effects) + { + if (from.Backpack == null) + { + return null; + } + + foreach (var item in from.Backpack.FindItems()) + { + if (item is BasePotion potion) + { + if (Array.IndexOf(effects, potion.PotionEffect) >= 0) + { + return potion; + } + } + else if (item is PotionKeg keg && keg.Held > 0 && Array.IndexOf(effects, keg.Type) >= 0) + { + return keg; + } + } + + return null; } } diff --git a/Projects/UOContent/Engines/Plants/PlantItem.cs b/Projects/UOContent/Engines/Plants/PlantItem.cs index 959bb031b..60451f53b 100644 --- a/Projects/UOContent/Engines/Plants/PlantItem.cs +++ b/Projects/UOContent/Engines/Plants/PlantItem.cs @@ -484,7 +484,7 @@ public partial class PlantItem : Item, ISecurable return; } - from.SendGump(new MainPlantGump(this)); + MainPlantGump.DisplayTo(from, this); } public void PlantSeed(Mobile from, Seed seed) diff --git a/Projects/UOContent/Engines/Plants/PlantPourTarget.cs b/Projects/UOContent/Engines/Plants/PlantPourTarget.cs index 6be83a241..454f4cfcc 100644 --- a/Projects/UOContent/Engines/Plants/PlantPourTarget.cs +++ b/Projects/UOContent/Engines/Plants/PlantPourTarget.cs @@ -22,7 +22,7 @@ namespace Server.Engines.Plants if (!m_Plant.Deleted && m_Plant.PlantStatus < PlantStatus.DecorativePlant && from.InRange(m_Plant.GetWorldLocation(), 3) && m_Plant.IsUsableBy(from)) { - from.SendGump(new MainPlantGump(m_Plant), true); + MainPlantGump.DisplayTo(from, m_Plant); } } } diff --git a/Projects/UOContent/Engines/Plants/PollinateTarget.cs b/Projects/UOContent/Engines/Plants/PollinateTarget.cs index 720060afc..b202c79a2 100644 --- a/Projects/UOContent/Engines/Plants/PollinateTarget.cs +++ b/Projects/UOContent/Engines/Plants/PollinateTarget.cs @@ -84,7 +84,7 @@ namespace Server.Engines.Plants m_Plant.PlantStatus != PlantStatus.BowlOfDirt && from.InRange(m_Plant.GetWorldLocation(), 3) && m_Plant.IsUsableBy(from)) { - from.SendGump(new ReproductionGump(m_Plant)); + ReproductionGump.DisplayTo(from, m_Plant); } } } diff --git a/Projects/UOContent/Engines/Plants/ReproductionGump.cs b/Projects/UOContent/Engines/Plants/ReproductionGump.cs index 4feba68ac..0c31d74a0 100644 --- a/Projects/UOContent/Engines/Plants/ReproductionGump.cs +++ b/Projects/UOContent/Engines/Plants/ReproductionGump.cs @@ -2,293 +2,288 @@ using Server.Engines.Help; using Server.Gumps; using Server.Network; -namespace Server.Engines.Plants +namespace Server.Engines.Plants; + +public class ReproductionGump : DynamicGump { - public class ReproductionGump : Gump + private readonly PlantItem _plant; + + public override bool Singleton => true; + + private ReproductionGump(PlantItem plant) : base(20, 20) { - private readonly PlantItem m_Plant; + _plant = plant; + } - public ReproductionGump(PlantItem plant) : base(20, 20) + public static void DisplayTo(Mobile from, PlantItem plant) + { + if (from?.NetState == null || plant == null || plant.Deleted) { - m_Plant = plant; - - DrawBackground(); - - AddButton(70, 67, 0xD4, 0xD4, 1); // Main menu - AddItem(57, 65, 0x1600); - - AddLabel(108, 67, 0x835, "Reproduction"); - - if (m_Plant.PlantStatus == PlantStatus.Stage9) - { - AddButton(212, 67, 0xD4, 0xD4, 2); // Set to decorative - AddItem(202, 68, 0xC61); - AddLabel(216, 66, 0x21, "/"); - } - - AddButton(80, 116, 0xD4, 0xD4, 3); // Pollination - AddItem(66, 117, 0x1AA2); - AddPollinationState(106, 116); - - AddButton(128, 116, 0xD4, 0xD4, 4); // Resources - AddItem(113, 120, 0x1021); - AddResourcesState(149, 116); - - AddButton(177, 116, 0xD4, 0xD4, 5); // Seeds - AddItem(160, 121, 0xDCF); - AddSeedsState(199, 116); - - AddButton(70, 163, 0xD2, 0xD2, 6); // Gather pollen - AddItem(56, 164, 0x1AA2); - - AddButton(138, 163, 0xD2, 0xD2, 7); // Gather resources - AddItem(123, 167, 0x1021); - - AddButton(212, 163, 0xD2, 0xD2, 8); // Gather seeds - AddItem(195, 168, 0xDCF); + return; } - private void DrawBackground() + from.SendGump(new ReproductionGump(plant)); + } + + protected override void BuildLayout(ref DynamicGumpBuilder builder) + { + builder.AddPage(); + + builder.AddBackground(50, 50, 200, 150, 0xE10); + + builder.AddImage(60, 90, 0xE17); + builder.AddImage(120, 90, 0xE17); + + builder.AddImage(60, 145, 0xE17); + builder.AddImage(120, 145, 0xE17); + + builder.AddItem(45, 45, 0xCEF); + builder.AddItem(45, 118, 0xCF0); + + builder.AddItem(211, 45, 0xCEB); + builder.AddItem(211, 118, 0xCEC); + + builder.AddButton(70, 67, 0xD4, 0xD4, 1); // Main menu + builder.AddItem(57, 65, 0x1600); + + builder.AddLabel(108, 67, 0x835, "Reproduction"); + + if (_plant.PlantStatus == PlantStatus.Stage9) { - AddBackground(50, 50, 200, 150, 0xE10); - - AddImage(60, 90, 0xE17); - AddImage(120, 90, 0xE17); - - AddImage(60, 145, 0xE17); - AddImage(120, 145, 0xE17); - - AddItem(45, 45, 0xCEF); - AddItem(45, 118, 0xCF0); - - AddItem(211, 45, 0xCEB); - AddItem(211, 118, 0xCEC); + builder.AddButton(212, 67, 0xD4, 0xD4, 2); // Set to decorative + builder.AddItem(202, 68, 0xC61); + builder.AddLabel(216, 66, 0x21, "/"); } - private void AddPollinationState(int x, int y) - { - var system = m_Plant.PlantSystem; + builder.AddButton(80, 116, 0xD4, 0xD4, 3); // Pollination + builder.AddItem(66, 117, 0x1AA2); + AddPollinationState(ref builder, 106, 116); - if (!system.PollenProducing) - { - AddLabel(x, y, 0x35, "-"); - } - else if (!system.Pollinated) - { - AddLabel(x, y, 0x21, "!"); - } - else - { - AddLabel(x, y, 0x3F, "+"); - } + builder.AddButton(128, 116, 0xD4, 0xD4, 4); // Resources + builder.AddItem(113, 120, 0x1021); + AddResourcesState(ref builder, 149, 116); + + builder.AddButton(177, 116, 0xD4, 0xD4, 5); // Seeds + builder.AddItem(160, 121, 0xDCF); + AddSeedsState(ref builder, 199, 116); + + builder.AddButton(70, 163, 0xD2, 0xD2, 6); // Gather pollen + builder.AddItem(56, 164, 0x1AA2); + + builder.AddButton(138, 163, 0xD2, 0xD2, 7); // Gather resources + builder.AddItem(123, 167, 0x1021); + + builder.AddButton(212, 163, 0xD2, 0xD2, 8); // Gather seeds + builder.AddItem(195, 168, 0xDCF); + } + + private void AddPollinationState(ref DynamicGumpBuilder builder, int x, int y) + { + var system = _plant.PlantSystem; + + if (!system.PollenProducing) + { + builder.AddLabel(x, y, 0x35, "-"); } - - private void AddResourcesState(int x, int y) + else if (!system.Pollinated) { - var resInfo = PlantResourceInfo.GetInfo(m_Plant.PlantType, m_Plant.PlantHue); - - var system = m_Plant.PlantSystem; - var totalResources = system.AvailableResources + system.LeftResources; - - if (resInfo == null || totalResources == 0) - { - AddLabel(x + 5, y, 0x21, "X"); - } - else - { - AddLabel( - x, - y, - PlantHueInfo.GetInfo(m_Plant.PlantHue).GumpHue, - $"{system.AvailableResources}/{totalResources}" - ); - } + builder.AddLabel(x, y, 0x21, "!"); } - - private void AddSeedsState(int x, int y) + else { - var system = m_Plant.PlantSystem; - var totalSeeds = system.AvailableSeeds + system.LeftSeeds; - - if (!m_Plant.Reproduces || totalSeeds == 0) - { - AddLabel(x + 5, y, 0x21, "X"); - } - else - { - AddLabel( - x, - y, - PlantHueInfo.GetInfo(system.SeedHue).GumpHue, - $"{system.AvailableSeeds}/{totalSeeds}" - ); - } - } - - public override void OnResponse(NetState sender, in RelayInfo info) - { - var from = sender.Mobile; - - if (info.ButtonID == 0 || m_Plant.Deleted || m_Plant.PlantStatus is >= PlantStatus.DecorativePlant or PlantStatus.BowlOfDirt) - { - return; - } - - if (info.ButtonID >= 6 && info.ButtonID <= 8 && !from.InRange(m_Plant.GetWorldLocation(), 3)) - { - from.LocalOverheadMessage(MessageType.Regular, 0x3E9, 500446); // That is too far away. - return; - } - - if (!m_Plant.IsUsableBy(from)) - { - m_Plant.LabelTo(from, 1061856); // You must have the item in your backpack or locked down in order to use it. - return; - } - - switch (info.ButtonID) - { - case 1: // Main menu - { - from.SendGump(new MainPlantGump(m_Plant)); - - break; - } - case 2: // Set to decorative - { - if (m_Plant.PlantStatus == PlantStatus.Stage9) - { - from.SendGump(new SetToDecorativeGump(m_Plant)); - } - - break; - } - case 3: // Pollination - { - from.NetState.SendDisplayHelpTopic(HelpTopic.PollinationState); - - from.SendGump(new ReproductionGump(m_Plant)); - - break; - } - case 4: // Resources - { - from.NetState.SendDisplayHelpTopic(HelpTopic.ResourceProduction); - - from.SendGump(new ReproductionGump(m_Plant)); - - break; - } - case 5: // Seeds - { - from.NetState.SendDisplayHelpTopic(HelpTopic.SeedProduction); - - from.SendGump(new ReproductionGump(m_Plant)); - - break; - } - case 6: // Gather pollen - { - if (!m_Plant.IsCrossable) - { - m_Plant.LabelTo(from, 1053050); // You cannot gather pollen from a mutated plant! - } - else if (!m_Plant.PlantSystem.PollenProducing) - { - // You cannot gather pollen from a plant in this stage of development! - m_Plant.LabelTo(from, 1053051); - } - else if (m_Plant.PlantSystem.Health < PlantHealth.Healthy) - { - m_Plant.LabelTo(from, 1053052); // You cannot gather pollen from an unhealthy plant! - } - else - { - from.Target = new PollinateTarget(m_Plant); - from.SendLocalizedMessage(1053054); // Target the plant you wish to cross-pollinate to. - - break; - } - - from.SendGump(new ReproductionGump(m_Plant)); - - break; - } - case 7: // Gather resources - { - var resInfo = PlantResourceInfo.GetInfo(m_Plant.PlantType, m_Plant.PlantHue); - var system = m_Plant.PlantSystem; - - if (resInfo == null) - { - if (m_Plant.IsCrossable) - { - m_Plant.LabelTo(from, 1053056); // This plant has no resources to gather! - } - else - { - m_Plant.LabelTo(from, 1053055); // Mutated plants do not produce resources! - } - } - else if (system.AvailableResources == 0) - { - m_Plant.LabelTo(from, 1053056); // This plant has no resources to gather! - } - else - { - var resource = resInfo.CreateResource(); - - if (from.PlaceInBackpack(resource)) - { - system.AvailableResources--; - m_Plant.LabelTo(from, 1053059); // You gather resources from the plant. - } - else - { - resource.Delete(); - // You attempt to gather as many resources as you can hold, but your backpack is full. - m_Plant.LabelTo(from, 1053058); - } - } - - from.SendGump(new ReproductionGump(m_Plant)); - - break; - } - case 8: // Gather seeds - { - var system = m_Plant.PlantSystem; - - if (!m_Plant.Reproduces) - { - m_Plant.LabelTo(from, 1053060); // Mutated plants do not produce seeds! - } - else if (system.AvailableSeeds == 0) - { - m_Plant.LabelTo(from, 1053061); // This plant has no seeds to gather! - } - else - { - var seed = new Seed(system.SeedType, system.SeedHue, true); - - if (from.PlaceInBackpack(seed)) - { - system.AvailableSeeds--; - m_Plant.LabelTo(from, 1053063); // You gather seeds from the plant. - } - else - { - seed.Delete(); - // You attempt to gather as many seeds as you can hold, but your backpack is full. - m_Plant.LabelTo(from, 1053062); - } - } - - from.SendGump(new ReproductionGump(m_Plant)); - - break; - } - } + builder.AddLabel(x, y, 0x3F, "+"); } } + + private void AddResourcesState(ref DynamicGumpBuilder builder, int x, int y) + { + var resInfo = PlantResourceInfo.GetInfo(_plant.PlantType, _plant.PlantHue); + + var system = _plant.PlantSystem; + var totalResources = system.AvailableResources + system.LeftResources; + + if (resInfo == null || totalResources == 0) + { + builder.AddLabel(x + 5, y, 0x21, "X"); + } + else + { + builder.AddLabel( + x, + y, + PlantHueInfo.GetInfo(_plant.PlantHue).GumpHue, + $"{system.AvailableResources}/{totalResources}" + ); + } + } + + private void AddSeedsState(ref DynamicGumpBuilder builder, int x, int y) + { + var system = _plant.PlantSystem; + var totalSeeds = system.AvailableSeeds + system.LeftSeeds; + + if (!_plant.Reproduces || totalSeeds == 0) + { + builder.AddLabel(x + 5, y, 0x21, "X"); + } + else + { + builder.AddLabel( + x, + y, + PlantHueInfo.GetInfo(system.SeedHue).GumpHue, + $"{system.AvailableSeeds}/{totalSeeds}" + ); + } + } + + public override void OnResponse(NetState sender, in RelayInfo info) + { + var from = sender.Mobile; + + if (info.ButtonID == 0 || _plant.Deleted || _plant.PlantStatus is >= PlantStatus.DecorativePlant or PlantStatus.BowlOfDirt) + { + return; + } + + if (info.ButtonID >= 6 && info.ButtonID <= 8 && !from.InRange(_plant.GetWorldLocation(), 3)) + { + from.LocalOverheadMessage(MessageType.Regular, 0x3E9, 500446); // That is too far away. + return; + } + + if (!_plant.IsUsableBy(from)) + { + _plant.LabelTo(from, 1061856); // You must have the item in your backpack or locked down in order to use it. + return; + } + + switch (info.ButtonID) + { + case 1: // Main menu + { + MainPlantGump.DisplayTo(from, _plant); + return; + } + case 2: // Set to decorative + { + if (_plant.PlantStatus == PlantStatus.Stage9) + { + SetToDecorativeGump.DisplayTo(from, _plant); + } + return; + } + case 3: // Pollination + { + from.NetState.SendDisplayHelpTopic(HelpTopic.PollinationState); + break; + } + case 4: // Resources + { + from.NetState.SendDisplayHelpTopic(HelpTopic.ResourceProduction); + break; + } + case 5: // Seeds + { + from.NetState.SendDisplayHelpTopic(HelpTopic.SeedProduction); + break; + } + case 6: // Gather pollen + { + if (!_plant.IsCrossable) + { + _plant.LabelTo(from, 1053050); // You cannot gather pollen from a mutated plant! + } + else if (!_plant.PlantSystem.PollenProducing) + { + // You cannot gather pollen from a plant in this stage of development! + _plant.LabelTo(from, 1053051); + } + else if (_plant.PlantSystem.Health < PlantHealth.Healthy) + { + _plant.LabelTo(from, 1053052); // You cannot gather pollen from an unhealthy plant! + } + else + { + from.Target = new PollinateTarget(_plant); + from.SendLocalizedMessage(1053054); // Target the plant you wish to cross-pollinate to. + return; + } + + break; + } + case 7: // Gather resources + { + var resInfo = PlantResourceInfo.GetInfo(_plant.PlantType, _plant.PlantHue); + var system = _plant.PlantSystem; + + if (resInfo == null) + { + if (_plant.IsCrossable) + { + _plant.LabelTo(from, 1053056); // This plant has no resources to gather! + } + else + { + _plant.LabelTo(from, 1053055); // Mutated plants do not produce resources! + } + } + else if (system.AvailableResources == 0) + { + _plant.LabelTo(from, 1053056); // This plant has no resources to gather! + } + else + { + var resource = resInfo.CreateResource(); + + if (from.PlaceInBackpack(resource)) + { + system.AvailableResources--; + _plant.LabelTo(from, 1053059); // You gather resources from the plant. + } + else + { + resource.Delete(); + // You attempt to gather as many resources as you can hold, but your backpack is full. + _plant.LabelTo(from, 1053058); + } + } + + break; + } + case 8: // Gather seeds + { + var system = _plant.PlantSystem; + + if (!_plant.Reproduces) + { + _plant.LabelTo(from, 1053060); // Mutated plants do not produce seeds! + } + else if (system.AvailableSeeds == 0) + { + _plant.LabelTo(from, 1053061); // This plant has no seeds to gather! + } + else + { + var seed = new Seed(system.SeedType, system.SeedHue, true); + + if (from.PlaceInBackpack(seed)) + { + system.AvailableSeeds--; + _plant.LabelTo(from, 1053063); // You gather seeds from the plant. + } + else + { + seed.Delete(); + // You attempt to gather as many seeds as you can hold, but your backpack is full. + _plant.LabelTo(from, 1053062); + } + } + + break; + } + } + + from.SendGump(this); + } } diff --git a/Projects/UOContent/Engines/Plants/SetToDecorativeGump.cs b/Projects/UOContent/Engines/Plants/SetToDecorativeGump.cs index f0bde3c0e..7f49d4665 100644 --- a/Projects/UOContent/Engines/Plants/SetToDecorativeGump.cs +++ b/Projects/UOContent/Engines/Plants/SetToDecorativeGump.cs @@ -2,87 +2,94 @@ using Server.Engines.Help; using Server.Gumps; using Server.Network; -namespace Server.Engines.Plants +namespace Server.Engines.Plants; + +public class SetToDecorativeGump : StaticGump { - public class SetToDecorativeGump : Gump + private readonly PlantItem _plant; + + public override bool Singleton => true; + + private SetToDecorativeGump(PlantItem plant) : base(20, 20) { - private readonly PlantItem m_Plant; + _plant = plant; + } - public SetToDecorativeGump(PlantItem plant) : base(20, 20) + public static void DisplayTo(Mobile from, PlantItem plant) + { + if (from?.NetState == null || plant == null || plant.Deleted) { - m_Plant = plant; - - DrawBackground(); - - AddLabel(115, 85, 0x44, "Set plant"); - AddLabel(82, 105, 0x44, "to decorative mode?"); - - AddButton(98, 140, 0x47E, 0x480, 1); // Cancel - - AddButton(138, 141, 0xD2, 0xD2, 2); // Help - AddLabel(143, 141, 0x835, "?"); - - AddButton(168, 140, 0x481, 0x483, 3); // Ok + return; } - private void DrawBackground() + from.SendGump(new SetToDecorativeGump(plant)); + } + + protected override void BuildLayout(ref StaticGumpBuilder builder) + { + builder.AddPage(); + + builder.AddBackground(50, 50, 200, 150, 0xE10); + + builder.AddItem(25, 45, 0xCEB); + builder.AddItem(25, 118, 0xCEC); + + builder.AddItem(227, 45, 0xCEF); + builder.AddItem(227, 118, 0xCF0); + + builder.AddLabel(115, 85, 0x44, "Set plant"); + builder.AddLabel(82, 105, 0x44, "to decorative mode?"); + + builder.AddButton(98, 140, 0x47E, 0x480, 1); // Cancel + + builder.AddButton(138, 141, 0xD2, 0xD2, 2); // Help + builder.AddLabel(143, 141, 0x835, "?"); + + builder.AddButton(168, 140, 0x481, 0x483, 3); // Ok + } + + public override void OnResponse(NetState sender, in RelayInfo info) + { + var from = sender.Mobile; + + if (info.ButtonID == 0 || _plant.Deleted || _plant.PlantStatus != PlantStatus.Stage9) { - AddBackground(50, 50, 200, 150, 0xE10); - - AddItem(25, 45, 0xCEB); - AddItem(25, 118, 0xCEC); - - AddItem(227, 45, 0xCEF); - AddItem(227, 118, 0xCF0); + return; } - public override void OnResponse(NetState sender, in RelayInfo info) + if (info.ButtonID == 3 && !from.InRange(_plant.GetWorldLocation(), 3)) { - var from = sender.Mobile; + from.LocalOverheadMessage(MessageType.Regular, 0x3E9, 500446); // That is too far away. + return; + } - if (info.ButtonID == 0 || m_Plant.Deleted || m_Plant.PlantStatus != PlantStatus.Stage9) - { - return; - } + if (!_plant.IsUsableBy(from)) + { + _plant.LabelTo(from, 1061856); // You must have the item in your backpack or locked down in order to use it. + return; + } - if (info.ButtonID == 3 && !from.InRange(m_Plant.GetWorldLocation(), 3)) - { - from.LocalOverheadMessage(MessageType.Regular, 0x3E9, 500446); // That is too far away. - return; - } - - if (!m_Plant.IsUsableBy(from)) - { - m_Plant.LabelTo(from, 1061856); // You must have the item in your backpack or locked down in order to use it. - return; - } - - switch (info.ButtonID) - { - case 1: // Cancel - { - from.SendGump(new ReproductionGump(m_Plant)); - - break; - } - case 2: // Help - { - from.NetState.SendDisplayHelpTopic(HelpTopic.DecorativeMode); - - from.SendGump(new SetToDecorativeGump(m_Plant)); - - break; - } - case 3: // Ok - { - m_Plant.PlantStatus = PlantStatus.DecorativePlant; - // You prune the plant. - // This plant will no longer produce resources or seeds, but will require no upkeep. - m_Plant.LabelTo(from, 1053077); - - break; - } - } + switch (info.ButtonID) + { + case 1: // Cancel + { + ReproductionGump.DisplayTo(from, _plant); + break; + } + case 2: // Help + { + from.NetState.SendDisplayHelpTopic(HelpTopic.DecorativeMode); + from.SendGump(this); + break; + } + case 3: // Ok + { + _plant.PlantStatus = PlantStatus.DecorativePlant; + // You prune the plant. + // This plant will no longer produce resources or seeds, but will require no upkeep. + _plant.LabelTo(from, 1053077); + break; + } } } }