Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
576
Scripts/Services/Factions/Mobiles/Guards/BaseFactionGuard.cs
Normal file
576
Scripts/Services/Factions/Mobiles/Guards/BaseFactionGuard.cs
Normal file
@@ -0,0 +1,576 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.Factions.AI;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public abstract class BaseFactionGuard : BaseCreature
|
||||
{
|
||||
private static readonly Type[] m_StrongPotions = new Type[]
|
||||
{
|
||||
typeof(GreaterHealPotion), typeof(GreaterHealPotion), typeof(GreaterHealPotion),
|
||||
typeof(GreaterCurePotion), typeof(GreaterCurePotion), typeof(GreaterCurePotion),
|
||||
typeof(GreaterStrengthPotion), typeof(GreaterStrengthPotion),
|
||||
typeof(GreaterAgilityPotion), typeof(GreaterAgilityPotion),
|
||||
typeof(TotalRefreshPotion), typeof(TotalRefreshPotion),
|
||||
typeof(GreaterExplosionPotion)
|
||||
};
|
||||
private static readonly Type[] m_WeakPotions = new Type[]
|
||||
{
|
||||
typeof(HealPotion), typeof(HealPotion), typeof(HealPotion),
|
||||
typeof(CurePotion), typeof(CurePotion), typeof(CurePotion),
|
||||
typeof(StrengthPotion), typeof(StrengthPotion),
|
||||
typeof(AgilityPotion), typeof(AgilityPotion),
|
||||
typeof(RefreshPotion), typeof(RefreshPotion),
|
||||
typeof(ExplosionPotion)
|
||||
};
|
||||
private const int ListenRange = 12;
|
||||
private Faction m_Faction;
|
||||
private Town m_Town;
|
||||
private Orders m_Orders;
|
||||
private DateTime m_OrdersEnd;
|
||||
public BaseFactionGuard(string title)
|
||||
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
this.m_Orders = new Orders(this);
|
||||
this.Title = title;
|
||||
|
||||
this.RangeHome = 6;
|
||||
}
|
||||
|
||||
public BaseFactionGuard(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool BardImmune
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public Faction Faction
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Faction;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Unregister();
|
||||
this.m_Faction = value;
|
||||
this.Register();
|
||||
}
|
||||
}
|
||||
public Orders Orders
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Orders;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
|
||||
public Town Town
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Town;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.Unregister();
|
||||
this.m_Town = value;
|
||||
this.Register();
|
||||
}
|
||||
}
|
||||
public abstract GuardAI GuardAI { get; }
|
||||
public override TimeSpan ReacquireDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return TimeSpan.FromSeconds(2.0);
|
||||
}
|
||||
}
|
||||
public override bool ClickTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
protected override BaseAI ForcedAI
|
||||
{
|
||||
get
|
||||
{
|
||||
return new FactionGuardAI(this);
|
||||
}
|
||||
}
|
||||
public void Register()
|
||||
{
|
||||
if (this.m_Town != null && this.m_Faction != null)
|
||||
this.m_Town.RegisterGuard(this);
|
||||
}
|
||||
|
||||
public void Unregister()
|
||||
{
|
||||
if (this.m_Town != null)
|
||||
this.m_Town.UnregisterGuard(this);
|
||||
}
|
||||
|
||||
public override bool IsEnemy(Mobile m)
|
||||
{
|
||||
Faction ourFaction = this.m_Faction;
|
||||
Faction theirFaction = Faction.Find(m);
|
||||
|
||||
if (theirFaction == null && m is BaseFactionGuard)
|
||||
theirFaction = ((BaseFactionGuard)m).Faction;
|
||||
|
||||
if (ourFaction != null && theirFaction != null && ourFaction != theirFaction)
|
||||
{
|
||||
ReactionType reactionType = this.Orders.GetReaction(theirFaction).Type;
|
||||
|
||||
if (reactionType == ReactionType.Attack)
|
||||
return true;
|
||||
|
||||
if (theirFaction != null)
|
||||
{
|
||||
List<AggressorInfo> list = m.Aggressed;
|
||||
|
||||
for (int i = 0; i < list.Count; ++i)
|
||||
{
|
||||
AggressorInfo ai = list[i];
|
||||
|
||||
if (ai.Defender is BaseFactionGuard)
|
||||
{
|
||||
BaseFactionGuard bf = (BaseFactionGuard)ai.Defender;
|
||||
|
||||
if (bf.Faction == ourFaction)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (m.Player && m.Alive && this.InRange(m, 10) && !this.InRange(oldLocation, 10) && this.InLOS(m) && this.m_Orders.GetReaction(Faction.Find(m)).Type == ReactionType.Warn)
|
||||
{
|
||||
this.Direction = this.GetDirectionTo(m);
|
||||
|
||||
string warning = null;
|
||||
|
||||
switch ( Utility.Random(6) )
|
||||
{
|
||||
case 0:
|
||||
warning = "I warn you, {0}, you would do well to leave this area before someone shows you the world of gray.";
|
||||
break;
|
||||
case 1:
|
||||
warning = "It would be wise to leave this area, {0}, lest your head become my commanders' trophy.";
|
||||
break;
|
||||
case 2:
|
||||
warning = "You are bold, {0}, for one of the meager {1}. Leave now, lest you be taught the taste of dirt.";
|
||||
break;
|
||||
case 3:
|
||||
warning = "Your presence here is an insult, {0}. Be gone now, knave.";
|
||||
break;
|
||||
case 4:
|
||||
warning = "Dost thou wish to be hung by your toes, {0}? Nay? Then come no closer.";
|
||||
break;
|
||||
case 5:
|
||||
warning = "Hey, {0}. Yeah, you. Get out of here before I beat you with a stick.";
|
||||
break;
|
||||
}
|
||||
|
||||
Faction faction = Faction.Find(m);
|
||||
|
||||
this.Say(warning, m.Name, faction == null ? "civilians" : faction.Definition.FriendlyName);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HandlesOnSpeech(Mobile from)
|
||||
{
|
||||
if (this.InRange(from, ListenRange))
|
||||
return true;
|
||||
|
||||
return base.HandlesOnSpeech(from);
|
||||
}
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e)
|
||||
{
|
||||
base.OnSpeech(e);
|
||||
|
||||
Mobile from = e.Mobile;
|
||||
|
||||
if (!e.Handled && this.InRange(from, ListenRange) && from.Alive)
|
||||
{
|
||||
if (e.HasKeyword(0xE6) && (Insensitive.Equals(e.Speech, "orders") || this.WasNamed(e.Speech))) // *orders*
|
||||
{
|
||||
if (this.m_Town == null || !this.m_Town.IsSheriff(from))
|
||||
{
|
||||
this.Say(1042189); // I don't work for you!
|
||||
}
|
||||
else if (Town.FromRegion(this.Region) == this.m_Town)
|
||||
{
|
||||
this.Say(1042180); // Your orders, sire?
|
||||
this.m_OrdersEnd = DateTime.UtcNow + TimeSpan.FromSeconds(10.0);
|
||||
}
|
||||
}
|
||||
else if (DateTime.UtcNow < this.m_OrdersEnd)
|
||||
{
|
||||
if (this.m_Town != null && this.m_Town.IsSheriff(from) && Town.FromRegion(this.Region) == this.m_Town)
|
||||
{
|
||||
this.m_OrdersEnd = DateTime.UtcNow + TimeSpan.FromSeconds(10.0);
|
||||
|
||||
bool understood = true;
|
||||
ReactionType newType = 0;
|
||||
|
||||
if (Insensitive.Contains(e.Speech, "attack"))
|
||||
newType = ReactionType.Attack;
|
||||
else if (Insensitive.Contains(e.Speech, "warn"))
|
||||
newType = ReactionType.Warn;
|
||||
else if (Insensitive.Contains(e.Speech, "ignore"))
|
||||
newType = ReactionType.Ignore;
|
||||
else
|
||||
understood = false;
|
||||
|
||||
if (understood)
|
||||
{
|
||||
understood = false;
|
||||
|
||||
if (Insensitive.Contains(e.Speech, "civil"))
|
||||
{
|
||||
this.ChangeReaction(null, newType);
|
||||
understood = true;
|
||||
}
|
||||
|
||||
List<Faction> factions = Faction.Factions;
|
||||
|
||||
for (int i = 0; i < factions.Count; ++i)
|
||||
{
|
||||
Faction faction = factions[i];
|
||||
|
||||
if (faction != this.m_Faction && Insensitive.Contains(e.Speech, faction.Definition.Keyword))
|
||||
{
|
||||
this.ChangeReaction(faction, newType);
|
||||
understood = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Insensitive.Contains(e.Speech, "patrol"))
|
||||
{
|
||||
this.Home = this.Location;
|
||||
this.RangeHome = 6;
|
||||
this.Combatant = null;
|
||||
this.m_Orders.Movement = MovementType.Patrol;
|
||||
this.Say(1005146); // This spot looks like it needs protection! I shall guard it with my life.
|
||||
understood = true;
|
||||
}
|
||||
else if (Insensitive.Contains(e.Speech, "follow"))
|
||||
{
|
||||
this.Home = this.Location;
|
||||
this.RangeHome = 6;
|
||||
this.Combatant = null;
|
||||
this.m_Orders.Follow = from;
|
||||
this.m_Orders.Movement = MovementType.Follow;
|
||||
this.Say(1005144); // Yes, Sire.
|
||||
understood = true;
|
||||
}
|
||||
|
||||
if (!understood)
|
||||
this.Say(1042183); // I'm sorry, I don't understand your orders...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (this.m_Faction != null && this.Map == Faction.Facet)
|
||||
list.Add(1060846, this.m_Faction.Definition.PropName); // Guard: ~1_val~
|
||||
}
|
||||
|
||||
public override void OnSingleClick(Mobile from)
|
||||
{
|
||||
if (this.m_Faction != null && this.Map == Faction.Facet)
|
||||
{
|
||||
string text = String.Concat("(Guard, ", this.m_Faction.Definition.FriendlyName, ")");
|
||||
|
||||
int hue = (Faction.Find(from) == this.m_Faction ? 98 : 38);
|
||||
|
||||
this.PrivateOverheadMessage(MessageType.Label, hue, true, text, from.NetState);
|
||||
}
|
||||
|
||||
base.OnSingleClick(from);
|
||||
}
|
||||
|
||||
public virtual void GenerateRandomHair()
|
||||
{
|
||||
Utility.AssignRandomHair(this);
|
||||
Utility.AssignRandomFacialHair(this, this.HairHue);
|
||||
}
|
||||
|
||||
public void PackStrongPotions(int min, int max)
|
||||
{
|
||||
this.PackStrongPotions(Utility.RandomMinMax(min, max));
|
||||
}
|
||||
|
||||
public void PackStrongPotions(int count)
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
this.PackStrongPotion();
|
||||
}
|
||||
|
||||
public void PackStrongPotion()
|
||||
{
|
||||
this.PackItem(Loot.Construct(m_StrongPotions));
|
||||
}
|
||||
|
||||
public void PackWeakPotions(int min, int max)
|
||||
{
|
||||
this.PackWeakPotions(Utility.RandomMinMax(min, max));
|
||||
}
|
||||
|
||||
public void PackWeakPotions(int count)
|
||||
{
|
||||
for (int i = 0; i < count; ++i)
|
||||
this.PackWeakPotion();
|
||||
}
|
||||
|
||||
public void PackWeakPotion()
|
||||
{
|
||||
this.PackItem(Loot.Construct(m_WeakPotions));
|
||||
}
|
||||
|
||||
public Item Immovable(Item item)
|
||||
{
|
||||
item.Movable = false;
|
||||
return item;
|
||||
}
|
||||
|
||||
public Item Newbied(Item item)
|
||||
{
|
||||
item.LootType = LootType.Newbied;
|
||||
return item;
|
||||
}
|
||||
|
||||
public Item Rehued(Item item, int hue)
|
||||
{
|
||||
item.Hue = hue;
|
||||
return item;
|
||||
}
|
||||
|
||||
public Item Layered(Item item, Layer layer)
|
||||
{
|
||||
item.Layer = layer;
|
||||
return item;
|
||||
}
|
||||
|
||||
public Item Resourced(BaseWeapon weapon, CraftResource resource)
|
||||
{
|
||||
weapon.Resource = resource;
|
||||
return weapon;
|
||||
}
|
||||
|
||||
public Item Resourced(BaseArmor armor, CraftResource resource)
|
||||
{
|
||||
armor.Resource = resource;
|
||||
return armor;
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
base.OnAfterDelete();
|
||||
this.Unregister();
|
||||
}
|
||||
|
||||
public override void OnDeath(Container c)
|
||||
{
|
||||
base.OnDeath(c);
|
||||
|
||||
c.Delete();
|
||||
}
|
||||
|
||||
public virtual void GenerateBody(bool isFemale, bool randomHair)
|
||||
{
|
||||
this.Hue = Utility.RandomSkinHue();
|
||||
|
||||
if (isFemale)
|
||||
{
|
||||
this.Female = true;
|
||||
this.Body = 401;
|
||||
this.Name = NameList.RandomName("female");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Female = false;
|
||||
this.Body = 400;
|
||||
this.Name = NameList.RandomName("male");
|
||||
}
|
||||
|
||||
if (randomHair)
|
||||
this.GenerateRandomHair();
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
Faction.WriteReference(writer, this.m_Faction);
|
||||
Town.WriteReference(writer, this.m_Town);
|
||||
|
||||
this.m_Orders.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_Faction = Faction.ReadReference(reader);
|
||||
this.m_Town = Town.ReadReference(reader);
|
||||
this.m_Orders = new Orders(this, reader);
|
||||
|
||||
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Register));
|
||||
}
|
||||
|
||||
private void ChangeReaction(Faction faction, ReactionType type)
|
||||
{
|
||||
if (faction == null)
|
||||
{
|
||||
switch ( type )
|
||||
{
|
||||
case ReactionType.Ignore:
|
||||
this.Say(1005179);
|
||||
break; // Civilians will now be ignored.
|
||||
case ReactionType.Warn:
|
||||
this.Say(1005180);
|
||||
break; // Civilians will now be warned of their impending deaths.
|
||||
case ReactionType.Attack:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TextDefinition def = null;
|
||||
|
||||
switch ( type )
|
||||
{
|
||||
case ReactionType.Ignore:
|
||||
def = faction.Definition.GuardIgnore;
|
||||
break;
|
||||
case ReactionType.Warn:
|
||||
def = faction.Definition.GuardWarn;
|
||||
break;
|
||||
case ReactionType.Attack:
|
||||
def = faction.Definition.GuardAttack;
|
||||
break;
|
||||
}
|
||||
|
||||
if (def != null && def.Number > 0)
|
||||
this.Say(def.Number);
|
||||
else if (def != null && def.String != null)
|
||||
this.Say(def.String);
|
||||
}
|
||||
|
||||
this.m_Orders.SetReaction(faction, type);
|
||||
}
|
||||
|
||||
private bool WasNamed(string speech)
|
||||
{
|
||||
string name = this.Name;
|
||||
|
||||
return (name != null && Insensitive.StartsWith(speech, name));
|
||||
}
|
||||
}
|
||||
|
||||
public class VirtualMount : IMount
|
||||
{
|
||||
private readonly VirtualMountItem m_Item;
|
||||
public VirtualMount(VirtualMountItem item)
|
||||
{
|
||||
this.m_Item = item;
|
||||
}
|
||||
|
||||
public Mobile Rider
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Item.Rider;
|
||||
}
|
||||
set
|
||||
{
|
||||
}
|
||||
}
|
||||
public virtual void OnRiderDamaged(Mobile from, ref int amount, bool willKill)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class VirtualMountItem : Item, IMountItem
|
||||
{
|
||||
private readonly VirtualMount m_Mount;
|
||||
private Mobile m_Rider;
|
||||
public VirtualMountItem(Mobile mob)
|
||||
: base(0x3EA0)
|
||||
{
|
||||
this.Layer = Layer.Mount;
|
||||
|
||||
this.m_Rider = mob;
|
||||
this.m_Mount = new VirtualMount(this);
|
||||
}
|
||||
|
||||
public VirtualMountItem(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
this.m_Mount = new VirtualMount(this);
|
||||
}
|
||||
|
||||
public Mobile Rider
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Rider;
|
||||
}
|
||||
}
|
||||
public IMount Mount
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Mount;
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
|
||||
writer.Write((Mobile)this.m_Rider);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
this.m_Rider = reader.ReadMobile();
|
||||
|
||||
if (this.m_Rider == null)
|
||||
this.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
921
Scripts/Services/Factions/Mobiles/Guards/GuardAI.cs
Normal file
921
Scripts/Services/Factions/Mobiles/Guards/GuardAI.cs
Normal file
@@ -0,0 +1,921 @@
|
||||
#region References
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server.Factions.AI;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using Server.Spells.Fifth;
|
||||
using Server.Spells.First;
|
||||
using Server.Spells.Fourth;
|
||||
using Server.Spells.Second;
|
||||
using Server.Spells.Seventh;
|
||||
using Server.Spells.Sixth;
|
||||
using Server.Spells.Third;
|
||||
using Server.Targeting;
|
||||
#endregion
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public enum GuardAI
|
||||
{
|
||||
Bless = 0x01, // heal, cure, +stats
|
||||
Curse = 0x02, // poison, -stats
|
||||
Melee = 0x04, // weapons
|
||||
Magic = 0x08, // damage spells
|
||||
Smart = 0x10 // smart weapons/damage spells
|
||||
}
|
||||
|
||||
public class ComboEntry
|
||||
{
|
||||
private readonly Type m_Spell;
|
||||
private readonly TimeSpan m_Hold;
|
||||
private readonly int m_Chance;
|
||||
|
||||
public ComboEntry(Type spell)
|
||||
: this(spell, 100, TimeSpan.Zero)
|
||||
{ }
|
||||
|
||||
public ComboEntry(Type spell, int chance)
|
||||
: this(spell, chance, TimeSpan.Zero)
|
||||
{ }
|
||||
|
||||
public ComboEntry(Type spell, int chance, TimeSpan hold)
|
||||
{
|
||||
m_Spell = spell;
|
||||
m_Chance = chance;
|
||||
m_Hold = hold;
|
||||
}
|
||||
|
||||
public Type Spell { get { return m_Spell; } }
|
||||
public TimeSpan Hold { get { return m_Hold; } }
|
||||
public int Chance { get { return m_Chance; } }
|
||||
}
|
||||
|
||||
public class SpellCombo
|
||||
{
|
||||
public static readonly SpellCombo Simple = new SpellCombo(
|
||||
50,
|
||||
new ComboEntry(typeof(ParalyzeSpell), 20),
|
||||
new ComboEntry(typeof(ExplosionSpell), 100, TimeSpan.FromSeconds(2.8)),
|
||||
new ComboEntry(typeof(PoisonSpell), 30),
|
||||
new ComboEntry(typeof(EnergyBoltSpell)));
|
||||
|
||||
public static readonly SpellCombo Strong = new SpellCombo(
|
||||
90,
|
||||
new ComboEntry(typeof(ParalyzeSpell), 20),
|
||||
new ComboEntry(typeof(ExplosionSpell), 50, TimeSpan.FromSeconds(2.8)),
|
||||
new ComboEntry(typeof(PoisonSpell), 30),
|
||||
new ComboEntry(typeof(ExplosionSpell), 100, TimeSpan.FromSeconds(2.8)),
|
||||
new ComboEntry(typeof(EnergyBoltSpell)),
|
||||
new ComboEntry(typeof(PoisonSpell), 30),
|
||||
new ComboEntry(typeof(EnergyBoltSpell)));
|
||||
|
||||
private readonly int m_Mana;
|
||||
private readonly ComboEntry[] m_Entries;
|
||||
|
||||
public SpellCombo(int mana, params ComboEntry[] entries)
|
||||
{
|
||||
m_Mana = mana;
|
||||
m_Entries = entries;
|
||||
}
|
||||
|
||||
public int Mana { get { return m_Mana; } }
|
||||
public ComboEntry[] Entries { get { return m_Entries; } }
|
||||
|
||||
public static Spell Process(Mobile mob, Mobile targ, ref SpellCombo combo, ref int index, ref DateTime releaseTime)
|
||||
{
|
||||
while (++index < combo.m_Entries.Length)
|
||||
{
|
||||
ComboEntry entry = combo.m_Entries[index];
|
||||
|
||||
if (entry.Spell == typeof(PoisonSpell) && targ.Poisoned)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.Chance > Utility.Random(100))
|
||||
{
|
||||
releaseTime = DateTime.UtcNow + entry.Hold;
|
||||
return (Spell)Activator.CreateInstance(entry.Spell, new object[] {mob, null});
|
||||
}
|
||||
}
|
||||
|
||||
combo = null;
|
||||
index = -1;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public class FactionGuardAI : BaseAI
|
||||
{
|
||||
private const int ManaReserve = 30;
|
||||
private readonly BaseFactionGuard m_Guard;
|
||||
private BandageContext m_Bandage;
|
||||
private DateTime m_BandageStart;
|
||||
private SpellCombo m_Combo;
|
||||
private int m_ComboIndex = -1;
|
||||
private DateTime m_ReleaseTarget;
|
||||
|
||||
public FactionGuardAI(BaseFactionGuard guard)
|
||||
: base(guard)
|
||||
{
|
||||
m_Guard = guard;
|
||||
}
|
||||
|
||||
public bool IsDamaged { get { return (m_Guard.Hits < m_Guard.HitsMax); } }
|
||||
public bool IsPoisoned { get { return m_Guard.Poisoned; } }
|
||||
|
||||
public TimeSpan TimeUntilBandage
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Bandage != null && m_Bandage.Timer == null)
|
||||
{
|
||||
m_Bandage = null;
|
||||
}
|
||||
|
||||
if (m_Bandage == null)
|
||||
{
|
||||
return TimeSpan.MaxValue;
|
||||
}
|
||||
|
||||
TimeSpan ts = (m_BandageStart + m_Bandage.Timer.Delay) - DateTime.UtcNow;
|
||||
|
||||
if (ts < TimeSpan.FromSeconds(-1.0))
|
||||
{
|
||||
m_Bandage = null;
|
||||
return TimeSpan.MaxValue;
|
||||
}
|
||||
|
||||
if (ts < TimeSpan.Zero)
|
||||
{
|
||||
ts = TimeSpan.Zero;
|
||||
}
|
||||
|
||||
return ts;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsAllowed(GuardAI flag)
|
||||
{
|
||||
return ((m_Guard.GuardAI & flag) == flag);
|
||||
}
|
||||
|
||||
public bool DequipWeapon()
|
||||
{
|
||||
Container pack = m_Guard.Backpack;
|
||||
|
||||
if (pack == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Item weapon = m_Guard.Weapon as Item;
|
||||
|
||||
if (weapon != null && weapon.Parent == m_Guard && !(weapon is Fists))
|
||||
{
|
||||
pack.DropItem(weapon);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool EquipWeapon()
|
||||
{
|
||||
Container pack = m_Guard.Backpack;
|
||||
|
||||
if (pack == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Item weapon = pack.FindItemByType(typeof(BaseWeapon));
|
||||
|
||||
if (weapon == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_Guard.EquipItem(weapon);
|
||||
}
|
||||
|
||||
public bool StartBandage()
|
||||
{
|
||||
m_Bandage = null;
|
||||
|
||||
Container pack = m_Guard.Backpack;
|
||||
|
||||
if (pack == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Item bandage = pack.FindItemByType(typeof(Bandage));
|
||||
|
||||
if (bandage == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_Bandage = BandageContext.BeginHeal(m_Guard, m_Guard);
|
||||
m_BandageStart = DateTime.UtcNow;
|
||||
return (m_Bandage != null);
|
||||
}
|
||||
|
||||
public bool UseItemByType(Type type)
|
||||
{
|
||||
Container pack = m_Guard.Backpack;
|
||||
|
||||
if (pack == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Item item = pack.FindItemByType(type);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool requip = DequipWeapon();
|
||||
|
||||
item.OnDoubleClick(m_Guard);
|
||||
|
||||
if (requip)
|
||||
{
|
||||
EquipWeapon();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public int GetStatMod(Mobile mob, StatType type)
|
||||
{
|
||||
int offset = 0;
|
||||
StatMod buff = mob.GetStatMod(String.Format("[Magic] {0} Buff", type));
|
||||
StatMod curse = mob.GetStatMod(String.Format("[Magic] {0} Curse", type));
|
||||
|
||||
if (buff != null)
|
||||
offset += buff.Offset;
|
||||
if (curse != null)
|
||||
offset += curse.Offset;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
public Spell RandomOffenseSpell()
|
||||
{
|
||||
int maxCircle = (int)((m_Guard.Skills.Magery.Value + 20.0) / (100.0 / 7.0));
|
||||
|
||||
if (maxCircle < 1)
|
||||
{
|
||||
maxCircle = 1;
|
||||
}
|
||||
|
||||
switch (Utility.Random(maxCircle * 2))
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
return new MagicArrowSpell(m_Guard, null);
|
||||
case 2:
|
||||
case 3:
|
||||
return new HarmSpell(m_Guard, null);
|
||||
case 4:
|
||||
case 5:
|
||||
return new FireballSpell(m_Guard, null);
|
||||
case 6:
|
||||
case 7:
|
||||
return new LightningSpell(m_Guard, null);
|
||||
case 8:
|
||||
return new MindBlastSpell(m_Guard, null);
|
||||
case 9:
|
||||
return new ParalyzeSpell(m_Guard, null);
|
||||
case 10:
|
||||
return new EnergyBoltSpell(m_Guard, null);
|
||||
case 11:
|
||||
return new ExplosionSpell(m_Guard, null);
|
||||
default:
|
||||
return new FlameStrikeSpell(m_Guard, null);
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile FindDispelTarget(bool activeOnly)
|
||||
{
|
||||
if (m_Mobile.Deleted || m_Mobile.Int < 95 || CanDispel(m_Mobile) || m_Mobile.AutoDispel)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (activeOnly)
|
||||
{
|
||||
var aggressed = m_Mobile.Aggressed;
|
||||
var aggressors = m_Mobile.Aggressors;
|
||||
|
||||
Mobile active = null;
|
||||
double activePrio = 0.0;
|
||||
|
||||
Mobile comb = m_Mobile.Combatant as Mobile;
|
||||
|
||||
if (comb != null && !comb.Deleted && comb.Alive && !comb.IsDeadBondedPet && m_Mobile.InRange(comb, 12) &&
|
||||
CanDispel(comb))
|
||||
{
|
||||
active = comb;
|
||||
activePrio = m_Mobile.GetDistanceToSqrt(comb);
|
||||
|
||||
if (activePrio <= 2)
|
||||
{
|
||||
return active;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < aggressed.Count; ++i)
|
||||
{
|
||||
AggressorInfo info = aggressed[i];
|
||||
Mobile m = info.Defender;
|
||||
|
||||
if (m != comb && m.Combatant == m_Mobile && m_Mobile.InRange(m, 12) && CanDispel(m))
|
||||
{
|
||||
double prio = m_Mobile.GetDistanceToSqrt(m);
|
||||
|
||||
if (active == null || prio < activePrio)
|
||||
{
|
||||
active = m;
|
||||
activePrio = prio;
|
||||
|
||||
if (activePrio <= 2)
|
||||
{
|
||||
return active;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < aggressors.Count; ++i)
|
||||
{
|
||||
AggressorInfo info = aggressors[i];
|
||||
Mobile m = info.Attacker;
|
||||
|
||||
if (m != comb && m.Combatant == m_Mobile && m_Mobile.InRange(m, 12) && CanDispel(m))
|
||||
{
|
||||
double prio = m_Mobile.GetDistanceToSqrt(m);
|
||||
|
||||
if (active == null || prio < activePrio)
|
||||
{
|
||||
active = m;
|
||||
activePrio = prio;
|
||||
|
||||
if (activePrio <= 2)
|
||||
{
|
||||
return active;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return active;
|
||||
}
|
||||
else
|
||||
{
|
||||
Map map = m_Mobile.Map;
|
||||
|
||||
if (map != null)
|
||||
{
|
||||
Mobile active = null, inactive = null;
|
||||
double actPrio = 0.0, inactPrio = 0.0;
|
||||
|
||||
Mobile comb = m_Mobile.Combatant as Mobile;
|
||||
|
||||
if (comb != null && !comb.Deleted && comb.Alive && !comb.IsDeadBondedPet && CanDispel(comb))
|
||||
{
|
||||
active = inactive = comb;
|
||||
actPrio = inactPrio = m_Mobile.GetDistanceToSqrt(comb);
|
||||
}
|
||||
|
||||
IPooledEnumerable eable = m_Mobile.GetMobilesInRange(12);
|
||||
|
||||
foreach (Mobile m in eable)
|
||||
{
|
||||
if (m != m_Mobile && CanDispel(m))
|
||||
{
|
||||
double prio = m_Mobile.GetDistanceToSqrt(m);
|
||||
|
||||
if (!activeOnly && (inactive == null || prio < inactPrio))
|
||||
{
|
||||
inactive = m;
|
||||
inactPrio = prio;
|
||||
}
|
||||
|
||||
if ((m_Mobile.Combatant == m || m.Combatant == m_Mobile) && (active == null || prio < actPrio))
|
||||
{
|
||||
active = m;
|
||||
actPrio = prio;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
return active != null ? active : inactive;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool CanDispel(Mobile m)
|
||||
{
|
||||
return (m is BaseCreature && ((BaseCreature)m).Summoned && m_Mobile.CanBeHarmful(m, false) &&
|
||||
!((BaseCreature)m).IsAnimatedDead);
|
||||
}
|
||||
|
||||
public void RunTo(Mobile m)
|
||||
{
|
||||
/*if ( m.Paralyzed || m.Frozen )
|
||||
{
|
||||
if ( m_Mobile.InRange( m, 1 ) )
|
||||
RunFrom( m );
|
||||
else if ( !m_Mobile.InRange( m, m_Mobile.RangeFight > 2 ? m_Mobile.RangeFight : 2 ) && !MoveTo( m, true, 1 ) )
|
||||
OnFailedMove();
|
||||
}
|
||||
else
|
||||
{*/
|
||||
if (!m_Mobile.InRange(m, m_Mobile.RangeFight))
|
||||
{
|
||||
if (!MoveTo(m, true, 1))
|
||||
{
|
||||
OnFailedMove();
|
||||
}
|
||||
}
|
||||
else if (m_Mobile.InRange(m, m_Mobile.RangeFight - 1))
|
||||
{
|
||||
RunFrom(m);
|
||||
}
|
||||
/*}*/
|
||||
}
|
||||
|
||||
public void RunFrom(Mobile m)
|
||||
{
|
||||
Run((Direction)((int)m_Mobile.GetDirectionTo(m) - 4) & Direction.Mask);
|
||||
}
|
||||
|
||||
public void OnFailedMove()
|
||||
{
|
||||
/*if ( !m_Mobile.DisallowAllMoves && 20 > Utility.Random( 100 ) && IsAllowed( GuardAI.Magic ) )
|
||||
{
|
||||
if ( m_Mobile.Target != null )
|
||||
m_Mobile.Target.Cancel( m_Mobile, TargetCancelType.Canceled );
|
||||
new TeleportSpell( m_Mobile, null ).Cast();
|
||||
m_Mobile.DebugSay( "I am stuck, I'm going to try teleporting away" );
|
||||
}
|
||||
else*/
|
||||
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
|
||||
{
|
||||
if (m_Mobile.Debug)
|
||||
{
|
||||
m_Mobile.DebugSay("My move is blocked, so I am going to attack {0}", m_Mobile.FocusMob.Name);
|
||||
}
|
||||
|
||||
m_Mobile.Combatant = m_Mobile.FocusMob;
|
||||
Action = ActionType.Combat;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mobile.DebugSay("I am stuck");
|
||||
}
|
||||
}
|
||||
|
||||
public void Run(Direction d)
|
||||
{
|
||||
if ((m_Mobile.Spell != null && m_Mobile.Spell.IsCasting) || m_Mobile.Paralyzed || m_Mobile.Frozen ||
|
||||
m_Mobile.DisallowAllMoves)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Mobile.Direction = d | Direction.Running;
|
||||
|
||||
if (!DoMove(m_Mobile.Direction, true))
|
||||
{
|
||||
OnFailedMove();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool Think()
|
||||
{
|
||||
if (m_Mobile.Deleted)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Mobile combatant = m_Guard.Combatant as Mobile;
|
||||
|
||||
if (combatant == null || combatant.Deleted || !combatant.Alive || combatant.IsDeadBondedPet ||
|
||||
!m_Mobile.CanSee(combatant) || !m_Mobile.CanBeHarmful(combatant, false) || combatant.Map != m_Mobile.Map)
|
||||
{
|
||||
// Our combatant is deleted, dead, hidden, or we cannot hurt them
|
||||
// Try to find another combatant
|
||||
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
|
||||
{
|
||||
m_Mobile.Combatant = combatant = m_Mobile.FocusMob as Mobile;
|
||||
m_Mobile.FocusMob = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Mobile.Combatant = combatant = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (combatant != null && (!m_Mobile.InLOS(combatant) || !m_Mobile.InRange(combatant, 12)))
|
||||
{
|
||||
if (AcquireFocusMob(m_Mobile.RangePerception, m_Mobile.FightMode, false, false, true))
|
||||
{
|
||||
m_Mobile.Combatant = combatant = m_Mobile.FocusMob as Mobile;
|
||||
m_Mobile.FocusMob = null;
|
||||
}
|
||||
else if (!m_Mobile.InRange(combatant, 36))
|
||||
{
|
||||
m_Mobile.Combatant = combatant = null;
|
||||
}
|
||||
}
|
||||
|
||||
Mobile dispelTarget = FindDispelTarget(true);
|
||||
|
||||
if (m_Guard.Target != null && m_ReleaseTarget == DateTime.MinValue)
|
||||
{
|
||||
m_ReleaseTarget = DateTime.UtcNow + TimeSpan.FromSeconds(10.0);
|
||||
}
|
||||
|
||||
if (m_Guard.Target != null && DateTime.UtcNow > m_ReleaseTarget)
|
||||
{
|
||||
Target targ = m_Guard.Target;
|
||||
|
||||
Mobile toHarm = (dispelTarget == null ? combatant : dispelTarget);
|
||||
|
||||
if ((targ.Flags & TargetFlags.Harmful) != 0 && toHarm != null)
|
||||
{
|
||||
if (m_Guard.Map == toHarm.Map && (targ.Range < 0 || m_Guard.InRange(toHarm, targ.Range)) && m_Guard.CanSee(toHarm) &&
|
||||
m_Guard.InLOS(toHarm))
|
||||
{
|
||||
targ.Invoke(m_Guard, toHarm);
|
||||
}
|
||||
else if (targ is DispelSpell.InternalTarget)
|
||||
{
|
||||
targ.Cancel(m_Guard, TargetCancelType.Canceled);
|
||||
}
|
||||
}
|
||||
else if ((targ.Flags & TargetFlags.Beneficial) != 0)
|
||||
{
|
||||
targ.Invoke(m_Guard, m_Guard);
|
||||
}
|
||||
else
|
||||
{
|
||||
targ.Cancel(m_Guard, TargetCancelType.Canceled);
|
||||
}
|
||||
|
||||
m_ReleaseTarget = DateTime.MinValue;
|
||||
}
|
||||
|
||||
if (dispelTarget != null)
|
||||
{
|
||||
if (Action != ActionType.Combat)
|
||||
{
|
||||
Action = ActionType.Combat;
|
||||
}
|
||||
|
||||
m_Guard.Warmode = true;
|
||||
|
||||
RunFrom(dispelTarget);
|
||||
}
|
||||
else if (combatant != null)
|
||||
{
|
||||
if (Action != ActionType.Combat)
|
||||
{
|
||||
Action = ActionType.Combat;
|
||||
}
|
||||
|
||||
m_Guard.Warmode = true;
|
||||
|
||||
RunTo(combatant);
|
||||
}
|
||||
else if (m_Guard.Orders.Movement != MovementType.Stand)
|
||||
{
|
||||
Mobile toFollow = null;
|
||||
|
||||
if (m_Guard.Town != null && m_Guard.Orders.Movement == MovementType.Follow)
|
||||
{
|
||||
toFollow = m_Guard.Orders.Follow;
|
||||
|
||||
if (toFollow == null)
|
||||
{
|
||||
toFollow = m_Guard.Town.Sheriff;
|
||||
}
|
||||
}
|
||||
|
||||
if (toFollow != null && toFollow.Map == m_Guard.Map && toFollow.InRange(m_Guard, m_Guard.RangePerception * 3) &&
|
||||
Town.FromRegion(toFollow.Region) == m_Guard.Town)
|
||||
{
|
||||
if (Action != ActionType.Combat)
|
||||
{
|
||||
Action = ActionType.Combat;
|
||||
}
|
||||
|
||||
if (m_Mobile.CurrentSpeed != m_Mobile.ActiveSpeed)
|
||||
{
|
||||
m_Mobile.CurrentSpeed = m_Mobile.ActiveSpeed;
|
||||
}
|
||||
|
||||
m_Guard.Warmode = true;
|
||||
|
||||
RunTo(toFollow);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Action != ActionType.Wander)
|
||||
{
|
||||
Action = ActionType.Wander;
|
||||
}
|
||||
|
||||
if (m_Mobile.CurrentSpeed != m_Mobile.PassiveSpeed)
|
||||
{
|
||||
m_Mobile.CurrentSpeed = m_Mobile.PassiveSpeed;
|
||||
}
|
||||
|
||||
m_Guard.Warmode = false;
|
||||
|
||||
WalkRandomInHome(2, 2, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Action != ActionType.Wander)
|
||||
{
|
||||
Action = ActionType.Wander;
|
||||
}
|
||||
|
||||
m_Guard.Warmode = false;
|
||||
}
|
||||
|
||||
if ((IsDamaged || IsPoisoned) && m_Guard.Skills.Healing.Base > 20.0)
|
||||
{
|
||||
TimeSpan ts = TimeUntilBandage;
|
||||
|
||||
if (ts == TimeSpan.MaxValue)
|
||||
{
|
||||
StartBandage();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_Mobile.Spell == null && Core.TickCount >= m_Mobile.NextSpellTime)
|
||||
{
|
||||
Spell spell = null;
|
||||
|
||||
DateTime toRelease = DateTime.MinValue;
|
||||
|
||||
if (IsPoisoned)
|
||||
{
|
||||
Poison p = m_Guard.Poison;
|
||||
|
||||
TimeSpan ts = TimeUntilBandage;
|
||||
|
||||
if (p != Poison.Lesser || ts == TimeSpan.MaxValue || TimeUntilBandage < TimeSpan.FromSeconds(1.5) ||
|
||||
(m_Guard.HitsMax - m_Guard.Hits) > Utility.Random(250))
|
||||
{
|
||||
if (IsAllowed(GuardAI.Bless))
|
||||
{
|
||||
spell = new CureSpell(m_Guard, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
UseItemByType(typeof(BaseCurePotion));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IsDamaged && (m_Guard.HitsMax - m_Guard.Hits) > Utility.Random(200))
|
||||
{
|
||||
if (IsAllowed(GuardAI.Magic) && ((m_Guard.Hits * 100) / Math.Max(m_Guard.HitsMax, 1)) < 10 &&
|
||||
m_Guard.Home != Point3D.Zero && !Utility.InRange(m_Guard.Location, m_Guard.Home, 15) && m_Guard.Mana >= 11)
|
||||
{
|
||||
spell = new RecallSpell(m_Guard, null, new RunebookEntry(m_Guard.Home, m_Guard.Map, "Guard's Home", null, RecallRuneType.Normal), null);
|
||||
}
|
||||
else if (IsAllowed(GuardAI.Bless))
|
||||
{
|
||||
if (m_Guard.Mana >= 11 && (m_Guard.Hits + 30) < m_Guard.HitsMax)
|
||||
{
|
||||
spell = new GreaterHealSpell(m_Guard, null);
|
||||
}
|
||||
else if ((m_Guard.Hits + 10) < m_Guard.HitsMax &&
|
||||
(m_Guard.Mana < 11 || (m_Guard.NextCombatTime - Core.TickCount) > 2000))
|
||||
{
|
||||
spell = new HealSpell(m_Guard, null);
|
||||
}
|
||||
}
|
||||
else if (m_Guard.CanBeginAction(typeof(BaseHealPotion)))
|
||||
{
|
||||
UseItemByType(typeof(BaseHealPotion));
|
||||
}
|
||||
}
|
||||
else if (dispelTarget != null && (IsAllowed(GuardAI.Magic) || IsAllowed(GuardAI.Bless) || IsAllowed(GuardAI.Curse)))
|
||||
{
|
||||
if (!dispelTarget.Paralyzed && m_Guard.Mana > (ManaReserve + 20) && 40 > Utility.Random(100))
|
||||
{
|
||||
spell = new ParalyzeSpell(m_Guard, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
spell = new DispelSpell(m_Guard, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (combatant != null)
|
||||
{
|
||||
if (m_Combo != null)
|
||||
{
|
||||
if (spell == null)
|
||||
{
|
||||
spell = SpellCombo.Process(m_Guard, combatant, ref m_Combo, ref m_ComboIndex, ref toRelease);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Combo = null;
|
||||
m_ComboIndex = -1;
|
||||
}
|
||||
}
|
||||
else if (20 > Utility.Random(100) && IsAllowed(GuardAI.Magic))
|
||||
{
|
||||
if (80 > Utility.Random(100))
|
||||
{
|
||||
m_Combo = (IsAllowed(GuardAI.Smart) ? SpellCombo.Simple : SpellCombo.Strong);
|
||||
m_ComboIndex = -1;
|
||||
|
||||
if (m_Guard.Mana >= (ManaReserve + m_Combo.Mana))
|
||||
{
|
||||
spell = SpellCombo.Process(m_Guard, combatant, ref m_Combo, ref m_ComboIndex, ref toRelease);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Combo = null;
|
||||
|
||||
if (m_Guard.Mana >= (ManaReserve + 40))
|
||||
{
|
||||
spell = RandomOffenseSpell();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_Guard.Mana >= (ManaReserve + 40))
|
||||
{
|
||||
spell = RandomOffenseSpell();
|
||||
}
|
||||
}
|
||||
|
||||
if (spell == null && 2 > Utility.Random(100) && m_Guard.Mana >= (ManaReserve + 10))
|
||||
{
|
||||
int strMod = GetStatMod(m_Guard, StatType.Str);
|
||||
int dexMod = GetStatMod(m_Guard, StatType.Dex);
|
||||
int intMod = GetStatMod(m_Guard, StatType.Int);
|
||||
|
||||
var types = new List<Type>();
|
||||
|
||||
if (strMod <= 0)
|
||||
{
|
||||
types.Add(typeof(StrengthSpell));
|
||||
}
|
||||
|
||||
if (dexMod <= 0 && IsAllowed(GuardAI.Melee))
|
||||
{
|
||||
types.Add(typeof(AgilitySpell));
|
||||
}
|
||||
|
||||
if (intMod <= 0 && IsAllowed(GuardAI.Magic))
|
||||
{
|
||||
types.Add(typeof(CunningSpell));
|
||||
}
|
||||
|
||||
if (IsAllowed(GuardAI.Bless))
|
||||
{
|
||||
if (types.Count > 1)
|
||||
{
|
||||
spell = new BlessSpell(m_Guard, null);
|
||||
}
|
||||
else if (types.Count == 1)
|
||||
{
|
||||
spell = (Spell)Activator.CreateInstance(types[0], new object[] {m_Guard, null});
|
||||
}
|
||||
}
|
||||
else if (types.Count > 0)
|
||||
{
|
||||
if (types[0] == typeof(StrengthSpell))
|
||||
{
|
||||
UseItemByType(typeof(BaseStrengthPotion));
|
||||
}
|
||||
else if (types[0] == typeof(AgilitySpell))
|
||||
{
|
||||
UseItemByType(typeof(BaseAgilityPotion));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (spell == null && 2 > Utility.Random(100) && m_Guard.Mana >= (ManaReserve + 10) && IsAllowed(GuardAI.Curse))
|
||||
{
|
||||
if (!combatant.Poisoned && 40 > Utility.Random(100))
|
||||
{
|
||||
spell = new PoisonSpell(m_Guard, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
int strMod = GetStatMod(combatant, StatType.Str);
|
||||
int dexMod = GetStatMod(combatant, StatType.Dex);
|
||||
int intMod = GetStatMod(combatant, StatType.Int);
|
||||
|
||||
var types = new List<Type>();
|
||||
|
||||
if (strMod >= 0)
|
||||
{
|
||||
types.Add(typeof(WeakenSpell));
|
||||
}
|
||||
|
||||
if (dexMod >= 0 && IsAllowed(GuardAI.Melee))
|
||||
{
|
||||
types.Add(typeof(ClumsySpell));
|
||||
}
|
||||
|
||||
if (intMod >= 0 && IsAllowed(GuardAI.Magic))
|
||||
{
|
||||
types.Add(typeof(FeeblemindSpell));
|
||||
}
|
||||
|
||||
if (types.Count > 1)
|
||||
{
|
||||
spell = new CurseSpell(m_Guard, null);
|
||||
}
|
||||
else if (types.Count == 1)
|
||||
{
|
||||
spell = (Spell)Activator.CreateInstance(types[0], new object[] {m_Guard, null});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (spell != null && (m_Guard.HitsMax - m_Guard.Hits + 10) > Utility.Random(100))
|
||||
{
|
||||
Type type = null;
|
||||
|
||||
if (spell is GreaterHealSpell)
|
||||
{
|
||||
type = typeof(BaseHealPotion);
|
||||
}
|
||||
else if (spell is CureSpell)
|
||||
{
|
||||
type = typeof(BaseCurePotion);
|
||||
}
|
||||
else if (spell is StrengthSpell)
|
||||
{
|
||||
type = typeof(BaseStrengthPotion);
|
||||
}
|
||||
else if (spell is AgilitySpell)
|
||||
{
|
||||
type = typeof(BaseAgilityPotion);
|
||||
}
|
||||
|
||||
if (type == typeof(BaseHealPotion) && !m_Guard.CanBeginAction(type))
|
||||
{
|
||||
type = null;
|
||||
}
|
||||
|
||||
if (type != null && m_Guard.Target == null && UseItemByType(type))
|
||||
{
|
||||
if (spell is GreaterHealSpell)
|
||||
{
|
||||
if ((m_Guard.Hits + 30) > m_Guard.HitsMax && (m_Guard.Hits + 10) < m_Guard.HitsMax)
|
||||
{
|
||||
spell = new HealSpell(m_Guard, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
spell = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (spell == null && m_Guard.Stam < (m_Guard.StamMax / 3) && IsAllowed(GuardAI.Melee))
|
||||
{
|
||||
UseItemByType(typeof(BaseRefreshPotion));
|
||||
}
|
||||
|
||||
if (spell == null || !spell.Cast())
|
||||
{
|
||||
EquipWeapon();
|
||||
}
|
||||
}
|
||||
else if (m_Mobile.Spell is Spell && ((Spell)m_Mobile.Spell).State == SpellState.Sequencing)
|
||||
{
|
||||
EquipWeapon();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
182
Scripts/Services/Factions/Mobiles/Guards/Orders.cs
Normal file
182
Scripts/Services/Factions/Mobiles/Guards/Orders.cs
Normal file
@@ -0,0 +1,182 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Factions.AI
|
||||
{
|
||||
public enum ReactionType
|
||||
{
|
||||
Ignore,
|
||||
Warn,
|
||||
Attack
|
||||
}
|
||||
|
||||
public enum MovementType
|
||||
{
|
||||
Stand,
|
||||
Patrol,
|
||||
Follow
|
||||
}
|
||||
|
||||
public class Reaction
|
||||
{
|
||||
private readonly Faction m_Faction;
|
||||
private ReactionType m_Type;
|
||||
public Reaction(Faction faction, ReactionType type)
|
||||
{
|
||||
this.m_Faction = faction;
|
||||
this.m_Type = type;
|
||||
}
|
||||
|
||||
public Reaction(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
this.m_Faction = Faction.ReadReference(reader);
|
||||
this.m_Type = (ReactionType)reader.ReadEncodedInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Faction Faction
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Faction;
|
||||
}
|
||||
}
|
||||
public ReactionType Type
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Type;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Type = value;
|
||||
}
|
||||
}
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt((int)0); // version
|
||||
|
||||
Faction.WriteReference(writer, this.m_Faction);
|
||||
writer.WriteEncodedInt((int)this.m_Type);
|
||||
}
|
||||
}
|
||||
|
||||
public class Orders
|
||||
{
|
||||
private readonly BaseFactionGuard m_Guard;
|
||||
private readonly List<Reaction> m_Reactions;
|
||||
private MovementType m_Movement;
|
||||
private Mobile m_Follow;
|
||||
public Orders(BaseFactionGuard guard)
|
||||
{
|
||||
this.m_Guard = guard;
|
||||
this.m_Reactions = new List<Reaction>();
|
||||
this.m_Movement = MovementType.Patrol;
|
||||
}
|
||||
|
||||
public Orders(BaseFactionGuard guard, GenericReader reader)
|
||||
{
|
||||
this.m_Guard = guard;
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
this.m_Follow = reader.ReadMobile();
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
int count = reader.ReadEncodedInt();
|
||||
this.m_Reactions = new List<Reaction>(count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
this.m_Reactions.Add(new Reaction(reader));
|
||||
|
||||
this.m_Movement = (MovementType)reader.ReadEncodedInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public BaseFactionGuard Guard
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Guard;
|
||||
}
|
||||
}
|
||||
public MovementType Movement
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Movement;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Movement = value;
|
||||
}
|
||||
}
|
||||
public Mobile Follow
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Follow;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Follow = value;
|
||||
}
|
||||
}
|
||||
public Reaction GetReaction(Faction faction)
|
||||
{
|
||||
Reaction reaction;
|
||||
|
||||
for (int i = 0; i < this.m_Reactions.Count; ++i)
|
||||
{
|
||||
reaction = this.m_Reactions[i];
|
||||
|
||||
if (reaction.Faction == faction)
|
||||
return reaction;
|
||||
}
|
||||
|
||||
reaction = new Reaction(faction, (faction == null || faction == this.m_Guard.Faction) ? ReactionType.Ignore : ReactionType.Attack);
|
||||
this.m_Reactions.Add(reaction);
|
||||
|
||||
return reaction;
|
||||
}
|
||||
|
||||
public void SetReaction(Faction faction, ReactionType type)
|
||||
{
|
||||
Reaction reaction = this.GetReaction(faction);
|
||||
|
||||
reaction.Type = type;
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.WriteEncodedInt((int)1); // version
|
||||
|
||||
writer.Write((Mobile)this.m_Follow);
|
||||
|
||||
writer.WriteEncodedInt((int)this.m_Reactions.Count);
|
||||
|
||||
for (int i = 0; i < this.m_Reactions.Count; ++i)
|
||||
this.m_Reactions[i].Serialize(writer);
|
||||
|
||||
writer.WriteEncodedInt((int)this.m_Movement);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionBerserker : BaseFactionGuard
|
||||
{
|
||||
[Constructable]
|
||||
public FactionBerserker()
|
||||
: base("the berserker")
|
||||
{
|
||||
this.GenerateBody(false, false);
|
||||
|
||||
this.SetStr(126, 150);
|
||||
this.SetDex(61, 85);
|
||||
this.SetInt(81, 95);
|
||||
|
||||
this.SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 30, 50);
|
||||
this.SetResistance(ResistanceType.Fire, 30, 50);
|
||||
this.SetResistance(ResistanceType.Cold, 30, 50);
|
||||
this.SetResistance(ResistanceType.Energy, 30, 50);
|
||||
this.SetResistance(ResistanceType.Poison, 30, 50);
|
||||
|
||||
this.VirtualArmor = 24;
|
||||
|
||||
this.SetSkill(SkillName.Swords, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Wrestling, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Tactics, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.MagicResist, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Healing, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Anatomy, 100.0, 110.0);
|
||||
|
||||
this.SetSkill(SkillName.Magery, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.EvalInt, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Meditation, 100.0, 110.0);
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(new BodySash(), 1645)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new Kilt(), 1645)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new Sandals(), 1645)));
|
||||
this.AddItem(this.Newbied(new DoubleAxe()));
|
||||
|
||||
this.HairItemID = 0x2047; // Afro
|
||||
this.HairHue = 0x29;
|
||||
|
||||
this.FacialHairItemID = 0x204B; // Medium Short Beard
|
||||
this.FacialHairHue = 0x29;
|
||||
|
||||
this.PackItem(new Bandage(Utility.RandomMinMax(30, 40)));
|
||||
this.PackStrongPotions(6, 12);
|
||||
}
|
||||
|
||||
public FactionBerserker(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override GuardAI GuardAI
|
||||
{
|
||||
get
|
||||
{
|
||||
return GuardAI.Melee | GuardAI.Curse | GuardAI.Bless;
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionDeathKnight : BaseFactionGuard
|
||||
{
|
||||
[Constructable]
|
||||
public FactionDeathKnight()
|
||||
: base("the death knight")
|
||||
{
|
||||
this.GenerateBody(false, false);
|
||||
this.Hue = 1;
|
||||
|
||||
this.SetStr(126, 150);
|
||||
this.SetDex(61, 85);
|
||||
this.SetInt(81, 95);
|
||||
|
||||
this.SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 30, 50);
|
||||
this.SetResistance(ResistanceType.Fire, 30, 50);
|
||||
this.SetResistance(ResistanceType.Cold, 30, 50);
|
||||
this.SetResistance(ResistanceType.Energy, 30, 50);
|
||||
this.SetResistance(ResistanceType.Poison, 30, 50);
|
||||
|
||||
this.VirtualArmor = 24;
|
||||
|
||||
this.SetSkill(SkillName.Swords, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Wrestling, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Tactics, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.MagicResist, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Healing, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Anatomy, 100.0, 110.0);
|
||||
|
||||
this.SetSkill(SkillName.Magery, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.EvalInt, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Meditation, 100.0, 110.0);
|
||||
|
||||
Item shroud = new Item(0x204E);
|
||||
shroud.Layer = Layer.OuterTorso;
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(shroud, 1109)));
|
||||
this.AddItem(this.Newbied(this.Rehued(new ExecutionersAxe(), 2211)));
|
||||
|
||||
this.PackItem(new Bandage(Utility.RandomMinMax(30, 40)));
|
||||
this.PackStrongPotions(6, 12);
|
||||
}
|
||||
|
||||
public FactionDeathKnight(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override GuardAI GuardAI
|
||||
{
|
||||
get
|
||||
{
|
||||
return GuardAI.Melee | GuardAI.Curse | GuardAI.Bless;
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionDragoon : BaseFactionGuard
|
||||
{
|
||||
[Constructable]
|
||||
public FactionDragoon()
|
||||
: base("the dragoon")
|
||||
{
|
||||
this.GenerateBody(false, false);
|
||||
|
||||
this.SetStr(151, 175);
|
||||
this.SetDex(61, 85);
|
||||
this.SetInt(151, 175);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 40, 60);
|
||||
this.SetResistance(ResistanceType.Fire, 40, 60);
|
||||
this.SetResistance(ResistanceType.Cold, 40, 60);
|
||||
this.SetResistance(ResistanceType.Energy, 40, 60);
|
||||
this.SetResistance(ResistanceType.Poison, 40, 60);
|
||||
|
||||
this.VirtualArmor = 32;
|
||||
|
||||
this.SetSkill(SkillName.Macing, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Wrestling, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Tactics, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.MagicResist, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Healing, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Anatomy, 110.0, 120.0);
|
||||
|
||||
this.SetSkill(SkillName.Magery, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.EvalInt, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Meditation, 110.0, 120.0);
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(new Cloak(), 1645)));
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateChest(), 1645)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateLegs(), 1109)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateArms(), 1109)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateGloves(), 1109)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateGorget(), 1109)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateHelm(), 1109)));
|
||||
|
||||
this.AddItem(this.Newbied(new WarHammer()));
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(new VirtualMountItem(this), 1109)));
|
||||
|
||||
this.PackItem(new Bandage(Utility.RandomMinMax(30, 40)));
|
||||
this.PackStrongPotions(6, 12);
|
||||
}
|
||||
|
||||
public FactionDragoon(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override GuardAI GuardAI
|
||||
{
|
||||
get
|
||||
{
|
||||
return GuardAI.Magic | GuardAI.Melee | GuardAI.Smart | GuardAI.Bless | GuardAI.Curse;
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionHenchman : BaseFactionGuard
|
||||
{
|
||||
[Constructable]
|
||||
public FactionHenchman()
|
||||
: base("the henchman")
|
||||
{
|
||||
this.GenerateBody(false, true);
|
||||
|
||||
this.SetStr(91, 115);
|
||||
this.SetDex(61, 85);
|
||||
this.SetInt(81, 95);
|
||||
|
||||
this.SetDamage(10, 14);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 10, 30);
|
||||
this.SetResistance(ResistanceType.Fire, 10, 30);
|
||||
this.SetResistance(ResistanceType.Cold, 10, 30);
|
||||
this.SetResistance(ResistanceType.Energy, 10, 30);
|
||||
this.SetResistance(ResistanceType.Poison, 10, 30);
|
||||
|
||||
this.VirtualArmor = 8;
|
||||
|
||||
this.SetSkill(SkillName.Fencing, 80.0, 90.0);
|
||||
this.SetSkill(SkillName.Wrestling, 80.0, 90.0);
|
||||
this.SetSkill(SkillName.Tactics, 80.0, 90.0);
|
||||
this.SetSkill(SkillName.MagicResist, 80.0, 90.0);
|
||||
this.SetSkill(SkillName.Healing, 80.0, 90.0);
|
||||
this.SetSkill(SkillName.Anatomy, 80.0, 90.0);
|
||||
|
||||
this.AddItem(new StuddedChest());
|
||||
this.AddItem(new StuddedLegs());
|
||||
this.AddItem(new StuddedArms());
|
||||
this.AddItem(new StuddedGloves());
|
||||
this.AddItem(new StuddedGorget());
|
||||
this.AddItem(new Boots());
|
||||
this.AddItem(this.Newbied(new Spear()));
|
||||
|
||||
this.PackItem(new Bandage(Utility.RandomMinMax(10, 20)));
|
||||
this.PackWeakPotions(1, 4);
|
||||
}
|
||||
|
||||
public FactionHenchman(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override GuardAI GuardAI
|
||||
{
|
||||
get
|
||||
{
|
||||
return GuardAI.Melee;
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionKnight : BaseFactionGuard
|
||||
{
|
||||
[Constructable]
|
||||
public FactionKnight()
|
||||
: base("the knight")
|
||||
{
|
||||
this.GenerateBody(false, false);
|
||||
|
||||
this.SetStr(126, 150);
|
||||
this.SetDex(61, 85);
|
||||
this.SetInt(81, 95);
|
||||
|
||||
this.SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 30, 50);
|
||||
this.SetResistance(ResistanceType.Fire, 30, 50);
|
||||
this.SetResistance(ResistanceType.Cold, 30, 50);
|
||||
this.SetResistance(ResistanceType.Energy, 30, 50);
|
||||
this.SetResistance(ResistanceType.Poison, 30, 50);
|
||||
|
||||
this.VirtualArmor = 24;
|
||||
|
||||
this.SetSkill(SkillName.Swords, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Wrestling, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Tactics, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.MagicResist, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Healing, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Anatomy, 100.0, 110.0);
|
||||
|
||||
this.SetSkill(SkillName.Magery, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.EvalInt, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Meditation, 100.0, 110.0);
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(new ChainChest(), 2125)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new ChainLegs(), 2125)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new ChainCoif(), 2125)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateArms(), 2125)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateGloves(), 2125)));
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(new BodySash(), 1254)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new Kilt(), 1254)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new Sandals(), 1254)));
|
||||
|
||||
this.AddItem(this.Newbied(new Bardiche()));
|
||||
|
||||
this.PackItem(new Bandage(Utility.RandomMinMax(30, 40)));
|
||||
this.PackStrongPotions(6, 12);
|
||||
}
|
||||
|
||||
public FactionKnight(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override GuardAI GuardAI
|
||||
{
|
||||
get
|
||||
{
|
||||
return GuardAI.Magic | GuardAI.Melee | GuardAI.Smart | GuardAI.Curse | GuardAI.Bless;
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionMercenary : BaseFactionGuard
|
||||
{
|
||||
[Constructable]
|
||||
public FactionMercenary()
|
||||
: base("the mercenary")
|
||||
{
|
||||
this.GenerateBody(false, true);
|
||||
|
||||
this.SetStr(116, 125);
|
||||
this.SetDex(61, 85);
|
||||
this.SetInt(81, 95);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 20, 40);
|
||||
this.SetResistance(ResistanceType.Fire, 20, 40);
|
||||
this.SetResistance(ResistanceType.Cold, 20, 40);
|
||||
this.SetResistance(ResistanceType.Energy, 20, 40);
|
||||
this.SetResistance(ResistanceType.Poison, 20, 40);
|
||||
|
||||
this.VirtualArmor = 16;
|
||||
|
||||
this.SetSkill(SkillName.Fencing, 90.0, 100.0);
|
||||
this.SetSkill(SkillName.Wrestling, 90.0, 100.0);
|
||||
this.SetSkill(SkillName.Tactics, 90.0, 100.0);
|
||||
this.SetSkill(SkillName.MagicResist, 90.0, 100.0);
|
||||
this.SetSkill(SkillName.Healing, 90.0, 100.0);
|
||||
this.SetSkill(SkillName.Anatomy, 90.0, 100.0);
|
||||
|
||||
this.AddItem(new ChainChest());
|
||||
this.AddItem(new ChainLegs());
|
||||
this.AddItem(new RingmailArms());
|
||||
this.AddItem(new RingmailGloves());
|
||||
this.AddItem(new ChainCoif());
|
||||
this.AddItem(new Boots());
|
||||
this.AddItem(this.Newbied(new ShortSpear()));
|
||||
|
||||
this.PackItem(new Bandage(Utility.RandomMinMax(20, 30)));
|
||||
this.PackStrongPotions(3, 8);
|
||||
}
|
||||
|
||||
public FactionMercenary(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override GuardAI GuardAI
|
||||
{
|
||||
get
|
||||
{
|
||||
return GuardAI.Melee | GuardAI.Smart;
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionNecromancer : BaseFactionGuard
|
||||
{
|
||||
[Constructable]
|
||||
public FactionNecromancer()
|
||||
: base("the necromancer")
|
||||
{
|
||||
this.GenerateBody(false, false);
|
||||
this.Hue = 1;
|
||||
|
||||
this.SetStr(151, 175);
|
||||
this.SetDex(61, 85);
|
||||
this.SetInt(151, 175);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 40, 60);
|
||||
this.SetResistance(ResistanceType.Fire, 40, 60);
|
||||
this.SetResistance(ResistanceType.Cold, 40, 60);
|
||||
this.SetResistance(ResistanceType.Energy, 40, 60);
|
||||
this.SetResistance(ResistanceType.Poison, 40, 60);
|
||||
|
||||
this.VirtualArmor = 32;
|
||||
|
||||
this.SetSkill(SkillName.Macing, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Wrestling, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Tactics, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.MagicResist, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Healing, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Anatomy, 110.0, 120.0);
|
||||
|
||||
this.SetSkill(SkillName.Magery, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.EvalInt, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Meditation, 110.0, 120.0);
|
||||
|
||||
Item shroud = new Item(0x204E);
|
||||
shroud.Layer = Layer.OuterTorso;
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(shroud, 1109)));
|
||||
this.AddItem(this.Newbied(this.Rehued(new GnarledStaff(), 2211)));
|
||||
|
||||
this.PackItem(new Bandage(Utility.RandomMinMax(30, 40)));
|
||||
this.PackStrongPotions(6, 12);
|
||||
}
|
||||
|
||||
public FactionNecromancer(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override GuardAI GuardAI
|
||||
{
|
||||
get
|
||||
{
|
||||
return GuardAI.Magic | GuardAI.Smart | GuardAI.Bless | GuardAI.Curse;
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionPaladin : BaseFactionGuard
|
||||
{
|
||||
[Constructable]
|
||||
public FactionPaladin()
|
||||
: base("the paladin")
|
||||
{
|
||||
this.GenerateBody(false, false);
|
||||
|
||||
this.SetStr(151, 175);
|
||||
this.SetDex(61, 85);
|
||||
this.SetInt(81, 95);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 40, 60);
|
||||
this.SetResistance(ResistanceType.Fire, 40, 60);
|
||||
this.SetResistance(ResistanceType.Cold, 40, 60);
|
||||
this.SetResistance(ResistanceType.Energy, 40, 60);
|
||||
this.SetResistance(ResistanceType.Poison, 40, 60);
|
||||
|
||||
this.VirtualArmor = 32;
|
||||
|
||||
this.SetSkill(SkillName.Swords, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Wrestling, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Tactics, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.MagicResist, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Healing, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Anatomy, 110.0, 120.0);
|
||||
|
||||
this.SetSkill(SkillName.Magery, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.EvalInt, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Meditation, 110.0, 120.0);
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateChest(), 2125)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateLegs(), 2125)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateHelm(), 2125)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateGorget(), 2125)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateArms(), 2125)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new PlateGloves(), 2125)));
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(new BodySash(), 1254)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new Cloak(), 1254)));
|
||||
|
||||
this.AddItem(this.Newbied(new Halberd()));
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(new VirtualMountItem(this), 1254)));
|
||||
|
||||
this.PackItem(new Bandage(Utility.RandomMinMax(30, 40)));
|
||||
this.PackStrongPotions(6, 12);
|
||||
}
|
||||
|
||||
public FactionPaladin(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override GuardAI GuardAI
|
||||
{
|
||||
get
|
||||
{
|
||||
return GuardAI.Magic | GuardAI.Melee | GuardAI.Smart | GuardAI.Curse | GuardAI.Bless;
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionSorceress : BaseFactionGuard
|
||||
{
|
||||
[Constructable]
|
||||
public FactionSorceress()
|
||||
: base("the sorceress")
|
||||
{
|
||||
this.GenerateBody(true, false);
|
||||
|
||||
this.SetStr(126, 150);
|
||||
this.SetDex(61, 85);
|
||||
this.SetInt(126, 150);
|
||||
|
||||
this.SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 30, 50);
|
||||
this.SetResistance(ResistanceType.Fire, 30, 50);
|
||||
this.SetResistance(ResistanceType.Cold, 30, 50);
|
||||
this.SetResistance(ResistanceType.Energy, 30, 50);
|
||||
this.SetResistance(ResistanceType.Poison, 30, 50);
|
||||
|
||||
this.VirtualArmor = 24;
|
||||
|
||||
this.SetSkill(SkillName.Macing, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Wrestling, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Tactics, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.MagicResist, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Healing, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Anatomy, 100.0, 110.0);
|
||||
|
||||
this.SetSkill(SkillName.Magery, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.EvalInt, 100.0, 110.0);
|
||||
this.SetSkill(SkillName.Meditation, 100.0, 110.0);
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(new WizardsHat(), 1325)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new Sandals(), 1325)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new LeatherGorget(), 1325)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new LeatherGloves(), 1325)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new LeatherLegs(), 1325)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new Skirt(), 1325)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new FemaleLeatherChest(), 1325)));
|
||||
this.AddItem(this.Newbied(this.Rehued(new QuarterStaff(), 1310)));
|
||||
|
||||
this.PackItem(new Bandage(Utility.RandomMinMax(30, 40)));
|
||||
this.PackStrongPotions(6, 12);
|
||||
}
|
||||
|
||||
public FactionSorceress(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override GuardAI GuardAI
|
||||
{
|
||||
get
|
||||
{
|
||||
return GuardAI.Magic | GuardAI.Bless | GuardAI.Curse;
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionWizard : BaseFactionGuard
|
||||
{
|
||||
[Constructable]
|
||||
public FactionWizard()
|
||||
: base("the wizard")
|
||||
{
|
||||
this.GenerateBody(false, false);
|
||||
|
||||
this.SetStr(151, 175);
|
||||
this.SetDex(61, 85);
|
||||
this.SetInt(151, 175);
|
||||
|
||||
this.SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
this.SetResistance(ResistanceType.Physical, 40, 60);
|
||||
this.SetResistance(ResistanceType.Fire, 40, 60);
|
||||
this.SetResistance(ResistanceType.Cold, 40, 60);
|
||||
this.SetResistance(ResistanceType.Energy, 40, 60);
|
||||
this.SetResistance(ResistanceType.Poison, 40, 60);
|
||||
|
||||
this.VirtualArmor = 32;
|
||||
|
||||
this.SetSkill(SkillName.Macing, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Wrestling, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Tactics, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.MagicResist, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Healing, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Anatomy, 110.0, 120.0);
|
||||
|
||||
this.SetSkill(SkillName.Magery, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.EvalInt, 110.0, 120.0);
|
||||
this.SetSkill(SkillName.Meditation, 110.0, 120.0);
|
||||
|
||||
this.AddItem(this.Immovable(this.Rehued(new WizardsHat(), 1325)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new Sandals(), 1325)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new Robe(), 1310)));
|
||||
this.AddItem(this.Immovable(this.Rehued(new LeatherGloves(), 1325)));
|
||||
this.AddItem(this.Newbied(this.Rehued(new GnarledStaff(), 1310)));
|
||||
|
||||
this.PackItem(new Bandage(Utility.RandomMinMax(30, 40)));
|
||||
this.PackStrongPotions(6, 12);
|
||||
}
|
||||
|
||||
public FactionWizard(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override GuardAI GuardAI
|
||||
{
|
||||
get
|
||||
{
|
||||
return GuardAI.Magic | GuardAI.Smart | GuardAI.Bless | GuardAI.Curse;
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user