## 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<T>`. - `SetToDecorativeGump` → `StaticGump<SetToDecorativeGump>`. 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)`
289 lines
9.4 KiB
C#
289 lines
9.4 KiB
C#
using Server.Engines.Help;
|
|
using Server.Gumps;
|
|
using Server.Network;
|
|
|
|
namespace Server.Engines.Plants;
|
|
|
|
public class ReproductionGump : DynamicGump
|
|
{
|
|
private readonly PlantItem _plant;
|
|
|
|
public override bool Singleton => true;
|
|
|
|
private ReproductionGump(PlantItem plant) : base(20, 20)
|
|
{
|
|
_plant = plant;
|
|
}
|
|
|
|
public static void DisplayTo(Mobile from, PlantItem plant)
|
|
{
|
|
if (from?.NetState == null || plant == null || plant.Deleted)
|
|
{
|
|
return;
|
|
}
|
|
|
|
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)
|
|
{
|
|
builder.AddButton(212, 67, 0xD4, 0xD4, 2); // Set to decorative
|
|
builder.AddItem(202, 68, 0xC61);
|
|
builder.AddLabel(216, 66, 0x21, "/");
|
|
}
|
|
|
|
builder.AddButton(80, 116, 0xD4, 0xD4, 3); // Pollination
|
|
builder.AddItem(66, 117, 0x1AA2);
|
|
AddPollinationState(ref builder, 106, 116);
|
|
|
|
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, "-");
|
|
}
|
|
else if (!system.Pollinated)
|
|
{
|
|
builder.AddLabel(x, y, 0x21, "!");
|
|
}
|
|
else
|
|
{
|
|
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);
|
|
}
|
|
}
|