Files
abysmal-isle/Scripts/Services/Plants/PlantItem.cs
Unstable Kitsune b918192e4e Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
2023-11-28 23:20:26 -05:00

645 lines
16 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Multis;
using Server.ContextMenus;
using Server.Network;
namespace Server.Engines.Plants
{
public enum PlantStatus
{
BowlOfDirt = 0,
Seed = 1,
Sapling = 2,
Plant = 4,
FullGrownPlant = 7,
DecorativePlant = 10,
DeadTwigs = 11,
Stage1 = 1,
Stage2 = 2,
Stage3 = 3,
Stage4 = 4,
Stage5 = 5,
Stage6 = 6,
Stage7 = 7,
Stage8 = 8,
Stage9 = 9
}
public class PlantItem : Item, ISecurable
{
/*
* Clients 7.0.12.0+ expect a container type in the plant label.
* To support older (and only older) clients, change this to false.
*/
private static readonly bool ShowContainerType = true;
private PlantSystem m_PlantSystem;
private PlantStatus m_PlantStatus;
private PlantType m_PlantType;
private PlantHue m_PlantHue;
private bool m_ShowType;
private SecureLevel m_Level;
[CommandProperty( AccessLevel.GameMaster )]
public SecureLevel Level
{
get{ return m_Level; }
set{ m_Level = value; }
}
public PlantSystem PlantSystem { get { return m_PlantSystem; } }
public override bool ForceShowProperties{ get{ return ObjectPropertyList.Enabled; } }
#region Magincia/Raised Garden Plant Support
public virtual bool RequiresUpkeep { get { return true; } }
public virtual bool MaginciaPlant { get { return false; } }
public virtual int BowlOfDirtID { get { return 0x1602; } }
public virtual int GreenBowlID { get { return 0x1600; } }
public virtual int ContainerLocalization { get { return 1150435; } }
public virtual int OnPlantLocalization { get { return 1061922; } }
public virtual int CantUseLocalization { get { return 1061921; } }
#endregion
public override void OnSingleClick( Mobile from )
{
if ( m_PlantStatus >= PlantStatus.DeadTwigs )
LabelTo( from, LabelNumber );
else if ( m_PlantStatus >= PlantStatus.DecorativePlant )
LabelTo( from, 1061924 ); // a decorative plant
else if ( m_PlantStatus >= PlantStatus.FullGrownPlant )
LabelTo( from, PlantTypeInfo.GetInfo( m_PlantType ).Name );
else
LabelTo( from, 1029913 ); // plant bowl
}
[CommandProperty( AccessLevel.GameMaster )]
public PlantStatus PlantStatus
{
get { return m_PlantStatus; }
set
{
if ( m_PlantStatus == value || value < PlantStatus.BowlOfDirt || value > PlantStatus.DeadTwigs )
return;
double ratio;
if ( m_PlantSystem != null )
ratio = (double) m_PlantSystem.Hits / m_PlantSystem.MaxHits;
else
ratio = 1.0;
m_PlantStatus = value;
if ( m_PlantStatus >= PlantStatus.DecorativePlant )
{
m_PlantSystem = null;
}
else
{
if ( m_PlantSystem == null )
m_PlantSystem = new PlantSystem( this, false );
int hits = (int)( m_PlantSystem.MaxHits * ratio );
if ( hits == 0 && m_PlantStatus > PlantStatus.BowlOfDirt )
m_PlantSystem.Hits = hits + 1;
else
m_PlantSystem.Hits = hits;
}
Update();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public PlantType PlantType
{
get { return m_PlantType; }
set
{
m_PlantType = value;
Update();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public PlantHue PlantHue
{
get { return m_PlantHue; }
set
{
m_PlantHue = value;
Update();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool ShowType
{
get { return m_ShowType; }
set
{
m_ShowType = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public virtual bool ValidGrowthLocation
{
get
{
if ( IsLockedDown && RootParent == null )
return true;
Mobile owner = RootParent as Mobile;
if ( owner == null )
return false;
if ( owner.Backpack != null && IsChildOf( owner.Backpack ) )
return true;
BankBox bank = owner.FindBankNoCreate();
if ( bank != null && IsChildOf( bank ) )
return true;
return false;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool IsGrowable
{
get { return m_PlantStatus >= PlantStatus.BowlOfDirt && m_PlantStatus <= PlantStatus.Stage9; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool IsCrossable
{
get { return PlantHueInfo.IsCrossable( this.PlantHue ) && PlantTypeInfo.IsCrossable( this.PlantType ); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Reproduces
{
get { return PlantHueInfo.CanReproduce( this.PlantHue ) && PlantTypeInfo.CanReproduce( this.PlantType ); }
}
private static ArrayList m_Instances = new ArrayList();
public static ArrayList Plants{ get{ return m_Instances; } }
[Constructable]
public PlantItem() : this( 0x1602, false )
{
}
[Constructable]
public PlantItem(int itemID) : this(itemID, false)
{
}
[Constructable]
public PlantItem(bool fertileDirt) : this(0x1602, fertileDirt)
{
}
[Constructable]
public PlantItem( int itemID, bool fertileDirt ) : base( itemID )
{
Weight = 1.0;
m_PlantStatus = PlantStatus.BowlOfDirt;
m_PlantSystem = new PlantSystem( this, fertileDirt );
m_Level = SecureLevel.Owner;
m_Instances.Add( this );
}
public PlantItem( Serial serial ) : base( serial )
{
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
if (m_PlantStatus != PlantStatus.DecorativePlant)
{
SetSecureLevelEntry.AddTo(from, this, list);
}
}
public int GetLocalizedPlantStatus()
{
if ( m_PlantStatus >= PlantStatus.Plant )
return 1060812; // plant
else if ( m_PlantStatus >= PlantStatus.Sapling )
return 1023305; // sapling
else if ( m_PlantStatus >= PlantStatus.Seed )
return 1060810; // seed
else
return 1026951; // dirt
}
public int GetLocalizedContainerType()
{
return ContainerLocalization; // mound -or- bowl
}
private void Update()
{
if ( m_PlantStatus >= PlantStatus.DeadTwigs )
{
ItemID = 0x1B9D;
Hue = PlantHueInfo.GetInfo( m_PlantHue ).Hue;
}
else if ( m_PlantStatus >= PlantStatus.FullGrownPlant )
{
ItemID = PlantTypeInfo.GetInfo( m_PlantType ).ItemID;
Hue = PlantHueInfo.GetInfo( m_PlantHue ).Hue;
}
else if ( m_PlantStatus >= PlantStatus.Plant )
{
ItemID = GreenBowlID;
Hue = 0;
}
else
{
ItemID = BowlOfDirtID;
Hue = 0;
}
InvalidateProperties();
}
public override void AddNameProperty( ObjectPropertyList list )
{
if ( m_PlantStatus >= PlantStatus.DeadTwigs )
{
base.AddNameProperty( list );
}
else if ( m_PlantStatus < PlantStatus.Seed )
{
string args;
if ( ShowContainerType )
args = String.Format( "#{0}\t#{1}", GetLocalizedContainerType(), m_PlantSystem.GetLocalizedDirtStatus() );
else
args = String.Format( "#{0}", m_PlantSystem.GetLocalizedDirtStatus() );
list.Add( 1060830, args ); // a ~1_val~ of ~2_val~ dirt
}
else
{
PlantTypeInfo typeInfo = PlantTypeInfo.GetInfo( m_PlantType );
PlantHueInfo hueInfo = PlantHueInfo.GetInfo( m_PlantHue );
if ( m_PlantStatus >= PlantStatus.DecorativePlant )
{
list.Add( typeInfo.GetPlantLabelDecorative( hueInfo ), String.Format( "#{0}\t#{1}", hueInfo.Name, typeInfo.Name ) );
}
else if ( m_PlantStatus >= PlantStatus.FullGrownPlant )
{
list.Add( typeInfo.GetPlantLabelFullGrown( hueInfo ), String.Format( "#{0}\t#{1}\t#{2}", m_PlantSystem.GetLocalizedHealth(), hueInfo.Name, typeInfo.Name ) );
}
else
{
string args;
if ( ShowContainerType )
args = String.Format( "#{0}\t#{1}\t#{2}", GetLocalizedContainerType(), m_PlantSystem.GetLocalizedDirtStatus(), m_PlantSystem.GetLocalizedHealth() );
else
args = String.Format( "#{0}\t#{1}", m_PlantSystem.GetLocalizedDirtStatus(), m_PlantSystem.GetLocalizedHealth() );
if ( m_ShowType )
{
args += String.Format( "\t#{0}\t#{1}\t#{2}", hueInfo.Name, typeInfo.Name, GetLocalizedPlantStatus() );
if ( m_PlantStatus == PlantStatus.Plant )
list.Add( typeInfo.GetPlantLabelPlant( hueInfo ), args );
else
list.Add( typeInfo.GetPlantLabelSeed( hueInfo ), args );
}
else
{
args += String.Format( "\t#{0}\t#{1}", ( typeInfo.PlantCategory == PlantCategory.Default ) ? hueInfo.Name : (int)typeInfo.PlantCategory, GetLocalizedPlantStatus() );
list.Add( hueInfo.IsBright() ? 1060832 : 1060831, args ); // a ~1_val~ of ~2_val~ dirt with a ~3_val~ [bright] ~4_val~ ~5_val~
}
}
}
}
public virtual bool IsUsableBy( Mobile from )
{
Item root = RootParent as Item;
return IsChildOf( from.Backpack ) || IsChildOf( from.FindBankNoCreate() ) || IsLockedDown && IsAccessibleTo( from ) || root != null && root.IsSecure && root.IsAccessibleTo( from );
}
public override void OnDoubleClick( Mobile from )
{
if ( m_PlantStatus >= PlantStatus.DecorativePlant )
return;
Point3D loc = this.GetWorldLocation();
if ( !from.InLOS( loc ) || !from.InRange( loc, 2 ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3E9, 1019045 ); // I can't reach that.
return;
}
if ( !IsUsableBy( from ) )
{
LabelTo( from, 1061856 ); // You must have the item in your backpack or locked down in order to use it.
return;
}
from.SendGump( new MainPlantGump( this ) );
}
public virtual bool PlantSeed( Mobile from, Seed seed )
{
if ( m_PlantStatus >= PlantStatus.FullGrownPlant )
{
LabelTo( from, 1061919 ); // You must use a seed on some prepared soil!
}
else if ( !IsUsableBy( from ) )
{
LabelTo( from, CantUseLocalization ); // The bowl of dirt must be in your pack, or you must lock it down.
}
else if ( m_PlantStatus != PlantStatus.BowlOfDirt )
{
if(RequiresUpkeep && !MaginciaPlant)
from.SendLocalizedMessage( 1080389, "#" + GetLocalizedPlantStatus().ToString() ); // This bowl of dirt already has a ~1_val~ in it!
else
from.SendLocalizedMessage( 1150441 ); // This mound of dirt already has a seed in it!
}
else if ( RequiresUpkeep && m_PlantSystem.Water < 2 )
{
LabelTo( from, 1061920 ); // The dirt needs to be softened first.
}
else
{
m_PlantType = seed.PlantType;
m_PlantHue = seed.PlantHue;
m_ShowType = seed.ShowType;
seed.Consume();
PlantStatus = PlantStatus.Seed;
m_PlantSystem.Reset( false );
LabelTo( from, OnPlantLocalization ); // You plant the seed in the bowl of dirt.
return true;
}
return false;
}
public virtual void Die()
{
if ( m_PlantStatus >= PlantStatus.FullGrownPlant )
{
PlantStatus = PlantStatus.DeadTwigs;
}
else
{
PlantStatus = PlantStatus.BowlOfDirt;
m_PlantSystem.Reset( true );
}
}
public void Pour( Mobile from, Item item )
{
if ( m_PlantStatus >= PlantStatus.DeadTwigs )
return;
if ( m_PlantStatus == PlantStatus.DecorativePlant )
{
LabelTo( from, 1053049 ); // This is a decorative plant, it does not need watering!
return;
}
if ( !RequiresUpkeep )
{
LabelTo( from, 1150619 ); // You don't need to water it.
return;
}
if ( !IsUsableBy( from ) )
{
LabelTo( from, 1061856 ); // You must have the item in your backpack or locked down in order to use it.
return;
}
if ( item is BaseBeverage )
{
BaseBeverage beverage = (BaseBeverage)item;
if ( beverage.IsEmpty || !beverage.Pourable || beverage.Content != BeverageType.Water )
{
LabelTo( from, 1053069 ); // You can't use that on a plant!
return;
}
if ( !beverage.ValidateUse( from, true ) )
return;
beverage.Quantity--;
m_PlantSystem.Water++;
from.PlaySound( 0x4E );
LabelTo( from, 1061858 ); // You soften the dirt with water.
m_PlantSystem.NextGrowth = DateTime.UtcNow + PlantSystem.CheckDelay;
}
else if ( item is BasePotion )
{
BasePotion potion = (BasePotion)item;
int message;
if ( ApplyPotion( potion.PotionEffect, false, out message ) )
{
potion.Consume();
from.PlaySound( 0x240 );
from.AddToBackpack( new Bottle() );
m_PlantSystem.NextGrowth = DateTime.UtcNow + PlantSystem.CheckDelay;
}
LabelTo( from, message );
}
else if ( item is PotionKeg )
{
PotionKeg keg = (PotionKeg)item;
if ( keg.Held <= 0 )
{
LabelTo( from, 1053069 ); // You can't use that on a plant!
return;
}
int message;
if ( ApplyPotion( keg.Type, false, out message ) )
{
keg.Held--;
from.PlaySound( 0x240 );
m_PlantSystem.NextGrowth = DateTime.UtcNow + PlantSystem.CheckDelay;
}
LabelTo( from, message );
}
else
{
LabelTo( from, 1053069 ); // You can't use that on a plant!
}
}
public bool ApplyPotion( PotionEffect effect, bool testOnly, out int message )
{
if ( m_PlantStatus >= PlantStatus.DecorativePlant )
{
message = 1053049; // This is a decorative plant, it does not need watering!
return false;
}
if ( !RequiresUpkeep )
{
message = 1150619; // You don't need to water it.
return false;
}
if ( m_PlantStatus == PlantStatus.BowlOfDirt )
{
message = 1053066; // You should only pour potions on a plant or seed!
return false;
}
bool full = false;
if ( effect == PotionEffect.PoisonGreater || effect == PotionEffect.PoisonDeadly )
{
if ( m_PlantSystem.IsFullPoisonPotion )
full = true;
else if ( !testOnly )
m_PlantSystem.PoisonPotion++;
}
else if ( effect == PotionEffect.CureGreater )
{
if ( m_PlantSystem.IsFullCurePotion )
full = true;
else if ( !testOnly )
m_PlantSystem.CurePotion++;
}
else if ( effect == PotionEffect.HealGreater )
{
if ( m_PlantSystem.IsFullHealPotion )
full = true;
else if ( !testOnly )
m_PlantSystem.HealPotion++;
}
else if ( effect == PotionEffect.StrengthGreater )
{
if ( m_PlantSystem.IsFullStrengthPotion )
full = true;
else if ( !testOnly )
m_PlantSystem.StrengthPotion++;
}
else if ( effect == PotionEffect.PoisonLesser || effect == PotionEffect.Poison || effect == PotionEffect.CureLesser || effect == PotionEffect.Cure ||
effect == PotionEffect.HealLesser || effect == PotionEffect.Heal || effect == PotionEffect.Strength )
{
message = 1053068; // This potion is not powerful enough to use on a plant!
return false;
}
else
{
message = 1053069; // You can't use that on a plant!
return false;
}
if ( full )
{
message = 1053065; // The plant is already soaked with this type of potion!
return false;
}
else
{
message = 1053067; // You pour the potion over the plant.
return true;
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 2 ); // version
writer.Write( (int) m_Level );
writer.Write( (int) m_PlantStatus );
writer.Write( (int) m_PlantType );
writer.Write( (int) m_PlantHue );
writer.Write( (bool) m_ShowType );
if ( m_PlantStatus < PlantStatus.DecorativePlant )
m_PlantSystem.Save( writer );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 2:
case 1:
{
m_Level = (SecureLevel)reader.ReadInt();
goto case 0;
}
case 0:
{
if ( version < 1 )
m_Level = SecureLevel.CoOwners;
m_PlantStatus = (PlantStatus)reader.ReadInt();
m_PlantType = (PlantType)reader.ReadInt();
m_PlantHue = (PlantHue)reader.ReadInt();
m_ShowType = reader.ReadBool();
if ( m_PlantStatus < PlantStatus.DecorativePlant )
m_PlantSystem = new PlantSystem( this, reader );
if ( version < 2 && PlantHueInfo.IsCrossable( m_PlantHue ) )
m_PlantHue |= PlantHue.Reproduces;
break;
}
}
m_Instances.Add( this );
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
m_Instances.Remove( this );
}
}
}