/Scripts/Engines/AI/Creature/BaseCreature.cs
C# | 4750 lines | 3594 code | 997 blank | 159 comment | 913 complexity | 1afd62a65d5182fc73a5cee6e9e74830 MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- using System;
- using System.Collections;
- using Server;
- using Server.Regions;
- using Server.Targeting;
- using Server.Network;
- using Server.Spells;
- using Server.Misc;
- using Server.Items;
- using Server.Mobiles;
- using Server.ContextMenus;
- using Server.Engines.Quests;
- using Server.Engines;
- using System.Collections.Generic;
- namespace Server.Mobiles
- {
- /// <summary>
- /// Summary description for MobileAI.
- /// </summary>
- ///
- public enum FightMode
- {
- None, // Never focus on others
- Agressor, // Only attack agressors
- Strongest, // Attack the strongest
- Weakest, // Attack the weakest
- Closest, // Attack the closest
- Evil // Only attack aggressor -or- negative karma
- }
- public enum OrderType
- {
- None, //When no order, let's roam
- Come, //"(All/Name) come" Summons all or one pet to your location.
- Drop, //"(Name) drop" Drops its loot to the ground (if it carries any).
- Follow, //"(Name) follow" Follows targeted being.
- //"(All/Name) follow me" Makes all or one pet follow you.
- Friend, //"(Name) friend" Allows targeted player to confirm resurrection.
- Guard, //"(Name) guard" Makes the specified pet guard you. Pets can only guard their owner.
- //"(All/Name) guard me" Makes all or one pet guard you.
- Attack, //"(All/Name) kill",
- //"(All/Name) attack" All or the specified pet(s) currently under your control attack the target.
- Patrol, //"(Name) patrol" Roves between two or more guarded targets.
- Release, //"(Name) release" Releases pet back into the wild (removes "tame" status).
- Stay, //"(All/Name) stay" All or the specified pet(s) will stop and stay in current spot.
- Stop, //"(All/Name) stop Cancels any current orders to attack, guard or follow.
- Transfert //"(Name) transfer" Transfers complete ownership to targeted player.
- }
- [Flags]
- public enum FoodType
- {
- Meat = 0x0001,
- FruitsAndVegies = 0x0002,
- GrainsAndHay = 0x0004,
- Fish = 0x0008,
- Eggs = 0x0010,
- Gold = 0x0020
- }
- [Flags]
- public enum PackInstinct
- {
- None = 0x0000,
- Canine = 0x0001,
- Ostard = 0x0002,
- Feline = 0x0004,
- Arachnid = 0x0008,
- Daemon = 0x0010,
- Bear = 0x0020,
- Equine = 0x0040,
- Bull = 0x0080
- }
- public enum ScaleType
- {
- Red,
- Yellow,
- Black,
- Green,
- White,
- Blue,
- All
- }
- public enum MeatType
- {
- Ribs,
- Bird,
- LambLeg,
- Chicken
- }
- public enum HideType
- {
- Regular,
- Spined,
- Horned,
- Barbed
- }
- public enum PetLoyalty
- {
- None,
- Confused,
- ExtremelyUnhappy,
- RatherUnhappy,
- Unhappy,
- SomewhatContent,
- Content,
- Happy,
- RatherHappy,
- VeryHappy,
- ExtremelyHappy,
- WonderfullyHappy
- }
- public class DamageStore : IComparable
- {
- public Mobile m_Mobile;
- public int m_Damage;
- public bool m_HasRight;
- public DamageStore(Mobile m, int damage)
- {
- m_Mobile = m;
- m_Damage = damage;
- }
- public int CompareTo(object obj)
- {
- DamageStore ds = (DamageStore)obj;
- return ds.m_Damage - m_Damage;
- }
- }
- [Description("PNJ")]
- public class BaseCreature : Mobile
- {
- private BaseAI m_AI; // THE AI
- private AIType m_CurrentAI; // The current AI
- private AIType m_DefaultAI; // The default AI
- private Mobile m_FocusMob; // Use focus mob instead of combatant, maybe we don't whan to fight
- private FightMode m_FightMode; // The style the mob uses
- private LootPackLevel m_LootLevel; // The loot pack level of the mob
- private int m_iRangePerception; // The view area
- private int m_iRangeFight; // The fight distance
- private bool m_bDebugAI; // Show debug AI messages
- private int m_iTeam; // Monster Team
- private double m_dActiveSpeed; // Timer speed when active
- private double m_dPassiveSpeed; // Timer speed when not active
- private double m_dCurrentSpeed; // The current speed, lets say it could be changed by something;
- private Point3D m_pHome; // The home position of the creature, used by some AI
- private int m_iRangeHome = 10; // The home range of the creature
- ArrayList m_arSpellAttack; // List of attack spell/power
- ArrayList m_arSpellDefense; // Liste of defensive spell/power
- private bool m_bControled; // Is controled
- private Mobile m_ControlMaster; // My master
- private Mobile m_ControlTarget; // My target mobile
- private Point3D m_ControlDest; // My target destination (patrol)
- private OrderType m_ControlOrder; // My order
- private PetLoyalty m_Loyalty;
- private double m_dMinTameSkill;
- private bool m_bTamable;
- private bool m_bSummoned = false;
- private DateTime m_SummonEnd;
- private int m_iControlSlots = 1;
- private bool m_bBardProvoked = false;
- private bool m_bBardPacified = false;
- private Mobile m_bBardMaster = null;
- private Mobile m_bBardTarget = null;
- private DateTime m_timeBardEnd;
- private WayPoint m_CurrentWayPoint = null;
- private Point2D m_TargetLocation = Point2D.Zero;
- private Mobile m_SummonMaster;
- private int m_HitsMax = -1;
- private int m_StamMax = -1;
- private int m_ManaMax = -1;
- private int m_DamageMin = -1;
- private int m_DamageMax = -1;
- private int m_PhysicalResistance, m_PhysicalDamage = 100;
- private int m_FireResistance, m_FireDamage;
- private int m_ColdResistance, m_ColdDamage;
- private int m_PoisonResistance, m_PoisonDamage;
- private int m_EnergyResistance, m_EnergyDamage;
- private ArrayList m_Owners;
- private Hashtable m_FearLove;
- private Hashtable m_Hate;
- private bool m_IsSystemInitialized = false;
- protected TimeSpan m_SayingsDelay = TimeSpan.FromSeconds(30);
- protected DateTime m_NextSaying;
- protected bool m_SayingsEnabled = false;
- protected int m_SayingsSecondsDelay = 30;
- protected string m_Saying1 = "";
- protected string m_Saying2 = "";
- protected string m_Saying3 = "";
- protected string m_Saying4 = "";
- protected string m_Saying5 = "";
- private bool m_ShowNameTag = true;
- private bool m_IsStabled;
- private bool m_HasGeneratedLoot; // have we generated our loot yet?
- public virtual InhumanSpeech SpeechType { get { return null; } }
- public bool IsStabled
- {
- get { return m_IsStabled; }
- set { m_IsStabled = value; }
- }
- #region Bonding
- public const bool BondingEnabled = true;
- public virtual bool IsBondable { get { return (BondingEnabled && !Summoned); } }
- public virtual TimeSpan BondingDelay { get { return TimeSpan.FromDays(7.0); } }
- public virtual TimeSpan BondingAbandonDelay { get { return TimeSpan.FromDays(1.0); } }
- public override bool CanRegenHits { get { return !m_IsDeadPet && base.CanRegenHits; } }
- public override bool CanRegenStam { get { return !m_IsDeadPet && base.CanRegenStam; } }
- public override bool CanRegenMana { get { return !m_IsDeadPet && base.CanRegenMana; } }
- public override bool IsDeadBondedPet { get { return m_IsDeadPet; } }
- private bool m_IsBonded;
- private bool m_IsDeadPet;
- private DateTime m_BondingBegin;
- private DateTime m_OwnerAbandonTime;
- [CommandProperty(AccessLevel.GameMaster)]
- public bool IsBonded
- {
- get { return m_IsBonded; }
- set { m_IsBonded = value; InvalidateProperties(); }
- }
- public bool IsDeadPet
- {
- get { return m_IsDeadPet; }
- set { m_IsDeadPet = value; }
- }
- [CommandProperty(AccessLevel.GameMaster)]
- public DateTime BondingBegin
- {
- get { return m_BondingBegin; }
- set { m_BondingBegin = value; }
- }
- [CommandProperty(AccessLevel.GameMaster)]
- public DateTime OwnerAbandonTime
- {
- get { return m_OwnerAbandonTime; }
- set { m_OwnerAbandonTime = value; }
- }
- #endregion
- public virtual double WeaponAbilityChance { get { return 0.4; } }
- public virtual WeaponAbility GetWeaponAbility()
- {
- return null;
- }
- public override int BasePhysicalResistance { get { return m_PhysicalResistance; } }
- public override int BaseFireResistance { get { return m_FireResistance; } }
- public override int BaseColdResistance { get { return m_ColdResistance; } }
- public override int BasePoisonResistance { get { return m_PoisonResistance; } }
- public override int BaseEnergyResistance { get { return m_EnergyResistance; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public bool ShowNameTag { get { return m_ShowNameTag; } set { m_ShowNameTag = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public bool SayingsEnabled { get { return m_SayingsEnabled; } set { m_SayingsEnabled = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public int SayingsSecondsDelay { get { return m_SayingsSecondsDelay; } set { m_SayingsSecondsDelay = value; m_SayingsDelay = TimeSpan.FromSeconds(value); } }
- [CommandProperty(AccessLevel.GameMaster)]
- public string Saying1 { get { return m_Saying1; } set { m_Saying1 = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public string Saying2 { get { return m_Saying2; } set { m_Saying2 = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public string Saying3 { get { return m_Saying3; } set { m_Saying3 = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public string Saying4 { get { return m_Saying4; } set { m_Saying4 = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public string Saying5 { get { return m_Saying5; } set { m_Saying5 = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public int PhysicalResistanceSeed { get { return m_PhysicalResistance; } set { m_PhysicalResistance = value; UpdateResistances(); } }
- [CommandProperty(AccessLevel.GameMaster)]
- public int FireResistSeed { get { return m_FireResistance; } set { m_FireResistance = value; UpdateResistances(); } }
- [CommandProperty(AccessLevel.GameMaster)]
- public int ColdResistSeed { get { return m_ColdResistance; } set { m_ColdResistance = value; UpdateResistances(); } }
- [CommandProperty(AccessLevel.GameMaster)]
- public int PoisonResistSeed { get { return m_PoisonResistance; } set { m_PoisonResistance = value; UpdateResistances(); } }
- [CommandProperty(AccessLevel.GameMaster)]
- public int EnergyResistSeed { get { return m_EnergyResistance; } set { m_EnergyResistance = value; UpdateResistances(); } }
- [CommandProperty(AccessLevel.GameMaster)]
- public int PhysicalDamage { get { return m_PhysicalDamage; } set { m_PhysicalDamage = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public int FireDamage { get { return m_FireDamage; } set { m_FireDamage = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public int ColdDamage { get { return m_ColdDamage; } set { m_ColdDamage = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public int PoisonDamage { get { return m_PoisonDamage; } set { m_PoisonDamage = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public int EnergyDamage { get { return m_EnergyDamage; } set { m_EnergyDamage = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public LootPackLevel LootLevel { get { return m_LootLevel; } set { m_LootLevel = value; } }
- public virtual FoodType FavoriteFood { get { return FoodType.Meat; } }
- public virtual PackInstinct PackInstinct { get { return PackInstinct.None; } }
- public ArrayList Owners { get { return m_Owners; } }
- public virtual bool AllowMaleTamer { get { return true; } }
- public virtual bool AllowFemaleTamer { get { return true; } }
- public virtual bool SubdueBeforeTame { get { return false; } }
- public virtual bool Commandable { get { return true; } }
- public virtual Poison HitPoison { get { return null; } }
- public virtual double HitPoisonChance { get { return 0.5; } }
- public virtual Poison PoisonImmune { get { return null; } }
- public virtual bool BardImmune { get { return false; } }
- public virtual bool Unprovokable { get { return BardImmune || m_IsDeadPet; } }
- public virtual bool Uncalmable { get { return BardImmune || m_IsDeadPet; } }
- public virtual double DispelDifficulty { get { return 0.0; } } // at this skill level we dispel 50% chance
- public virtual double DispelFocus { get { return 20.0; } } // at difficulty - focus we have 0%, at difficulty + focus we have 100%
- #region Breath ability, like dragon fire breath
- private DateTime m_NextBreathTime;
- // Must be overriden in subclass to enable
- public virtual bool HasBreath { get { return false; } }
- // Base damage given is: CurrentHitPoints * BreathDamageScalar
- public virtual double BreathDamageScalar { get { return (Core.AOS ? 0.16 : 0.05); } }
- // Min/max seconds until next breath
- public virtual double BreathMinDelay { get { return 10.0; } }
- public virtual double BreathMaxDelay { get { return 15.0; } }
- // Creature stops moving for 1.0 seconds while breathing
- public virtual double BreathStallTime { get { return 1.0; } }
- // Effect is sent 1.3 seconds after BreathAngerSound and BreathAngerAnimation is played
- public virtual double BreathEffectDelay { get { return 1.3; } }
- // Damage is given 1.0 seconds after effect is sent
- public virtual double BreathDamageDelay { get { return 1.0; } }
- public virtual int BreathRange { get { return RangePerception; } }
- // Damage types
- public virtual int BreathPhysicalDamage { get { return 0; } }
- public virtual int BreathFireDamage { get { return 100; } }
- public virtual int BreathColdDamage { get { return 0; } }
- public virtual int BreathPoisonDamage { get { return 0; } }
- public virtual int BreathEnergyDamage { get { return 0; } }
- // Effect details and sound
- public virtual int BreathEffectItemID { get { return 0x36D4; } }
- public virtual int BreathEffectSpeed { get { return 5; } }
- public virtual int BreathEffectDuration { get { return 0; } }
- public virtual bool BreathEffectExplodes { get { return false; } }
- public virtual bool BreathEffectFixedDir { get { return false; } }
- public virtual int BreathEffectHue { get { return 0; } }
- public virtual int BreathEffectRenderMode { get { return 0; } }
- public virtual int BreathEffectSound { get { return 0x227; } }
- // Anger sound/animations
- public virtual int BreathAngerSound { get { return GetAngerSound(); } }
- public virtual int BreathAngerAnimation { get { return 12; } }
- public virtual void BreathStart(Mobile target)
- {
- BreathStallMovement();
- BreathPlayAngerSound();
- BreathPlayAngerAnimation();
- this.Direction = this.GetDirectionTo(target);
- Timer.DelayCall(TimeSpan.FromSeconds(BreathEffectDelay), new TimerStateCallback(BreathEffect_Callback), target);
- }
- public virtual void BreathStallMovement()
- {
- if (m_AI != null)
- m_AI.NextMove = DateTime.Now + TimeSpan.FromSeconds(BreathStallTime);
- }
- public virtual void BreathPlayAngerSound()
- {
- PlaySound(BreathAngerSound);
- }
- public virtual void BreathPlayAngerAnimation()
- {
- Animate(BreathAngerAnimation, 5, 1, true, false, 0);
- }
- public virtual void BreathEffect_Callback(object state)
- {
- Mobile target = (Mobile)state;
- if (!target.Alive || !CanBeHarmful(target))
- return;
- BreathPlayEffectSound();
- BreathPlayEffect(target);
- Timer.DelayCall(TimeSpan.FromSeconds(BreathDamageDelay), new TimerStateCallback(BreathDamage_Callback), target);
- }
- public virtual void BreathPlayEffectSound()
- {
- PlaySound(BreathEffectSound);
- }
- public virtual void BreathPlayEffect(Mobile target)
- {
- Effects.SendMovingEffect(this, target, BreathEffectItemID,
- BreathEffectSpeed, BreathEffectDuration, BreathEffectFixedDir,
- BreathEffectExplodes, BreathEffectHue, BreathEffectRenderMode);
- }
- public virtual void BreathDamage_Callback(object state)
- {
- Mobile target = (Mobile)state;
- if (CanBeHarmful(target))
- {
- DoHarmful(target);
- BreathDealDamage(target);
- }
- }
- public virtual void BreathDealDamage(Mobile target)
- {
- int physDamage = BreathPhysicalDamage;
- int fireDamage = BreathFireDamage;
- int coldDamage = BreathColdDamage;
- int poisDamage = BreathPoisonDamage;
- int nrgyDamage = BreathEnergyDamage;
- if (physDamage == 0 && fireDamage == 0 && coldDamage == 0 && poisDamage == 0 && nrgyDamage == 0)
- { // Unresistable damage even in AOS
- target.Damage(BreathComputeDamage(), this);
- }
- else
- {
- AOS.Damage(target, this, BreathComputeDamage(), physDamage, fireDamage, coldDamage, poisDamage, nrgyDamage);
- }
- }
- public virtual int BreathComputeDamage()
- {
- return (int)(Hits * BreathDamageScalar);
- }
- #endregion
- private DateTime m_EndFlee;
- public DateTime EndFleeTime
- {
- get { return m_EndFlee; }
- set { m_EndFlee = value; }
- }
- public virtual void StopFlee()
- {
- m_EndFlee = DateTime.MinValue;
- }
- public virtual bool CheckFlee()
- {
- if (m_EndFlee == DateTime.MinValue)
- return false;
- if (DateTime.Now >= m_EndFlee)
- {
- StopFlee();
- return false;
- }
- return true;
- }
- public virtual void BeginFlee(TimeSpan maxDuration)
- {
- m_EndFlee = DateTime.Now + maxDuration;
- }
- public BaseAI AIObject { get { return m_AI; } }
- public const int MaxOwners = 5;
- public virtual OppositionGroup OppositionGroup
- {
- get { return null; }
- }
- public virtual bool IsFriend(Mobile m)
- {
- OppositionGroup g = this.OppositionGroup;
- if (g != null && g.IsEnemy(this, m))
- return false;
- if (!(m is BaseCreature))
- return false;
- BaseCreature c = (BaseCreature)m;
- return (m_iTeam == c.m_iTeam && ((m_bSummoned || m_bControled) == (c.m_bSummoned || c.m_bControled)));
- }
- public virtual bool IsEnemy(Mobile m)
- {
- OppositionGroup g = this.OppositionGroup;
- if (g != null && g.IsEnemy(this, m))
- return true;
- if (m is BaseGuard)
- return false;
- if (!(m is BaseCreature))
- return true;
- BaseCreature c = (BaseCreature)m;
- return (m_iTeam != c.m_iTeam || ((m_bSummoned || m_bControled) != (c.m_bSummoned || c.m_bControled)));
- }
- public virtual bool CheckControlChance(Mobile m)
- {
- return CheckControlChance(m, 0.0);
- }
- public virtual bool CheckControlChance(Mobile m, double offset)
- {
- double v = GetControlChance(m) + offset;
- if (v > Utility.RandomDouble())
- return true;
- PlaySound(GetAngerSound());
- if (Body.IsAnimal)
- Animate(10, 5, 1, true, false, 0);
- else if (Body.IsMonster)
- Animate(18, 5, 1, true, false, 0);
- return false;
- }
- public virtual bool CanBeControlledBy(Mobile m)
- {
- return (GetControlChance(m) > 0.0);
- }
- public virtual double GetControlChance(Mobile m)
- {
- return 100;
- }
- private static Type[] m_AnimateDeadTypes = new Type[]
- {
- typeof( MoundOfMaggots ), typeof( HellSteed ), typeof( SkeletalMount ),
- typeof( WailingBanshee ), typeof( Wraith ), typeof( SkeletalDragon ),
- typeof( LichLord ), typeof( FleshGolem ), typeof( Lich ),
- typeof( SkeletalKnight ), typeof( BoneKnight ), typeof( Mummy2 ),
- typeof( SkeletalMage ), typeof( BoneMagi ), typeof( PatchworkSkeleton )
- };
- public virtual bool IsAnimatedDead
- {
- get
- {
- if (!Summoned)
- return false;
- Type type = this.GetType();
- bool contains = false;
- for (int i = 0; !contains && i < m_AnimateDeadTypes.Length; ++i)
- contains = (type == m_AnimateDeadTypes[i]);
- return contains;
- }
- }
- public override void Damage(int amount, Mobile from)
- {
- int oldHits = this.Hits;
- if (Spells.Necromancy.EvilOmenSpell.CheckEffect(this))
- amount = (int)(amount * 1.25);
- Mobile oath = Spells.Necromancy.BloodOathSpell.GetBloodOath(from);
- if (oath == this)
- {
- amount = (int)(amount * 1.1);
- from.Damage(amount, from);
- }
- base.Damage(amount, from);
- if (SubdueBeforeTame && !Controled)
- {
- if ((oldHits > (this.HitsMax / 10)) && (this.Hits <= (this.HitsMax / 10)))
- PublicOverheadMessage(MessageType.Regular, 0x3B2, false, "* The creature has been beaten into subjugation! *");
- }
- }
- public virtual bool DeleteCorpseOnDeath
- {
- get
- {
- return !Core.AOS && m_bSummoned;
- }
- }
- public override void SetLocation(Point3D newLocation, bool isTeleport)
- {
- base.SetLocation(newLocation, isTeleport);
- if (isTeleport && m_AI != null)
- m_AI.OnTeleported();
- }
- public override ApplyPoisonResult ApplyPoison(Mobile from, Poison poison)
- {
- if (!Alive || IsDeadPet)
- return ApplyPoisonResult.Immune;
- if (Spells.Necromancy.EvilOmenSpell.CheckEffect(this))
- return base.ApplyPoison(from, PoisonImpl.IncreaseLevel(poison));
- return base.ApplyPoison(from, poison);
- }
- public override bool CheckPoisonImmunity(Mobile from, Poison poison)
- {
- if (base.CheckPoisonImmunity(from, poison))
- return true;
- Poison p = this.PoisonImmune;
- return (p != null && p.Level >= poison.Level);
- }
- [CommandProperty(AccessLevel.GameMaster)]
- public PetLoyalty Loyalty
- {
- get
- {
- return m_Loyalty;
- }
- set
- {
- m_Loyalty = value;
- }
- }
- [CommandProperty(AccessLevel.GameMaster)]
- public WayPoint CurrentWayPoint
- {
- get
- {
- return m_CurrentWayPoint;
- }
- set
- {
- m_CurrentWayPoint = value;
- }
- }
- [CommandProperty(AccessLevel.GameMaster)]
- public Point2D TargetLocation
- {
- get
- {
- return m_TargetLocation;
- }
- set
- {
- m_TargetLocation = value;
- }
- }
- public virtual Mobile ConstantFocus { get { return null; } }
- public virtual bool DisallowAllMoves
- {
- get
- {
- return false;
- }
- }
- public virtual bool InitialInnocent
- {
- get
- {
- return false;
- }
- }
- public virtual bool AlwaysMurderer
- {
- get
- {
- return false;
- }
- }
- public virtual bool AlwaysAttackable
- {
- get
- {
- return false;
- }
- }
- [CommandProperty(AccessLevel.GameMaster)]
- public virtual int DamageMin { get { return m_DamageMin; } set { m_DamageMin = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public virtual int DamageMax { get { return m_DamageMax; } set { m_DamageMax = value; } }
- [CommandProperty(AccessLevel.GameMaster)]
- public override int HitsMax
- {
- get
- {
- if (m_HitsMax >= 0)
- return m_HitsMax;
- return Str;
- }
- }
- [CommandProperty(AccessLevel.GameMaster)]
- public int HitsMaxSeed
- {
- get { return m_HitsMax; }
- set { m_HitsMax = value; }
- }
- [CommandProperty(AccessLevel.GameMaster)]
- public override int StamMax
- {
- get
- {
- if (m_StamMax >= 0)
- return m_StamMax;
- return Dex;
- }
- }
- [CommandProperty(AccessLevel.GameMaster)]
- public int StamMaxSeed
- {
- get { return m_StamMax; }
- set { m_StamMax = value; }
- }
- [CommandProperty(AccessLevel.GameMaster)]
- public override int ManaMax
- {
- get
- {
- if (m_ManaMax >= 0)
- return m_ManaMax;
- return Int;
- }
- }
- [CommandProperty(AccessLevel.GameMaster)]
- public int ManaMaxSeed
- {
- get { return m_ManaMax; }
- set { m_ManaMax = value; }
- }
- public Hashtable FearLove
- {
- get { return m_FearLove; }
- }
- public Hashtable Hate
- {
- get { return m_Hate; }
- }
- public virtual bool CanOpenDoors
- {
- get
- {
- return !this.Body.IsAnimal && !this.Body.IsSea;
- }
- }
- public virtual bool CanMoveOverObstacles
- {
- get
- {
- return this.Body.IsMonster;
- }
- }
- public virtual bool CanDestroyObstacles
- {
- get
- {
- // to enable breaking of furniture, 'return CanMoveOverObstacles;'
- return false;
- }
- }
- public override void OnDamage(int amount, Mobile from, bool willKill)
- {
- WeightOverloading.FatigueOnDamage(this, amount);
- InhumanSpeech speechType = this.SpeechType;
- if (speechType != null && !willKill)
- speechType.OnDamage(this, amount);
- base.OnDamage(amount, from, willKill);
- }
- public virtual void OnDamagedBySpell(Mobile from)
- {
- }
- public virtual void AlterDamageScalarFrom(Mobile caster, ref double scalar)
- {
- }
- public virtual void AlterDamageScalarTo(Mobile target, ref double scalar)
- {
- }
- public virtual void AlterMeleeDamageFrom(Mobile from, ref int damage)
- {
- }
- public virtual void AlterMeleeDamageTo(Mobile to, ref int damage)
- {
- }
- public virtual void CheckReflect(Mobile caster, ref bool reflect)
- {
- }
- public virtual void OnCarve(Mobile from, Corpse corpse)
- {
- int feathers = Feathers;
- int wool = Wool;
- int meat = Meat;
- int hides = Hides;
- int scales = Scales;
- if ((feathers == 0 && wool == 0 && meat == 0 && hides == 0 && scales == 0) || Summoned || IsBonded)
- {
- from.SendLocalizedMessage(500485); // You see nothing useful to carve from the corpse.
- }
- else
- {
- if (corpse.Map == Map.Felucca)
- {
- feathers *= 2;
- wool *= 2;
- hides *= 2;
- }
- new Blood(0x122D).MoveToWorld(corpse.Location, corpse.Map);
- if (feathers != 0)
- {
- corpse.DropItem(new Feather(feathers));
- from.SendLocalizedMessage(500479); // You pluck the bird. The feathers are now on the corpse.
- }
- if (wool != 0)
- {
- corpse.DropItem(new Wool(wool));
- from.SendLocalizedMessage(500483); // You shear it, and the wool is now on the corpse.
- }
- if (meat != 0)
- {
- if (MeatType == MeatType.Ribs)
- corpse.DropItem(new RawRibs(meat));
- else if (MeatType == MeatType.Bird)
- corpse.DropItem(new RawBird(meat));
- else if (MeatType == MeatType.LambLeg)
- corpse.DropItem(new RawLambLeg(meat));
- else if (MeatType == MeatType.Chicken)
- corpse.DropItem(new RawChickenLeg(meat));
- from.SendLocalizedMessage(500467); // You carve some meat, which remains on the corpse.
- }
- if (hides != 0)
- {
- if (HideType == HideType.Regular)
- corpse.DropItem(new Hides(hides));
- else if (HideType == HideType.Spined)
- corpse.DropItem(new SpinedHides(hides));
- else if (HideType == HideType.Horned)
- corpse.DropItem(new HornedHides(hides));
- else if (HideType == HideType.Barbed)
- corpse.DropItem(new BarbedHides(hides));
- from.SendLocalizedMessage(500471); // You skin it, and the hides are now in the corpse.
- }
- if (scales != 0)
- {
- ScaleType sc = this.ScaleType;
- switch (sc)
- {
- case ScaleType.Red: corpse.DropItem(new RedScales(scales)); break;
- case ScaleType.Yellow: corpse.DropItem(new YellowScales(scales)); break;
- case ScaleType.Black: corpse.DropItem(new BlackScales(scales)); break;
- case ScaleType.Green: corpse.DropItem(new GreenScales(scales)); break;
- case ScaleType.White: corpse.DropItem(new WhiteScales(scales)); break;
- case ScaleType.Blue: corpse.DropItem(new BlueScales(scales)); break;
- case ScaleType.All:
- {
- corpse.DropItem(new RedScales(scales));
- corpse.DropItem(new YellowScales(scales));
- corpse.DropItem(new BlackScales(scales));
- corpse.DropItem(new GreenScales(scales));
- corpse.DropItem(new WhiteScales(scales));
- corpse.DropItem(new BlueScales(scales));
- break;
- }
- }
- from.SendMessage("You cut away some scales, but they remain on the corpse.");
- }
- corpse.Carved = true;
- if (corpse.IsCriminalAction(from))
- from.CriminalAction(true);
- }
- }
- public const int DefaultRangePerception = 16;
- public const int OldRangePerception = 10;
- public BaseCreature(AIType ai,
- FightMode mode,
- int iRangePerception,
- int iRangeFight,
- double dActiveSpeed,
- double dPassiveSpeed)
- {
- if (iRangePerception == OldRangePerception)
- iRangePerception = DefaultRangePerception;
- m_Loyalty = PetLoyalty.WonderfullyHappy;
- m_CurrentAI = ai;
- m_DefaultAI = ai;
- m_iRangePerception = iRangePerception;
- m_iRangeFight = iRangeFight;
- m_FightMode = mode;
- m_iTeam = 0;
- SpeedInfo.GetSpeeds(this, ref dActiveSpeed, ref dPassiveSpeed);
- m_dActiveSpeed = dActiveSpeed;
- m_dPassiveSpeed = dPassiveSpeed;
- m_dCurrentSpeed = dPassiveSpeed;
- m_bDebugAI = false;
- m_arSpellAttack = new ArrayList();
- m_arSpellDefense = new ArrayList();
- m_bControled = false;
- m_ControlMaster = null;
- m_ControlTarget = null;
- m_ControlOrder = OrderType.None;
- m_bTamable = false;
- m_Owners = new ArrayList();
- m_NextReaquireTime = DateTime.Now + ReaquireDelay;
- ChangeAIType(AI);
- InhumanSpeech speechType = this.SpeechType;
- if (speechType != null)
- speechType.OnConstruct(this);
- GenerateLoot(true);
- }
- public BaseCreature(Serial serial)
- : base(serial)
- {
- m_arSpellAttack = new ArrayList();
- m_arSpellDefense = new ArrayList();
- m_bDebugAI = false;
- }
- public override void Serialize(GenericWriter writer)
- {
- base.Serialize(writer);
- writer.Write((int)17); // version
- writer.Write((int)m_LootLevel);
- writer.Write(Frozen);
- writer.Write(m_IsSystemInitialized);
- writer.Write(m_ShowNameTag);
- writer.Write(m_SayingsEnabled);
- writer.Write(m_SayingsSecondsDelay);
- writer.Write(m_Saying1);
- writer.Write(m_Saying2);
- writer.Write(m_Saying3);
- writer.Write(m_Saying4);
- writer.Write(m_Saying5);
- writer.Write((int)m_CurrentAI);
- writer.Write((int)m_DefaultAI);
- writer.Write((int)m_iRangePerception);
- writer.Write((int)m_iRangeFight);
- writer.Write((int)m_iTeam);
- writer.Write((double)m_dActiveSpeed);
- writer.Write((double)m_dPassiveSpeed);
- writer.Write((double)m_dCurrentSpeed);
- writer.Write((int)m_pHome.X);
- writer.Write((int)m_pHome.Y);
- writer.Write((int)m_pHome.Z);
- // Version 1
- writer.Write((int)m_iRangeHome);
- int i = 0;
- writer.Write((int)m_arSpellAttack.Count);
- for (i = 0; i < m_arSpellAttack.Count; i++)
- {
- writer.Write(m_arSpellAttack[i].ToString());
- }
- writer.Write((int)m_arSpellDefense.Count);
- for (i = 0; i < m_arSpellDefense.Count; i++)
- {
- writer.Write(m_arSpellDefense[i].ToString());
- }
- // Version 2
- writer.Write((int)m_FightMode);
- writer.Write((bool)m_bControled);
- writer.Write((Mobile)m_ControlMaster);
- writer.Write((Mobile)m_ControlTarget);
- writer.Write((Point3D)m_ControlDest);
- writer.Write((int)m_ControlOrder);
- writer.Write((double)m_dMinTameSkill);
- // Removed in version 9
- //writer.Write( (double) m_dMaxTameSkill );
- writer.Write((bool)m_bTamable);
- writer.Write((bool)m_bSummoned);
- if (m_bSummoned)
- writer.WriteDeltaTime(m_SummonEnd);
- writer.Write((int)m_iControlSlots);
- // Version 3
- writer.Write((int)m_Loyalty);
- // Version 4
- writer.Write(m_CurrentWayPoint);
- // Verison 5
- writer.Write(m_SummonMaster);
- // Version 6
- writer.Write((int)m_HitsMax);
- writer.Write((int)m_StamMax);
- writer.Write((int)m_ManaMax);
- writer.Write((int)m_DamageMin);
- writer.Write((int)m_DamageMax);
- // Version 7
- writer.Write((int)m_PhysicalResistance);
- writer.Write((int)m_PhysicalDamage);
- writer.Write((int)m_FireResistance);
- writer.Write((int)m_FireDamage);
- writer.Write((int)m_ColdResistance);
- writer.Write((int)m_ColdDamage);
- writer.Write((int)m_PoisonResistance);
- writer.Write((int)m_PoisonDamage);
- writer.Write((int)m_EnergyResistance);
- writer.Write((int)m_EnergyDamage);
- // Version 8
- writer.WriteMobileList(m_Owners, true);
- // Version 10
- writer.Write((bool)m_IsDeadPet);
- writer.Write((bool)m_IsBonded);
- writer.Write((DateTime)m_BondingBegin);
- writer.Write((DateTime)m_OwnerAbandonTime);
- // Version 11
- writer.Write((bool)m_HasGeneratedLoot);
- // Version 12
- writer.Write((int)Erudition);
- //// Version 13
- //writer.Write((int)m_FearLove.Count);
- //foreach (Mobile mobile in m_FearLove.Keys)
- //{
- // writer.Write((Mobile)mobile);
- // writer.Write((double)m_FearLove[mobile]);
- //}
- //writer.Write((int)m_Hate.Count);
- //foreach (Mobile mobile in m_Hate.Keys)
- //{
- // writer.Write((Mobile)mobile);
- // writer.Write((double)m_Hate[mobile]);
- //}
- }
- private static double[] m_StandardActiveSpeeds = new double[]
- {
- 0.175, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.8
- };
- private static double[] m_StandardPassiveSpeeds = new double[]
- {
- 0.350, 0.2, 0.4, 0.5, 0.6, 0.8, 1.0, 1.2, 1.6, 2.0
- };
- public override void Deserialize(GenericReader reader)
- {
- base.Deserialize(reader);
- int version = reader.ReadInt();
- if (version >= 17)
- {
- m_LootLevel = (LootPackLevel)reader.ReadInt();
- }
- if (version >= 16)
- {
- Frozen = reader.ReadBool();
- }
- if (version >= 15)
- {
- m_IsSystemInitialized = reader.ReadBool();
- }
- if (version >= 14)
- {
- m_ShowNameTag = reader.ReadBool();
- }
- if (version >= 13)
- {
- m_SayingsEnabled = reader.ReadBool();
- m_SayingsSecondsDelay = reader.ReadInt();
- m_Saying1 = reader.ReadString();
- m_Saying2 = reader.ReadString();
- m_Saying3 = reader.ReadString();
- m_Saying4 = reader.ReadString();
- m_Saying5 = reader.ReadString();
- m_SayingsDelay = TimeSpan.FromSeconds(m_SayingsSecondsDelay);
- }
- m_CurrentAI = (AIType)reader.ReadInt();
- m_DefaultAI = (AIType)reader.ReadInt();
- m_iRangePerception = reader.ReadInt();
- m_iRangeFight = reader.ReadInt();
- m_iTeam = reader.ReadInt();
- m_dActiveSpeed = reader.ReadDouble();
- m_dPassiveSpeed = reader.ReadDouble();
- m_dCurrentSpeed = reader.ReadDouble();
- double activeSpeed = m_dActiveSpeed;
- double passiveSpeed = m_dPassiveSpeed;
- SpeedInfo.GetSpeeds(this, ref activeSpeed, ref passiveSpeed);
- bool isStandardActive = false;
- for (int i = 0; !isStandardActive && i < m_StandardActiveSpeeds.Length; ++i)
- isStandardActive = (m_dActiveSpeed == m_StandardActiveSpeeds[i]);
- bool isStandardPassive = false;
- for (int i = 0; !isStandardPassive && i < m_StandardPassiveSpeeds.Length; ++i)
- isStandardPassive = (m_dPassiveSpeed == m_StandardPassiveSpeeds[i]);
- if (isStandardActive && m_dCurrentSpeed == m_dActiveSpeed)
- m_dCurrentSpeed = activeSpeed;
- else if (isStandardPassive && m_dCurrentSpeed == m_dPassiveSpeed)
- m_dCurrentSpeed = passiveSpeed;
- if (isStandardActive)
- m_dActiveSpeed = activeSpeed;
- if (isStandardPassive)
- m_dPassiveSpeed = passiveSpeed;
- if (m_iRangePerception == OldRangePerception)
- m_iRangePerception = DefaultRangePerception;
- m_pHome.X = reader.ReadInt();
- m_pHome.Y = reader.ReadInt();
- m_pHome.Z = reader.ReadInt();
- if (version >= 1)
- {
- m_iRangeHome = reader.ReadInt();
- int i, iCount;
- iCount = reader.ReadInt();
- for (i = 0; i < iCount; i++)
- {
- string str = reader.ReadString();
- Type type = Type.GetType(str);
- if (type != null)
- {
- m_arSpellAttack.Add(type);
- }
- }
- iCount = reader.ReadInt();
- for (i = 0; i < iCount; i++)
- {
- string str = reader.ReadString();
- Type type = Type.GetType(str);
- if (type != null)
- {
- m_arSpellDefense.Add(type);
- }
- }
- }
- else
- {
- m_iRangeHome = 0;
- }
- if (version >= 2)
- {
- m_FightMode = (FightMode)reader.ReadInt();
- m_bControled = reader.ReadBool();
- m_ControlMaster = reader.ReadMobile();
- m_ControlTarget = reader.ReadMobile();
- m_ControlDest = reader.ReadPoint3D();
- m_ControlOrder = (OrderType)reader.ReadInt();
- m_dMinTameSkill = reader.ReadDouble();
- if (version < 9)
- reader.ReadDouble();
- m_bTamable = reader.ReadBool();
- m_bSummoned = reader.ReadBool();
- if (m_bSummoned)
- {
- m_SummonEnd = reader.ReadDeltaTime();
- new UnsummonTimer(m_ControlMaster, this, m_SummonEnd - DateTime.Now).Start();
- }
- m_iControlSlots = reader.ReadInt();
- }
- else
- {
- m_FightMode = FightMode.Closest;
- m_bControled = false;
- m_ControlMaster = null;
- m_ControlTarget = null;
- m_ControlOrder = OrderType.None;
- }
- if (version >= 3)
- m_Loyalty = (PetLoyalty)reader.ReadInt();
- else
- m_Loyalty = PetLoyalty.WonderfullyHappy;
- if (version >= 4)
- m_CurrentWayPoint = reader.ReadItem() as WayPoint;
- if (version >= 5)
- m_SummonMaster = reader.ReadMobile();
- if (version >= 6)
- {
- m_HitsMax = reader.ReadInt();
- m_StamMax = reader.ReadInt();
- m_ManaMax = reader.ReadInt();
- m_DamageMin = reader.ReadInt();
- m_DamageMax = reader.ReadInt();
- }
- if (version >= 7)
- {
- m_PhysicalResistance = reader.ReadInt();
- m_PhysicalDamage = reader.ReadInt();
- m_FireResistance = reader.ReadInt();
- m_FireDamage = reader.ReadInt();
- m_ColdResistance = reader.ReadInt();
- m_ColdDamage = reader.ReadInt();
- m_PoisonResistance = reader.ReadInt();
- m_PoisonDamage = reader.ReadInt();
- m_EnergyResistance = reader.ReadInt();
- m_EnergyDamage = reader.ReadInt();
- }
- if (version >= 8)
- m_Owners = reader.ReadMobileList();
- else
- m_Owners = new ArrayList();
- if (version >= 10)
- {
- m_IsDeadPet = reader.ReadBool();
- m_IsBonded = reader.ReadBool();
- m_BondingBegin = reader.ReadDateTime();
- m_OwnerAbandonTime = reader.ReadDateTime();
- }
- if (version >= 11)
- m_HasGeneratedLoot = reader.ReadBool();
- else
- m_HasGeneratedLoot = true;
- if (version >= 12)
- Erudition = reader.ReadInt();
- else
- Erudition = 0;
- CheckStatTimers();
- ChangeAIType(m_CurrentAI);
- AddFollowers();
- if (IsAnimatedDead)
- Spells.Necromancy.AnimateDeadSpell.Register(m_SummonMaster, this);
- }
- #region Fonction ObjectPropertyList
- public override void AddNameProperties(ObjectPropertyList list)
- {
- base.AddNameProperties(list);
- if (Controled && Commandable)
- {
- if (Summoned)
- list.Add(1049646); // (summoned)
- else if (IsBonded)
- list.Add(1049608); // (bonded)
- else
- list.Add(502006); // (tame)
- }
- }
- public override void GetProperties(ObjectPropertyList list)
- {
- base.GetProperties(list);
- }
- protected int m_Erudition = 0;
- [CommandProperty(AccessLevel.GameMaster)]
- public int Erudition
- {
- get { return m_Erudition; }
- set { m_Erudition = value; }
- }
- public override void SendPropertiesTo(Mobile from)
- {
- ObjectPropertyList opl = new ObjectPropertyList(this);
- string name = Name;
- if (from is RacePlayerMobile && (!(this is BaseVendor)))
- {
- RacePlayerMobile pmf = (RacePlayerMobile)from;
- if (pmf.AccessLevel > AccessLevel.Player)
- {
- // SI GM
- if (pmf.Capacities[CapacityName.Lore].Value < Erudition)
- {//pas érudit
- opl.Add(1050045, "{0} \t{1}\t {2}", "", "Créature", ""); // ~1_PREFIX~~2_NAME~~3_SUFFIX~
- }
- else
- {//Assez érudit
- opl.Add(1050045, "{0} \t{1}\t {2}", "", name, ""); // ~1_PREFIX~~2_NAME~~3_SUFFIX~
- }
- }
- else
- {
- // SI PJ
- if (pmf.Capacities[CapacityName.Lore].Value < Erudition)
- {//pas érudit
- opl.Add(1050045, "{0} \t{1}\t {2}", "", "Créature", ""); // ~1_PREFIX~~2_NAME~~3_SUFFIX~
- }
- else
- {//Assez érudit
- opl.Add(1050045, "{0} \t{1}\t {2}", "", name, ""); // ~1_PREFIX~~2_NAME~~3_SUFFIX~
- }
- }
- }
- //from.Send(opl);
- base.SendPropertiesTo(from);
- }
- private static ArrayList m_Hears;
- private static ArrayList m_OnSpeech;
- private static bool m_NoSpeechLOS1;
- [CommandProperty(AccessLevel.GameMaster)]
- public static bool NoSpeechLOS1 { get { return m_NoSpeechLOS1; } set { m_NoSpeechLOS1 = value; } }
- public override bool CanSee(Mobile m)
- {
- //SendPropertiesTo(this);
- //SendPropertiesTo(m);
- return base.CanSee(m);
- }
- public override void DoSpeech(string text, int[] keywords, MessageType type, int hue)
- {
- // base.DoSpeech(text, keywords, type, hue);
- if (Commands.Handle(this, text))
- return;
- int range = 12;
- switch (type)
- {
- case MessageType.Regular: this.SpeechHue = hue; break;
- case MessageType.Emote: this.EmoteHue = hue; break;
- case MessageType.Whisper: this.WhisperHue = hue; range = 2; break;
- case MessageType.Yell:
- this.YellHue = hue; range = 18;
- range = 18;
- break;
- default: type = MessageType.Regular; break;
- }
- SpeechEventArgs regArgs = new SpeechEventArgs(this, text, type, hue, keywords);
- EventSink.InvokeSpeech(regArgs);
- this…
Large files files are truncated, but you can click here to view the full file