Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
// When this attachment is deleted, the object that it is attached to will be deleted as well.
|
||||
// The quest system will automatically delete these attachments after a quest is completed.
|
||||
// Specifying an expiration time will also allow you to give objects limited lifetimes.
|
||||
public class TemporaryQuestObject : XmlAttachment, ITemporaryQuestAttachment
|
||||
{
|
||||
|
||||
private Mobile m_QuestOwner;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Mobile QuestOwner
|
||||
{
|
||||
get {return m_QuestOwner;}
|
||||
set {m_QuestOwner = value;}
|
||||
}
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public TemporaryQuestObject(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public TemporaryQuestObject(string questname)
|
||||
{
|
||||
Name = questname;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public TemporaryQuestObject(string questname, double expiresin)
|
||||
{
|
||||
Name = questname;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public TemporaryQuestObject(string questname, double expiresin, Mobile questowner)
|
||||
{
|
||||
Name = questname;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
QuestOwner = questowner;
|
||||
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
// delete the object that it is attached to
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
// dont allow deletion of players
|
||||
if(!((Mobile)AttachedTo).Player)
|
||||
{
|
||||
SafeMobileDelete((Mobile)AttachedTo);
|
||||
//((Mobile)AttachedTo).Delete();
|
||||
}
|
||||
}
|
||||
else
|
||||
if(AttachedTo is Item)
|
||||
{
|
||||
SafeItemDelete((Item)AttachedTo);
|
||||
//((Item)AttachedTo).Delete();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
|
||||
// version 0
|
||||
writer.Write(m_QuestOwner);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
// version 0
|
||||
m_QuestOwner = reader.ReadMobile();
|
||||
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{1} expires in {0} mins",Expiration.TotalMinutes, Name);
|
||||
} else
|
||||
{
|
||||
return String.Format("{1}: QuestOwner {0}",QuestOwner, Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using System.Collections;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlAddFame : XmlAttachment
|
||||
{
|
||||
private int m_DataValue; // default data
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Value { get{ return m_DataValue; } set { m_DataValue = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlAddFame(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlAddFame( int value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(m_DataValue);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_DataValue = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod
|
||||
if(AttachedTo is PlayerMobile)
|
||||
{
|
||||
// for players just add it immediately
|
||||
((Mobile)AttachedTo).Fame += Value;
|
||||
|
||||
((Mobile)AttachedTo).SendMessage("Receive {0}",OnIdentify((Mobile)AttachedTo));
|
||||
|
||||
// and then remove the attachment
|
||||
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Delete));
|
||||
//Delete();
|
||||
}
|
||||
else
|
||||
if(AttachedTo is Item)
|
||||
{
|
||||
// dont allow item attachments
|
||||
Delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override bool HandlesOnKilled { get { return true; } }
|
||||
|
||||
public override void OnKilled(Mobile killed, Mobile killer )
|
||||
{
|
||||
base.OnKilled(killed, killer);
|
||||
|
||||
if(killer == null) return;
|
||||
|
||||
killer.Fame += Value;
|
||||
|
||||
killer.SendMessage("Receive {0}",OnIdentify(killer));
|
||||
}
|
||||
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
|
||||
return String.Format("{0} Fame", Value);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using System.Collections;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlAddKarma : XmlAttachment
|
||||
{
|
||||
private int m_DataValue; // default data
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Value { get{ return m_DataValue; } set { m_DataValue = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlAddKarma(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlAddKarma( int value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(m_DataValue);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_DataValue = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod
|
||||
if(AttachedTo is PlayerMobile)
|
||||
{
|
||||
// for players just add it immediately
|
||||
((Mobile)AttachedTo).Karma += Value;
|
||||
|
||||
((Mobile)AttachedTo).SendMessage("Receive {0}",OnIdentify((Mobile)AttachedTo));
|
||||
|
||||
// and then remove the attachment
|
||||
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Delete));
|
||||
//Delete();
|
||||
}
|
||||
else
|
||||
if(AttachedTo is Item)
|
||||
{
|
||||
// dont allow item attachments
|
||||
Delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override bool HandlesOnKilled { get { return true; } }
|
||||
|
||||
public override void OnKilled(Mobile killed, Mobile killer )
|
||||
{
|
||||
base.OnKilled(killed, killer);
|
||||
|
||||
if(killer == null) return;
|
||||
|
||||
killer.Karma += Value;
|
||||
|
||||
killer.SendMessage("Receive {0}",OnIdentify(killer));
|
||||
}
|
||||
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
|
||||
return String.Format("{0} Karma", Value);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using System.Collections;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlAddTithing : XmlAttachment
|
||||
{
|
||||
private int m_DataValue; // default data
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Value { get{ return m_DataValue; } set { m_DataValue = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlAddTithing(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlAddTithing( int value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(m_DataValue);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_DataValue = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod
|
||||
if(AttachedTo is PlayerMobile)
|
||||
{
|
||||
// for players just add it immediately
|
||||
((Mobile)AttachedTo).TithingPoints += Value;
|
||||
|
||||
((Mobile)AttachedTo).SendMessage("Receive {0}",OnIdentify((Mobile)AttachedTo));
|
||||
|
||||
// and then remove the attachment
|
||||
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Delete));
|
||||
//Delete();
|
||||
}
|
||||
else
|
||||
if(AttachedTo is Item)
|
||||
{
|
||||
// dont allow item attachments
|
||||
Delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override bool HandlesOnKilled { get { return true; } }
|
||||
|
||||
public override void OnKilled(Mobile killed, Mobile killer )
|
||||
{
|
||||
base.OnKilled(killed, killer);
|
||||
|
||||
if(killer == null) return;
|
||||
|
||||
killer.TithingPoints += Value;
|
||||
|
||||
killer.SendMessage("Receive {0}",OnIdentify(killer));
|
||||
}
|
||||
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
|
||||
return String.Format("{0} TithingPoints", Value);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using System.Collections;
|
||||
|
||||
using Server.Services.Virtues;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlAddVirtue : XmlAttachment
|
||||
{
|
||||
private int m_DataValue; // default data
|
||||
private string m_Virtue;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Value { get{ return m_DataValue; } set { m_DataValue = value; } }
|
||||
public string Virtue { get{ return m_Virtue; } set { m_Virtue = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlAddVirtue(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlAddVirtue(string virtue, int value)
|
||||
{
|
||||
Value = value;
|
||||
Virtue = virtue;
|
||||
}
|
||||
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(m_DataValue);
|
||||
writer.Write(m_Virtue);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_DataValue = reader.ReadInt();
|
||||
m_Virtue = reader.ReadString();
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod
|
||||
if(AttachedTo is PlayerMobile)
|
||||
{
|
||||
// for players just add it immediately
|
||||
// lookup the virtue type
|
||||
VirtueName g = (VirtueName)0;
|
||||
bool valid = true;
|
||||
bool gainedPath = false;
|
||||
try{
|
||||
g = (VirtueName)Enum.Parse(typeof(VirtueName),Virtue, true);
|
||||
} catch{valid = false;}
|
||||
|
||||
if(valid)
|
||||
{
|
||||
|
||||
VirtueHelper.Award( (Mobile)AttachedTo, g, Value, ref gainedPath );
|
||||
|
||||
((Mobile)AttachedTo).SendMessage("Receive {0}",OnIdentify((Mobile)AttachedTo));
|
||||
|
||||
if(gainedPath)
|
||||
{
|
||||
((Mobile)AttachedTo).SendMessage("You have gained a path in {0}",Virtue);
|
||||
}
|
||||
} else
|
||||
{
|
||||
((Mobile)AttachedTo).SendMessage("{0}: no such Virtue", Virtue);
|
||||
}
|
||||
// and then remove the attachment
|
||||
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Delete));
|
||||
//Delete();
|
||||
} else
|
||||
if(AttachedTo is Item)
|
||||
{
|
||||
// dont allow item attachments
|
||||
Delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override bool HandlesOnKilled { get { return true; } }
|
||||
|
||||
public override void OnKilled(Mobile killed, Mobile killer )
|
||||
{
|
||||
base.OnKilled(killed, killer);
|
||||
|
||||
if(killer == null) return;
|
||||
|
||||
VirtueName g = (VirtueName)0;
|
||||
bool valid = true;
|
||||
bool gainedPath = false;
|
||||
try{
|
||||
g = (VirtueName)Enum.Parse(typeof(VirtueName),Virtue, true);
|
||||
} catch{valid = false;}
|
||||
|
||||
if(valid)
|
||||
{
|
||||
// give the killer the Virtue
|
||||
|
||||
VirtueHelper.Award( killer, g, Value, ref gainedPath );
|
||||
|
||||
if(gainedPath)
|
||||
{
|
||||
killer.SendMessage("You have gained a path in {0}",Virtue);
|
||||
}
|
||||
|
||||
killer.SendMessage("Receive {0}",OnIdentify(killer));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
|
||||
return String.Format("{0} {1} Virtue points", Value, Virtue);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,451 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlAnimate : XmlAttachment
|
||||
{
|
||||
private int m_AnimationValue = 0;// default animation
|
||||
private int m_FrameCount = 7;// default framecount
|
||||
private int m_RepeatCount = 1;// default repeatcount
|
||||
private int m_AnimationDelay = 0;// default animation delay
|
||||
private bool m_Repeat = false;// default repeat
|
||||
private bool m_Forward = true;// default animation direction
|
||||
private string m_ActivationWord = null;// no word activation by default
|
||||
private TimeSpan m_Refractory = TimeSpan.FromSeconds(5);// 5 seconds default time between activations
|
||||
private DateTime m_EndTime;
|
||||
private int m_ProximityRange = 5;// default movement activation from 5 tiles away
|
||||
private LoopTimer m_Timer;
|
||||
private int m_LoopCount = 0;// repeat animations using a timed loop
|
||||
private int m_LoopDelay = 5;// interval in seconds between loop ticks
|
||||
private int m_CurrentCount = 0;
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlAnimate(ASerial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlAnimate()
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlAnimate(int animation)
|
||||
{
|
||||
this.AnimationValue = animation;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlAnimate(int animation, double refractory)
|
||||
{
|
||||
this.AnimationValue = animation;
|
||||
this.Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlAnimate(int animation, int framecount, double refractory)
|
||||
{
|
||||
this.AnimationValue = animation;
|
||||
this.FrameCount = framecount;
|
||||
this.Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlAnimate(int animation, double refractory, int loopcount, int loopdelay)
|
||||
{
|
||||
this.LoopCount = loopcount;
|
||||
this.LoopDelay = loopdelay;
|
||||
this.AnimationValue = animation;
|
||||
this.Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlAnimate(int animation, int framecount, double refractory, int loopcount, int loopdelay)
|
||||
{
|
||||
this.LoopCount = loopcount;
|
||||
this.LoopDelay = loopdelay;
|
||||
this.AnimationValue = animation;
|
||||
this.FrameCount = framecount;
|
||||
this.Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int ProximityRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_ProximityRange;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_ProximityRange = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int FrameCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_FrameCount;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_FrameCount = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int RepeatCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_RepeatCount;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_RepeatCount = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int AnimationDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_AnimationDelay;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_AnimationDelay = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Repeat
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Repeat;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Repeat = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Forward
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Forward;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Forward = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int AnimationValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_AnimationValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_AnimationValue = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string ActivationWord
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_ActivationWord;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_ActivationWord = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan Refractory
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Refractory;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Refractory = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int LoopCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_LoopCount;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_LoopCount = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int LoopDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_LoopDelay;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_LoopDelay = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int CurrentCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_CurrentCount;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_CurrentCount = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool DoAnimate
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == true)
|
||||
this.OnTrigger(null, null);
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool DoReset
|
||||
{
|
||||
get
|
||||
{
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == true)
|
||||
this.Reset();
|
||||
}
|
||||
}
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
public override bool HandlesOnSpeech
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.ActivationWord != null);
|
||||
}
|
||||
}
|
||||
public override bool HandlesOnMovement
|
||||
{
|
||||
get
|
||||
{
|
||||
return (this.ProximityRange >= 0 && this.ActivationWord == null);
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0);
|
||||
// version 0
|
||||
writer.Write(this.m_CurrentCount);
|
||||
writer.Write(this.m_LoopCount);
|
||||
writer.Write(this.m_LoopDelay);
|
||||
writer.Write(this.m_ProximityRange);
|
||||
writer.Write(this.m_AnimationValue);
|
||||
writer.Write(this.m_FrameCount);
|
||||
writer.Write(this.m_RepeatCount);
|
||||
writer.Write(this.m_AnimationDelay);
|
||||
writer.Write(this.m_Forward);
|
||||
writer.Write(this.m_Repeat);
|
||||
writer.Write(this.m_ActivationWord);
|
||||
writer.Write(this.m_Refractory);
|
||||
writer.Write(this.m_EndTime - DateTime.UtcNow);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
// version 0
|
||||
this.m_CurrentCount = reader.ReadInt();
|
||||
this.m_LoopCount = reader.ReadInt();
|
||||
this.m_LoopDelay = reader.ReadInt();
|
||||
this.m_ProximityRange = reader.ReadInt();
|
||||
this.m_AnimationValue = reader.ReadInt();
|
||||
this.m_FrameCount = reader.ReadInt();
|
||||
this.m_RepeatCount = reader.ReadInt();
|
||||
this.m_AnimationDelay = reader.ReadInt();
|
||||
this.m_Forward = reader.ReadBool();
|
||||
this.m_Repeat = reader.ReadBool();
|
||||
this.m_ActivationWord = reader.ReadString();
|
||||
this.m_Refractory = reader.ReadTimeSpan();
|
||||
TimeSpan remaining = reader.ReadTimeSpan();
|
||||
this.m_EndTime = DateTime.UtcNow + remaining;
|
||||
break;
|
||||
}
|
||||
|
||||
// restart any animation loops that were active
|
||||
if (this.CurrentCount > 0)
|
||||
{
|
||||
this.DoTimer(TimeSpan.FromSeconds(this.LoopDelay));
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if (from == null || from.AccessLevel < AccessLevel.Counselor)
|
||||
return null;
|
||||
|
||||
string msg = String.Format("Animation #{0},{1} : {2} secs between uses", this.AnimationValue, this.FrameCount, this.Refractory.TotalSeconds);
|
||||
|
||||
if (this.ActivationWord == null)
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{0} : trigger on '{1}'", msg, this.ActivationWord);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e)
|
||||
{
|
||||
base.OnSpeech(e);
|
||||
|
||||
if (e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player)
|
||||
return;
|
||||
|
||||
if (e.Speech == this.ActivationWord)
|
||||
{
|
||||
this.OnTrigger(null, e.Mobile);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnMovement(MovementEventArgs e)
|
||||
{
|
||||
base.OnMovement(e);
|
||||
|
||||
if (e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player)
|
||||
return;
|
||||
|
||||
if (this.AttachedTo is Item && (((Item)this.AttachedTo).Parent == null) && Utility.InRange(e.Mobile.Location, ((Item)this.AttachedTo).Location, this.ProximityRange))
|
||||
{
|
||||
this.OnTrigger(null, e.Mobile);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// only attach to mobiles
|
||||
if (!(this.AttachedTo is Mobile))
|
||||
{
|
||||
this.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if (this.m_Timer != null)
|
||||
this.m_Timer.Stop();
|
||||
|
||||
this.CurrentCount = 0;
|
||||
this.m_EndTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
public void Animate()
|
||||
{
|
||||
// play a animation
|
||||
if (this.AttachedTo is Mobile && this.AnimationValue >= 0)
|
||||
{
|
||||
((Mobile)this.AttachedTo).Animate(this.AnimationValue, this.FrameCount, this.RepeatCount, this.Forward, this.Repeat, this.AnimationDelay);
|
||||
}
|
||||
|
||||
this.UpdateRefractory();
|
||||
|
||||
this.CurrentCount--;
|
||||
}
|
||||
|
||||
public void UpdateRefractory()
|
||||
{
|
||||
this.m_EndTime = DateTime.UtcNow + this.Refractory;
|
||||
}
|
||||
|
||||
public override void OnTrigger(object activator, Mobile m)
|
||||
{
|
||||
if (DateTime.UtcNow < this.m_EndTime)
|
||||
return;
|
||||
|
||||
if (this.LoopCount > 0)
|
||||
{
|
||||
this.CurrentCount = this.LoopCount;
|
||||
// check to make sure the timer is running
|
||||
this.DoTimer(TimeSpan.FromSeconds(this.LoopDelay));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Animate();
|
||||
}
|
||||
}
|
||||
|
||||
private void DoTimer(TimeSpan delay)
|
||||
{
|
||||
if (this.m_Timer != null)
|
||||
this.m_Timer.Stop();
|
||||
|
||||
this.m_Timer = new LoopTimer(this, delay);
|
||||
this.m_Timer.Start();
|
||||
}
|
||||
|
||||
private class LoopTimer : Timer
|
||||
{
|
||||
public readonly TimeSpan m_delay;
|
||||
private readonly XmlAnimate m_attachment;
|
||||
public LoopTimer(XmlAnimate attachment, TimeSpan delay)
|
||||
: base(delay, delay)
|
||||
{
|
||||
this.Priority = TimerPriority.OneSecond;
|
||||
|
||||
this.m_attachment = attachment;
|
||||
this.m_delay = delay;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if (this.m_attachment != null && !this.m_attachment.Deleted)
|
||||
{
|
||||
this.m_attachment.Animate();
|
||||
|
||||
if (this.m_attachment.CurrentCount <= 0)
|
||||
this.Stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlData : XmlAttachment
|
||||
{
|
||||
private string m_DataValue = null; // default data
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Data { get{ return m_DataValue; } set { m_DataValue = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlData(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlData(string name)
|
||||
{
|
||||
Name = name;
|
||||
Data = String.Empty;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlData(string name, string data)
|
||||
{
|
||||
Name = name;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlData(string name, string data, double expiresin)
|
||||
{
|
||||
Name = name;
|
||||
Data = data;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write((string)m_DataValue);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_DataValue = reader.ReadString();
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{2}: Data {0} expires in {1} mins",Data,Expiration.TotalMinutes, Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{1}: Data {0}",Data, Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlDate : XmlAttachment
|
||||
{
|
||||
private DateTime m_DataValue;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public DateTime Date { get{ return m_DataValue; } set { m_DataValue = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlDate(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlDate(string name)
|
||||
{
|
||||
Name = name;
|
||||
Date = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlDate(string name, double expiresin)
|
||||
{
|
||||
Name = name;
|
||||
Date = DateTime.UtcNow;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlDate(string name, DateTime value, double expiresin)
|
||||
{
|
||||
Name = name;
|
||||
Date = value;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(m_DataValue);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_DataValue = reader.ReadDateTime();
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{2}: Date {0} expires in {1} mins",Date,Expiration.TotalMinutes, Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{1}: Date {0}",Date, Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using System.Collections;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlDeathAction : XmlAttachment
|
||||
{
|
||||
private string m_Action; // action string
|
||||
private string m_Condition; // condition string
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Action { get { return m_Action; } set { m_Action = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Condition { get { return m_Condition; } set { m_Condition = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlDeathAction(ASerial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlDeathAction(string action)
|
||||
{
|
||||
Action = action;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlDeathAction()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)1);
|
||||
// version 1
|
||||
writer.Write(m_Condition);
|
||||
// version 0
|
||||
writer.Write(m_Action);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
m_Condition = reader.ReadString();
|
||||
goto case 0;
|
||||
case 0:
|
||||
m_Action = reader.ReadString();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
if (AttachedTo is Item)
|
||||
{
|
||||
// dont allow item attachments
|
||||
Delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override bool HandlesOnKilled { get { return true; } }
|
||||
|
||||
public override void OnKilled(Mobile killed, Mobile killer)
|
||||
{
|
||||
base.OnKilled(killed, killer);
|
||||
|
||||
if (killed == null) return;
|
||||
|
||||
// now check for any conditions as well
|
||||
// check for any condition that must be met for this entry to be processed
|
||||
if (Condition != null)
|
||||
{
|
||||
string status_str;
|
||||
|
||||
if (!BaseXmlSpawner.CheckPropertyString(null, killed, Condition, killer, out status_str))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ExecuteDeathActions(killed.Corpse, killer, Action);
|
||||
}
|
||||
|
||||
private void ExecuteDeathActions(Item corpse, Mobile killer, string actions)
|
||||
{
|
||||
if (actions == null || actions.Length <= 0) return;
|
||||
// execute any action associated with it
|
||||
// allow for multiple action strings on a single line separated by a semicolon
|
||||
|
||||
string[] args = actions.Split(';');
|
||||
|
||||
for (int j = 0; j < args.Length; j++)
|
||||
{
|
||||
ExecuteDeathAction(corpse, killer, args[j]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static void ExecuteDeathAction(Item corpse, Mobile killer, string action)
|
||||
{
|
||||
if (action == null || action.Length <= 0 || corpse == null) return;
|
||||
|
||||
string status_str = null;
|
||||
Server.Mobiles.XmlSpawner.SpawnObject TheSpawn = new Server.Mobiles.XmlSpawner.SpawnObject(null, 0);
|
||||
|
||||
TheSpawn.TypeName = action;
|
||||
string substitutedtypeName = BaseXmlSpawner.ApplySubstitution(null, corpse, killer, action);
|
||||
string typeName = BaseXmlSpawner.ParseObjectType(substitutedtypeName);
|
||||
|
||||
Point3D loc = corpse.Location;
|
||||
Map map = corpse.Map;
|
||||
|
||||
if (BaseXmlSpawner.IsTypeOrItemKeyword(typeName))
|
||||
{
|
||||
BaseXmlSpawner.SpawnTypeKeyword(corpse, TheSpawn, typeName, substitutedtypeName, true, killer, loc, map, out status_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
// its a regular type descriptor so find out what it is
|
||||
Type type = SpawnerType.GetType(typeName);
|
||||
try
|
||||
{
|
||||
string[] arglist = BaseXmlSpawner.ParseString(substitutedtypeName, 3, "/");
|
||||
object o = Server.Mobiles.XmlSpawner.CreateObject(type, arglist[0]);
|
||||
|
||||
if (o == null)
|
||||
{
|
||||
status_str = "invalid type specification: " + arglist[0];
|
||||
}
|
||||
else
|
||||
if (o is Mobile)
|
||||
{
|
||||
Mobile m = (Mobile)o;
|
||||
if (m is BaseCreature)
|
||||
{
|
||||
BaseCreature c = (BaseCreature)m;
|
||||
c.Home = loc; // Spawners location is the home point
|
||||
}
|
||||
|
||||
m.Location = loc;
|
||||
m.Map = map;
|
||||
|
||||
BaseXmlSpawner.ApplyObjectStringProperties(null, substitutedtypeName, m, killer, corpse, out status_str);
|
||||
}
|
||||
else
|
||||
if (o is Item)
|
||||
{
|
||||
Item item = (Item)o;
|
||||
BaseXmlSpawner.AddSpawnItem(null, corpse, TheSpawn, item, loc, map, killer, false, substitutedtypeName, out status_str);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlDex : XmlAttachment
|
||||
{
|
||||
private TimeSpan m_Duration = TimeSpan.FromSeconds(30.0); // default 30 sec duration
|
||||
private int m_Value = 10; // default value of 10
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Value { get { return m_Value; } set { m_Value = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlDex(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
[Attachable]
|
||||
public XmlDex()
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlDex(int value)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlDex(int value, double duration)
|
||||
{
|
||||
m_Value = value;
|
||||
m_Duration = TimeSpan.FromSeconds(duration);
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
((Mobile)AttachedTo).AddStatMod( new StatMod( StatType.Dex, "XmlDex"+Name, m_Value, m_Duration ) );
|
||||
}
|
||||
// and then remove the attachment
|
||||
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Delete));
|
||||
//Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,161 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using System.Collections;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlEnemyMastery : XmlAttachment
|
||||
{
|
||||
private int m_Chance = 20; // 20% chance by default
|
||||
private int m_PercentIncrease = 50;
|
||||
private string m_Enemy;
|
||||
private Type m_EnemyType;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Chance { get{ return m_Chance; } set { m_Chance = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int PercentIncrease { get{ return m_PercentIncrease; } set { m_PercentIncrease = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Enemy
|
||||
{
|
||||
get { return m_Enemy; }
|
||||
set
|
||||
{
|
||||
m_Enemy = value;
|
||||
// look up the type
|
||||
m_EnemyType = SpawnerType.GetType(m_Enemy);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlEnemyMastery(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlEnemyMastery(string enemy)
|
||||
{
|
||||
Enemy = enemy;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlEnemyMastery(string enemy,int increase )
|
||||
{
|
||||
m_PercentIncrease = increase;
|
||||
Enemy = enemy;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlEnemyMastery(string enemy,int chance, int increase )
|
||||
{
|
||||
m_Chance = chance;
|
||||
m_PercentIncrease = increase;
|
||||
Enemy = enemy;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlEnemyMastery(string enemy, int chance, int increase, double expiresin)
|
||||
{
|
||||
m_Chance = chance;
|
||||
m_PercentIncrease = increase;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
Enemy = enemy;
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
Mobile m = AttachedTo as Mobile;
|
||||
Effects.PlaySound( m, m.Map, 516 );
|
||||
m.SendMessage(String.Format("You gain the power of Enemy Mastery over {0}",Enemy));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// note that this method will be called when attached to either a mobile or a weapon
|
||||
// when attached to a weapon, only that weapon will do additional damage
|
||||
// when attached to a mobile, any weapon the mobile wields will do additional damage
|
||||
public override void OnWeaponHit(Mobile attacker, Mobile defender, BaseWeapon weapon, int damageGiven)
|
||||
{
|
||||
if(m_Chance <= 0 || Utility.Random(100) > m_Chance)
|
||||
return;
|
||||
|
||||
if(defender != null && attacker != null && m_EnemyType != null)
|
||||
{
|
||||
|
||||
// is the defender the correct type?
|
||||
if(defender.GetType() == m_EnemyType || defender.GetType().IsSubclassOf(m_EnemyType))
|
||||
{
|
||||
defender.Damage( (int) (damageGiven*PercentIncrease/100), attacker );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
Mobile m = AttachedTo as Mobile;
|
||||
if(!m.Deleted)
|
||||
{
|
||||
Effects.PlaySound( m, m.Map, 958 );
|
||||
m.SendMessage(String.Format("Your power of Enemy Mastery over {0} fades..",Enemy));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(m_PercentIncrease);
|
||||
writer.Write(m_Chance);
|
||||
writer.Write(m_Enemy);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_PercentIncrease = reader.ReadInt();
|
||||
m_Chance = reader.ReadInt();
|
||||
Enemy = reader.ReadString();
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
string msg = null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
msg = String.Format("Enemy Mastery : +{3}% damage vs {0}, {1}%, hitchance expires in {2} mins", m_Enemy, Chance, Expiration.TotalMinutes, PercentIncrease);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = String.Format("Enemy Mastery : +{2}% damage vs {0}, {1}% hitchance",m_Enemy, Chance, PercentIncrease);
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlFire : XmlAttachment
|
||||
{
|
||||
private int m_Damage = 0;
|
||||
private TimeSpan m_Refractory = TimeSpan.FromSeconds(5); // 5 seconds default time between activations
|
||||
private DateTime m_EndTime;
|
||||
private int proximityrange = 5; // default movement activation from 5 tiles away
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Damage { get{ return m_Damage; } set { m_Damage = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan Refractory { get { return m_Refractory; } set { m_Refractory = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Range { get { return proximityrange; } set { proximityrange = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlFire(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlFire(int damage)
|
||||
{
|
||||
m_Damage = damage;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlFire(int damage, double refractory)
|
||||
{
|
||||
m_Damage = damage;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlFire(int damage, double refractory, double expiresin)
|
||||
{
|
||||
m_Damage = damage;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
|
||||
// note that this method will be called when attached to either a mobile or a weapon
|
||||
// when attached to a weapon, only that weapon will do additional damage
|
||||
// when attached to a mobile, any weapon the mobile wields will do additional damage
|
||||
public override void OnWeaponHit(Mobile attacker, Mobile defender, BaseWeapon weapon, int damageGiven)
|
||||
{
|
||||
// if it is still refractory then return
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
int damage = 0;
|
||||
|
||||
if(m_Damage > 0)
|
||||
damage = Utility.Random(m_Damage);
|
||||
|
||||
if(defender != null && attacker != null && damage > 0)
|
||||
{
|
||||
attacker.MovingParticles( defender, 0x36D4, 7, 0, false, true, 9502, 4019, 0x160 );
|
||||
attacker.PlaySound( 0x15E );
|
||||
|
||||
SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 100, 0, 0, 0 );
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement { get { return true; } }
|
||||
|
||||
public override void OnMovement(MovementEventArgs e )
|
||||
{
|
||||
base.OnMovement(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
if(AttachedTo is Item && (((Item)AttachedTo).Parent == null) && Utility.InRange( e.Mobile.Location, ((Item)AttachedTo).Location, proximityrange ))
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 1 );
|
||||
// version 1
|
||||
writer.Write(proximityrange);
|
||||
// version 0
|
||||
writer.Write(m_Damage);
|
||||
writer.Write(m_Refractory);
|
||||
writer.Write(m_EndTime - DateTime.UtcNow);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch(version)
|
||||
{
|
||||
case 1:
|
||||
Range = reader.ReadInt();
|
||||
goto case 0;
|
||||
case 0:
|
||||
// version 0
|
||||
m_Damage = reader.ReadInt();
|
||||
Refractory = reader.ReadTimeSpan();
|
||||
TimeSpan remaining = reader.ReadTimeSpan();
|
||||
m_EndTime = DateTime.UtcNow + remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
string msg = null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
msg = String.Format("Fire Damage {0} expires in {1} mins", m_Damage, Expiration.TotalMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = String.Format("Fire Damage {0}",m_Damage);
|
||||
}
|
||||
|
||||
if(Refractory > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{0} : {1} secs between uses",msg, Refractory.TotalSeconds);
|
||||
}
|
||||
else
|
||||
return msg;
|
||||
}
|
||||
|
||||
public override void OnTrigger(object activator, Mobile m)
|
||||
{
|
||||
if(m == null ) return;
|
||||
|
||||
// if it is still refractory then return
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
int damage = 0;
|
||||
|
||||
if(m_Damage > 0)
|
||||
damage = Utility.Random(m_Damage);
|
||||
|
||||
if(damage > 0)
|
||||
{
|
||||
m.MovingParticles( m, 0x36D4, 7, 0, false, true, 9502, 4019, 0x160 );
|
||||
m.PlaySound( 0x15E );
|
||||
SpellHelper.Damage( TimeSpan.Zero, m, damage, 0, 100, 0, 0, 0 );
|
||||
}
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
#define ServUO
|
||||
#if(ServUO)
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlFollow : XmlAttachment
|
||||
{
|
||||
private int m_DataValue;
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlFollow(ASerial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlFollow(int distance)
|
||||
{
|
||||
this.Distance = distance;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlFollow(int distance, double expiresin)
|
||||
{
|
||||
this.Distance = distance;
|
||||
this.Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Distance
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_DataValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_DataValue = value;
|
||||
if (this.AttachedTo is BaseCreature)
|
||||
{
|
||||
((BaseCreature)this.AttachedTo).FollowRange = this.m_DataValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
// These are the various ways in which the message attachment can be constructed. ?
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0);
|
||||
// version 0
|
||||
writer.Write(this.m_DataValue);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
this.m_DataValue = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
// remove the mod
|
||||
if (this.AttachedTo is BaseCreature)
|
||||
{
|
||||
((BaseCreature)this.AttachedTo).FollowRange = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod immediately if attached to a mob
|
||||
if (this.AttachedTo is BaseCreature)
|
||||
{
|
||||
((BaseCreature)this.AttachedTo).FollowRange = this.Distance;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnReattach()
|
||||
{
|
||||
base.OnReattach();
|
||||
|
||||
// reapply the mod if attached to a mob
|
||||
if (this.AttachedTo is BaseCreature)
|
||||
{
|
||||
((BaseCreature)this.AttachedTo).FollowRange = this.Distance;
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if (from == null || from.IsPlayer() || !(this.AttachedTo is BaseCreature))
|
||||
return null;
|
||||
|
||||
BaseCreature b = this.AttachedTo as BaseCreature;
|
||||
|
||||
if (this.Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("Following {0} at Distance {1} expires in {2} mins", b.SummonMaster, this.Distance, this.Expiration.TotalMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("Following {0} at Distance {1}", b.SummonMaster, this.Distance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlFreeze : XmlAttachment
|
||||
{
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlFreeze(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlFreeze()
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlFreeze(double seconds)
|
||||
{
|
||||
Expiration = TimeSpan.FromSeconds(seconds);
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
base.OnIdentify(from);
|
||||
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("Freeze expires in {1} secs",Expiration.TotalSeconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("Frozen");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
// remove the mod
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
((Mobile)AttachedTo).Frozen = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
((Mobile)AttachedTo).Frozen = true;
|
||||
((Mobile)AttachedTo).ProcessDelta();
|
||||
}
|
||||
else
|
||||
Delete();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlHue : XmlAttachment
|
||||
{
|
||||
private int m_Originalhue;
|
||||
private int m_Hue;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Hue { get{ return m_Hue; } set { m_Hue = value; } }
|
||||
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlHue(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlHue(int value)
|
||||
{
|
||||
m_Hue = value;
|
||||
Expiration = TimeSpan.FromSeconds(30.0); // default 30 second duration
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlHue(int value, double duration)
|
||||
{
|
||||
m_Hue = value;
|
||||
Expiration = TimeSpan.FromMinutes(duration);
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(m_Originalhue);
|
||||
writer.Write(m_Hue);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
|
||||
m_Originalhue = reader.ReadInt();
|
||||
m_Hue = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
base.OnIdentify(from);
|
||||
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("Hue {0} expires in {1} mins",m_Hue,Expiration.TotalMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("Hue {0}",m_Hue);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
// remove the mod
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
((Mobile)AttachedTo).Hue = m_Originalhue;
|
||||
}
|
||||
else
|
||||
if(AttachedTo is Item)
|
||||
{
|
||||
((Item)AttachedTo).Hue = m_Originalhue;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
Mobile m = AttachedTo as Mobile;
|
||||
m_Originalhue = m.Hue;
|
||||
m.Hue = m_Hue;
|
||||
}
|
||||
else
|
||||
if(AttachedTo is Item)
|
||||
{
|
||||
Item i = AttachedTo as Item;
|
||||
m_Originalhue = i.Hue;
|
||||
i.Hue = m_Hue;
|
||||
}
|
||||
else
|
||||
Delete();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlInt : XmlAttachment
|
||||
{
|
||||
private TimeSpan m_Duration = TimeSpan.FromSeconds(30.0); // default 30 sec duration
|
||||
private int m_Value = 10; // default value of 10
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Value { get { return m_Value; } set { m_Value = value; } }
|
||||
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlInt(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlInt()
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlInt(int value)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlInt(int value, double duration)
|
||||
{
|
||||
m_Value = value;
|
||||
m_Duration = TimeSpan.FromSeconds(duration);
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
((Mobile)AttachedTo).AddStatMod( new StatMod( StatType.Int, "XmlInt"+Name, m_Value, m_Duration ) );
|
||||
}
|
||||
// and then remove the attachment
|
||||
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Delete));
|
||||
//Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlIsEnemy : XmlAttachment
|
||||
{
|
||||
private string m_TestString = null;// Test condition to see if mobile is an enemy of the object this is attached to
|
||||
public XmlIsEnemy(ASerial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlIsEnemy()
|
||||
{
|
||||
this.Test = String.Empty;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlIsEnemy(string name)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Test = String.Empty;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlIsEnemy(string name, string test)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Test = test;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlIsEnemy(string name, string test, double expiresin)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Test = test;
|
||||
this.Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Test
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_TestString;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_TestString = value;
|
||||
}
|
||||
}
|
||||
public bool IsEnemy(Mobile from)
|
||||
{
|
||||
if (from == null)
|
||||
return false;
|
||||
|
||||
bool isenemy = false;
|
||||
|
||||
// test the condition if there is one
|
||||
if (this.Test != null && this.Test.Length > 0)
|
||||
{
|
||||
string status_str;
|
||||
|
||||
isenemy = BaseXmlSpawner.CheckPropertyString(null, this.AttachedTo, this.Test, from, out status_str);
|
||||
}
|
||||
|
||||
return isenemy;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0);
|
||||
// version 0
|
||||
writer.Write(this.m_TestString);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
this.m_TestString = reader.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if (from == null || from.AccessLevel < AccessLevel.Counselor)
|
||||
return null;
|
||||
|
||||
if (this.Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{0}: IsEnemy '{1}' expires in {2} mins", this.Name, this.Test, this.Expiration.TotalMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{0}: IsEnemy '{1}'", this.Name, this.Test);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlLifeDrain : XmlAttachment
|
||||
{
|
||||
private int m_Drain = 0;
|
||||
private TimeSpan m_Refractory = TimeSpan.FromSeconds(5); // 5 seconds default time between activations
|
||||
private DateTime m_EndTime;
|
||||
private int proximityrange = 5; // default movement activation from 5 tiles away
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Drain { get{ return m_Drain; } set { m_Drain = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Range { get { return proximityrange; } set { proximityrange = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan Refractory { get { return m_Refractory; } set { m_Refractory = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlLifeDrain(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlLifeDrain(int drain)
|
||||
{
|
||||
m_Drain = drain;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlLifeDrain(int drain, double refractory)
|
||||
{
|
||||
m_Drain = drain;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlLifeDrain(int drain, double refractory, double expiresin)
|
||||
{
|
||||
m_Drain = drain;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
|
||||
// note that this method will be called when attached to either a mobile or a weapon
|
||||
// when attached to a weapon, only that weapon will do additional damage
|
||||
// when attached to a mobile, any weapon the mobile wields will do additional damage
|
||||
public override void OnWeaponHit(Mobile attacker, Mobile defender, BaseWeapon weapon, int damageGiven)
|
||||
{
|
||||
// if it is still refractory then return
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
int drain = 0;
|
||||
|
||||
if(m_Drain > 0)
|
||||
drain = Utility.Random(m_Drain);
|
||||
|
||||
if(defender != null && attacker != null && drain > 0)
|
||||
{
|
||||
defender.Hits -= drain;
|
||||
if(defender.Hits < 0) defender.Hits = 0;
|
||||
attacker.Hits += drain;
|
||||
if(attacker.Hits < 0) attacker.Hits = 0;
|
||||
|
||||
DrainEffect(defender);
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
}
|
||||
}
|
||||
|
||||
public void DrainEffect(Mobile m)
|
||||
{
|
||||
if (m == null) return;
|
||||
|
||||
m.FixedParticles( 0x374A, 10, 15, 5013, 0x496, 0, EffectLayer.Waist );
|
||||
m.PlaySound( 0x231 );
|
||||
|
||||
m.SendMessage( "You feel the life drain out of you!" );
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement { get { return true; } }
|
||||
|
||||
public override void OnMovement(MovementEventArgs e )
|
||||
{
|
||||
base.OnMovement(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
if(AttachedTo is Item && (((Item)AttachedTo).Parent == null) && Utility.InRange( e.Mobile.Location, ((Item)AttachedTo).Location, proximityrange ))
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 1 );
|
||||
// version 1
|
||||
writer.Write(proximityrange);
|
||||
// version 0
|
||||
writer.Write(m_Drain);
|
||||
writer.Write(m_Refractory);
|
||||
writer.Write(m_EndTime - DateTime.UtcNow);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch(version)
|
||||
{
|
||||
case 1:
|
||||
// version 1
|
||||
Range = reader.ReadInt();
|
||||
goto case 0;
|
||||
case 0:
|
||||
// version 0
|
||||
m_Drain = reader.ReadInt();
|
||||
Refractory = reader.ReadTimeSpan();
|
||||
TimeSpan remaining = reader.ReadTimeSpan();
|
||||
m_EndTime = DateTime.UtcNow + remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
string msg = null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
msg = String.Format("Life drain {0} expires in {1} mins", m_Drain, Expiration.TotalMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = String.Format("Life drain {0}",m_Drain);
|
||||
}
|
||||
|
||||
if(Refractory > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{0} : {1} secs between uses",msg, Refractory.TotalSeconds);
|
||||
}
|
||||
else
|
||||
return msg;
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// announce it to the mob
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
if(m_Drain > 0)
|
||||
((Mobile)AttachedTo).SendMessage("You have been granted the power of Life Drain!");
|
||||
else
|
||||
((Mobile)AttachedTo).SendMessage("You have been cursed with Life Drain!");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnTrigger(object activator, Mobile m)
|
||||
{
|
||||
if(m == null ) return;
|
||||
|
||||
// if it is still refractory then return
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
int drain = 0;
|
||||
|
||||
if(m_Drain > 0)
|
||||
drain = Utility.Random(m_Drain);
|
||||
|
||||
if(drain > 0)
|
||||
{
|
||||
m.Hits -= drain;
|
||||
if(m.Hits < 0) m.Hits = 0;
|
||||
|
||||
DrainEffect(m);
|
||||
|
||||
}
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlLightning : XmlAttachment
|
||||
{
|
||||
private int m_Damage = 0;
|
||||
private TimeSpan m_Refractory = TimeSpan.FromSeconds(5); // 5 seconds default time between activations
|
||||
private DateTime m_EndTime;
|
||||
private int proximityrange = 5; // default movement activation from 5 tiles away
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Damage { get{ return m_Damage; } set { m_Damage = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan Refractory { get { return m_Refractory; } set { m_Refractory = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Range { get { return proximityrange; } set { proximityrange = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlLightning(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlLightning(int damage)
|
||||
{
|
||||
m_Damage = damage;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlLightning(int damage, double refractory)
|
||||
{
|
||||
m_Damage = damage;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlLightning(int damage, double refractory, double expiresin)
|
||||
{
|
||||
m_Damage = damage;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
|
||||
// note that this method will be called when attached to either a mobile or a weapon
|
||||
// when attached to a weapon, only that weapon will do additional damage
|
||||
// when attached to a mobile, any weapon the mobile wields will do additional damage
|
||||
public override void OnWeaponHit(Mobile attacker, Mobile defender, BaseWeapon weapon, int damageGiven)
|
||||
{
|
||||
// if it is still refractory then return
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
int damage = 0;
|
||||
|
||||
if(m_Damage > 0)
|
||||
damage = Utility.Random(m_Damage);
|
||||
|
||||
if(defender != null && attacker != null && damage > 0)
|
||||
{
|
||||
defender.BoltEffect( 0 );
|
||||
|
||||
SpellHelper.Damage( TimeSpan.Zero, defender, attacker, damage, 0, 0, 0, 0, 100 );
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
}
|
||||
}
|
||||
|
||||
//public override bool HandlesOnMovement { get { return true; } }
|
||||
|
||||
// restrict the movement detection feature to non-movable items
|
||||
|
||||
public override bool HandlesOnMovement
|
||||
{
|
||||
get
|
||||
{
|
||||
if(AttachedTo is Item && !((Item)AttachedTo).Movable)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void OnMovement(MovementEventArgs e )
|
||||
{
|
||||
base.OnMovement(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
if(AttachedTo is Item && (((Item)AttachedTo).Parent == null) && Utility.InRange( e.Mobile.Location, ((Item)AttachedTo).Location, proximityrange ))
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 1 );
|
||||
// version 1
|
||||
writer.Write(proximityrange);
|
||||
// version 0
|
||||
writer.Write(m_Damage);
|
||||
writer.Write(m_Refractory);
|
||||
writer.Write(m_EndTime - DateTime.UtcNow);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch(version)
|
||||
{
|
||||
case 1:
|
||||
proximityrange = reader.ReadInt();
|
||||
goto case 0;
|
||||
case 0:
|
||||
// version 0
|
||||
m_Damage = reader.ReadInt();
|
||||
Refractory = reader.ReadTimeSpan();
|
||||
TimeSpan remaining = reader.ReadTimeSpan();
|
||||
m_EndTime = DateTime.UtcNow + remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
string msg = null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
msg = String.Format("Lightning Damage {0} expires in {1} mins", m_Damage, Expiration.TotalMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = String.Format("Lightning Damage {0}",m_Damage);
|
||||
}
|
||||
|
||||
if(Refractory > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{0} - {1} secs between uses",msg, Refractory.TotalSeconds);
|
||||
}
|
||||
else
|
||||
return msg;
|
||||
}
|
||||
|
||||
public override void OnTrigger(object activator, Mobile m)
|
||||
{
|
||||
if(m == null ) return;
|
||||
|
||||
// if it is still refractory then return
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
int damage = 0;
|
||||
|
||||
if(m_Damage > 0)
|
||||
damage = Utility.Random(m_Damage);
|
||||
|
||||
if(damage > 0)
|
||||
{
|
||||
m.BoltEffect( 0 );
|
||||
|
||||
SpellHelper.Damage( TimeSpan.Zero, m, damage, 0, 0, 0, 0, 100 );
|
||||
}
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlLocalVariable : XmlAttachment
|
||||
{
|
||||
private string m_DataValue = null; // default data
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Data { get{ return m_DataValue; } set { m_DataValue = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlLocalVariable(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlLocalVariable(string name)
|
||||
{
|
||||
Name = name;
|
||||
Data = String.Empty;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlLocalVariable(string name, string data)
|
||||
{
|
||||
Name = name;
|
||||
Data = data;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlLocalVariable(string name, string data, double expiresin)
|
||||
{
|
||||
Name = name;
|
||||
Data = data;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write((string)m_DataValue);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_DataValue = reader.ReadString();
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{2} = {0} : expires in {1} mins",Data,Expiration.TotalMinutes, Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{1} = {0}",Data, Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlMagicWord : XmlAttachment
|
||||
{
|
||||
private string Word;
|
||||
private TimeSpan Duration = TimeSpan.FromSeconds(30.0); // 30 sec default duration for effects
|
||||
private int Charges = 1; // single use by default, note a value of zero or less means unlimited use
|
||||
private TimeSpan Refractory = TimeSpan.Zero; // no refractory period
|
||||
private DateTime m_EndTime = DateTime.MinValue;
|
||||
|
||||
// static list used for random word assignment
|
||||
private static string [] keywordlist = new string[] { "Shoda", "Malik", "Lepto" , "Velas", "Tarda", "Marda", "Vas Malik", "Nartor", "Santor"};
|
||||
|
||||
// note that support for player identification requires modification of the identification skill (see the installation notes for details)
|
||||
private bool m_Identified = false; // optional identification flag that can suppress application of the mod until identified when applied to items
|
||||
|
||||
private bool m_RequireIdentification = false; // by default no identification is required for the mod to be activatable
|
||||
|
||||
// this property can be set allowing individual items to determine whether they must be identified for the mod to be activatable
|
||||
public bool RequireIdentification { get { return m_RequireIdentification; } set {m_RequireIdentification = value; } }
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlMagicWord(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMagicWord()
|
||||
{
|
||||
Word = keywordlist[Utility.Random(keywordlist.Length)];
|
||||
Name = Word;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMagicWord(string word)
|
||||
{
|
||||
Word = word;
|
||||
Name = word;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMagicWord(string word, double duration)
|
||||
{
|
||||
Name = word;
|
||||
Word = word;
|
||||
Duration = TimeSpan.FromSeconds(duration);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMagicWord(string word, double duration, double refractory)
|
||||
{
|
||||
Name = word;
|
||||
Word = word;
|
||||
Duration = TimeSpan.FromSeconds(duration);
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMagicWord(string word, double duration, double refractory, int charges)
|
||||
{
|
||||
Name = word;
|
||||
Word = word;
|
||||
Duration = TimeSpan.FromSeconds(duration);
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
Charges = charges;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(Word);
|
||||
writer.Write(Charges);
|
||||
writer.Write(Duration);
|
||||
writer.Write(Refractory);
|
||||
writer.Write(m_EndTime - DateTime.UtcNow);
|
||||
writer.Write(m_RequireIdentification);
|
||||
writer.Write(m_Identified);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
Word = reader.ReadString();
|
||||
Charges = reader.ReadInt();
|
||||
Duration = reader.ReadTimeSpan();
|
||||
Refractory = reader.ReadTimeSpan();
|
||||
TimeSpan remaining = reader.ReadTimeSpan();
|
||||
m_EndTime = DateTime.UtcNow + remaining;
|
||||
m_RequireIdentification = reader.ReadBool();
|
||||
m_Identified = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
string msg = null;
|
||||
|
||||
// can force identification before the skill mods can be applied
|
||||
if(from != null && from.AccessLevel == AccessLevel.Player)
|
||||
{
|
||||
m_Identified = true;
|
||||
}
|
||||
|
||||
if(RequireIdentification && !m_Identified) return null;
|
||||
|
||||
if(Refractory > TimeSpan.Zero)
|
||||
{
|
||||
msg = String.Format("{0} lasting {1} secs : {2} secs between uses",Word,Duration.TotalSeconds, Refractory.TotalSeconds);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = String.Format("{0} lasting {1} secs",Word,Duration.TotalSeconds);
|
||||
}
|
||||
|
||||
if(Charges > 0)
|
||||
{
|
||||
return String.Format("{0} : {1} charge(s) remaining",msg, Charges);
|
||||
}
|
||||
else
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
// by overriding these properties armor and weapons can be restricted to trigger on speech only when equipped and not when in the pack or in the world
|
||||
public override bool CanActivateInBackpack
|
||||
{
|
||||
get
|
||||
{
|
||||
if(AttachedTo is BaseWeapon || AttachedTo is BaseArmor)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanActivateInWorld
|
||||
{
|
||||
get
|
||||
{
|
||||
if(AttachedTo is BaseWeapon || AttachedTo is BaseArmor)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HandlesOnSpeech { get { return true; } }
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e )
|
||||
{
|
||||
base.OnSpeech(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
// dont respond to other players speech if this is attached to a mob
|
||||
if(AttachedTo is Mobile && (Mobile)AttachedTo != e.Mobile) return;
|
||||
|
||||
if(e.Speech == Word)
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
}
|
||||
|
||||
public void Hide_Callback(object state)
|
||||
{
|
||||
object[] args = (object[])state;
|
||||
Mobile m = (Mobile)args[0];
|
||||
|
||||
m.Hidden = true;
|
||||
}
|
||||
|
||||
public override void OnTrigger(object activator, Mobile m)
|
||||
{
|
||||
if(m == null || Word == null || (RequireIdentification && !m_Identified)) return;
|
||||
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
string msgstr = "Activating the power of " + Word;
|
||||
|
||||
// assign powers to certain words
|
||||
switch ( Word )
|
||||
{
|
||||
case "Shoda":
|
||||
m.AddStatMod( new StatMod( StatType.Int, "Shoda", 20, Duration ) );
|
||||
m.SendMessage("Your mind expands!");
|
||||
break;
|
||||
case "Malik":
|
||||
m.AddStatMod( new StatMod( StatType.Str, "Malik", 20, Duration ) );
|
||||
m.SendMessage("Your strength surges!");
|
||||
break;
|
||||
case "Lepto":
|
||||
m.AddStatMod( new StatMod( StatType.Dex, "Lepto", 20, Duration ) );
|
||||
m.SendMessage("You are more nimble!");
|
||||
break;
|
||||
case "Velas":
|
||||
Timer.DelayCall( TimeSpan.Zero, new TimerStateCallback( Hide_Callback ), new object[]{ m } );
|
||||
m.SendMessage("You disappear!");
|
||||
break;
|
||||
case "Tarda":
|
||||
m.AddSkillMod( new TimedSkillMod( SkillName.Tactics, true, 20, Duration ) );
|
||||
m.SendMessage("You are more skillful warrior!");
|
||||
break;
|
||||
case "Marda":
|
||||
m.AddSkillMod( new TimedSkillMod( SkillName.Magery, true, 20, Duration ) );
|
||||
m.SendMessage("You are more skillful mage!");
|
||||
break;
|
||||
case "Vas Malik":
|
||||
m.AddStatMod( new StatMod( StatType.Str, "Vas Malik", 40, Duration ) );
|
||||
m.SendMessage("You are exceptionally strong!");
|
||||
break;
|
||||
case "Nartor":
|
||||
BaseCreature b = new Drake();
|
||||
b.MoveToWorld(m.Location, m.Map);
|
||||
b.Owners.Add( m );
|
||||
b.SetControlMaster( m );
|
||||
if(b.Controlled)
|
||||
m.SendMessage("You master the beast!");
|
||||
break;
|
||||
case "Santor":
|
||||
b = new Horse();
|
||||
b.MoveToWorld(m.Location, m.Map);
|
||||
b.Owners.Add( m );
|
||||
b.SetControlMaster( m );
|
||||
if(b.Controlled)
|
||||
m.SendMessage("You master the beast!");
|
||||
break;
|
||||
default:
|
||||
m.SendMessage("There is no effect.");
|
||||
break;
|
||||
}
|
||||
|
||||
// display activation effects
|
||||
Effects.SendLocationParticles( EffectItem.Create( m.Location, m.Map, EffectItem.DefaultDuration ), 0x3728, 8, 20, 5042 );
|
||||
Effects.PlaySound( m, m.Map, 0x201 );
|
||||
|
||||
// display a message over the item it was attached to
|
||||
if(AttachedTo is Item )
|
||||
{
|
||||
((Item)AttachedTo).PublicOverheadMessage( MessageType.Regular, 0x3B2, true, msgstr );
|
||||
}
|
||||
|
||||
Charges--;
|
||||
|
||||
// remove the attachment after the charges run out
|
||||
if(Charges == 0)
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlManaDrain : XmlAttachment
|
||||
{
|
||||
private int m_Drain = 0;
|
||||
private TimeSpan m_Refractory = TimeSpan.FromSeconds(5); // 5 seconds default time between activations
|
||||
private DateTime m_EndTime;
|
||||
private int proximityrange = 5; // default movement activation from 5 tiles away
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Drain { get{ return m_Drain; } set { m_Drain = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Range { get { return proximityrange; } set { proximityrange = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan Refractory { get { return m_Refractory; } set { m_Refractory = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlManaDrain(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlManaDrain(int drain)
|
||||
{
|
||||
m_Drain = drain;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlManaDrain(int drain, double refractory)
|
||||
{
|
||||
m_Drain = drain;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlManaDrain(int drain, double refractory, double expiresin)
|
||||
{
|
||||
m_Drain = drain;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
|
||||
// note that this method will be called when attached to either a mobile or a weapon
|
||||
// when attached to a weapon, only that weapon will do additional damage
|
||||
// when attached to a mobile, any weapon the mobile wields will do additional damage
|
||||
public override void OnWeaponHit(Mobile attacker, Mobile defender, BaseWeapon weapon, int damageGiven)
|
||||
{
|
||||
// if it is still refractory then return
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
int drain = 0;
|
||||
|
||||
if(m_Drain > 0)
|
||||
drain = Utility.Random(m_Drain);
|
||||
|
||||
if(defender != null && attacker != null && drain > 0)
|
||||
{
|
||||
defender.Mana -= drain;
|
||||
if(defender.Mana < 0) defender.Mana = 0;
|
||||
attacker.Mana += drain;
|
||||
if(attacker.Mana < 0) attacker.Mana = 0;
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement { get { return true; } }
|
||||
|
||||
public override void OnMovement(MovementEventArgs e )
|
||||
{
|
||||
base.OnMovement(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
if(AttachedTo is Item && (((Item)AttachedTo).Parent == null) && Utility.InRange( e.Mobile.Location, ((Item)AttachedTo).Location, proximityrange ))
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 1 );
|
||||
// version 1
|
||||
writer.Write(proximityrange);
|
||||
// version 0
|
||||
writer.Write(m_Drain);
|
||||
writer.Write(m_Refractory);
|
||||
writer.Write(m_EndTime - DateTime.UtcNow);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch(version)
|
||||
{
|
||||
case 1:
|
||||
// version 1
|
||||
Range = reader.ReadInt();
|
||||
goto case 0;
|
||||
case 0:
|
||||
// version 0
|
||||
m_Drain = reader.ReadInt();
|
||||
Refractory = reader.ReadTimeSpan();
|
||||
TimeSpan remaining = reader.ReadTimeSpan();
|
||||
m_EndTime = DateTime.UtcNow + remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
string msg = null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
msg = String.Format("Mana drain {0} expires in {1} mins", m_Drain, Expiration.TotalMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = String.Format("Mana drain {0}",m_Drain);
|
||||
}
|
||||
|
||||
if(Refractory > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{0} : {1} secs between uses",msg, Refractory.TotalSeconds);
|
||||
}
|
||||
else
|
||||
return msg;
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// announce it to the mob
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
if(m_Drain > 0)
|
||||
((Mobile)AttachedTo).SendMessage("You have been granted the power of Mana Drain!");
|
||||
else
|
||||
((Mobile)AttachedTo).SendMessage("You have been cursed with Mana Drain!");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnTrigger(object activator, Mobile m)
|
||||
{
|
||||
if(m == null ) return;
|
||||
|
||||
// if it is still refractory then return
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
int drain = 0;
|
||||
|
||||
if(m_Drain > 0)
|
||||
drain = Utility.Random(m_Drain);
|
||||
|
||||
if(drain > 0)
|
||||
{
|
||||
m.Mana -= drain;
|
||||
if(m.Mana < 0) m.Mana = 0;
|
||||
|
||||
}
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlMessage : XmlAttachment
|
||||
{
|
||||
private string m_MessageStr;
|
||||
private string m_Word = null; // no word activation by default
|
||||
private TimeSpan m_Refractory = TimeSpan.FromSeconds(5); // 5 seconds default time between activations
|
||||
private DateTime m_EndTime;
|
||||
private int m_Charges = 0; // no charge limit
|
||||
private int proximityrange = 5; // default movement activation from 5 tiles away
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Message { get { return m_MessageStr; } set { m_MessageStr = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Range { get { return proximityrange; } set { proximityrange = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string ActivationWord { get { return m_Word; } set { m_Word = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Charges { get { return m_Charges; } set { m_Charges = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan Refractory { get { return m_Refractory; } set { m_Refractory = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlMessage(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMessage(string msg)
|
||||
{
|
||||
Message = msg;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMessage(string msg, double refractory)
|
||||
{
|
||||
Message = msg;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMessage(string msg, double refractory, string word )
|
||||
{
|
||||
ActivationWord = word;
|
||||
Message = msg;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMessage(string msg, double refractory, string word, int charges )
|
||||
{
|
||||
ActivationWord = word;
|
||||
Message = msg;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
Charges = charges;
|
||||
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 1 );
|
||||
// version 1
|
||||
writer.Write(proximityrange);
|
||||
// version 0
|
||||
writer.Write(m_MessageStr);
|
||||
writer.Write(m_Word);
|
||||
writer.Write(m_Charges);
|
||||
writer.Write(m_Refractory);
|
||||
writer.Write(m_EndTime - DateTime.UtcNow);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch(version)
|
||||
{
|
||||
case 1:
|
||||
Range = reader.ReadInt();
|
||||
goto case 0;
|
||||
case 0:
|
||||
// version 0
|
||||
Message = reader.ReadString();
|
||||
ActivationWord = reader.ReadString();
|
||||
Charges = reader.ReadInt();
|
||||
Refractory = reader.ReadTimeSpan();
|
||||
TimeSpan remaining = reader.ReadTimeSpan();
|
||||
m_EndTime = DateTime.UtcNow + remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
string msg = null;
|
||||
|
||||
if(Charges > 0)
|
||||
{
|
||||
msg = String.Format("{0} : {1} secs between uses, {2} charges left",Message,Refractory.TotalSeconds, Charges);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = String.Format("{0} : {1} secs between uses",Message,Refractory.TotalSeconds);
|
||||
}
|
||||
|
||||
if(ActivationWord == null)
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{0} : trigger on '{1}'",msg,ActivationWord);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override bool HandlesOnSpeech { get { return (ActivationWord != null); } }
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e )
|
||||
{
|
||||
base.OnSpeech(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
if(e.Speech == ActivationWord)
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement { get { return (ActivationWord == null); } }
|
||||
|
||||
public override void OnMovement(MovementEventArgs e )
|
||||
{
|
||||
base.OnMovement(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
if(AttachedTo is Item && (((Item)AttachedTo).Parent == null) && Utility.InRange( e.Mobile.Location, ((Item)AttachedTo).Location, proximityrange ))
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
else
|
||||
if(AttachedTo is Mobile && Utility.InRange( e.Mobile.Location, ((Mobile)AttachedTo).Location, proximityrange ))
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public override void OnTrigger(object activator, Mobile m)
|
||||
{
|
||||
if(m == null ) return;
|
||||
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
|
||||
// display a message over the item it was attached to
|
||||
if(AttachedTo is Item )
|
||||
{
|
||||
((Item)AttachedTo).PublicOverheadMessage( MessageType.Regular, 0x3B2, true, Message );
|
||||
}
|
||||
else
|
||||
if(AttachedTo is Mobile )
|
||||
{
|
||||
((Mobile)AttachedTo).PublicOverheadMessage( MessageType.Regular, 0x3B2, true, Message );
|
||||
}
|
||||
|
||||
Charges--;
|
||||
|
||||
// remove the attachment either after the charges run out or if refractory is zero, then it is one use only
|
||||
if(Refractory == TimeSpan.Zero || Charges == 0)
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using System.Collections;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlMinionStrike : XmlAttachment
|
||||
{
|
||||
private int m_Chance = 5; // 5% chance by default
|
||||
private TimeSpan m_Refractory = TimeSpan.FromSeconds(5); // 5 seconds default time between activations
|
||||
private DateTime m_EndTime;
|
||||
private string m_Minion = "Drake";
|
||||
private ArrayList MinionList = new ArrayList();
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Chance { get{ return m_Chance; } set { m_Chance = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan Refractory { get { return m_Refractory; } set { m_Refractory = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Minion { get { return m_Minion; } set { m_Minion = value; } }
|
||||
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlMinionStrike(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMinionStrike(string minion)
|
||||
{
|
||||
m_Minion = minion;
|
||||
Expiration = TimeSpan.FromMinutes(30);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMinionStrike(string minion,int chance )
|
||||
{
|
||||
m_Chance = chance;
|
||||
m_Minion = minion;
|
||||
Expiration = TimeSpan.FromMinutes(30);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMinionStrike(string minion, int chance, double refractory)
|
||||
{
|
||||
m_Chance = chance;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
Expiration = TimeSpan.FromMinutes(30);
|
||||
m_Minion = minion;
|
||||
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMinionStrike(string minion, int chance, double refractory, double expiresin)
|
||||
{
|
||||
m_Chance = chance;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
m_Minion = minion;
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
Mobile m = AttachedTo as Mobile;
|
||||
Effects.PlaySound( m, m.Map, 516 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// note that this method will be called when attached to either a mobile or a weapon
|
||||
// when attached to a weapon, only that weapon will do additional damage
|
||||
// when attached to a mobile, any weapon the mobile wields will do additional damage
|
||||
public override void OnWeaponHit(Mobile attacker, Mobile defender, BaseWeapon weapon, int damageGiven)
|
||||
{
|
||||
|
||||
// if it is still refractory then return
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
if(m_Chance <= 0 || Utility.Random(100) > m_Chance)
|
||||
return;
|
||||
|
||||
if(defender != null && attacker != null)
|
||||
{
|
||||
|
||||
// spawn a minion
|
||||
object o = null;
|
||||
try
|
||||
{
|
||||
o = Activator.CreateInstance( SpawnerType.GetType(m_Minion) );
|
||||
}
|
||||
catch{}
|
||||
|
||||
if(o is BaseCreature)
|
||||
{
|
||||
BaseCreature b = o as BaseCreature;
|
||||
b.MoveToWorld(attacker.Location, attacker.Map);
|
||||
|
||||
if(attacker is PlayerMobile)
|
||||
{
|
||||
b.Controlled = true;
|
||||
b.ControlMaster = attacker;
|
||||
}
|
||||
|
||||
b.Combatant = defender;
|
||||
|
||||
// add it to the list of controlled mobs
|
||||
MinionList.Add(b);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(o is Item)
|
||||
((Item)o).Delete();
|
||||
if(o is Mobile)
|
||||
((Mobile)o).Delete();
|
||||
// bad minion specification so delete the attachment
|
||||
Delete();
|
||||
}
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
Mobile m = AttachedTo as Mobile;
|
||||
if(!m.Deleted)
|
||||
{
|
||||
Effects.PlaySound( m, m.Map, 958 );
|
||||
}
|
||||
}
|
||||
|
||||
// delete the minions
|
||||
foreach(BaseCreature b in MinionList)
|
||||
{
|
||||
if(b != null && !b.Deleted)
|
||||
b.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(m_Chance);
|
||||
writer.Write(m_Minion);
|
||||
writer.Write(m_Refractory);
|
||||
writer.Write(m_EndTime - DateTime.UtcNow);
|
||||
writer.Write(MinionList.Count);
|
||||
foreach(BaseCreature b in MinionList)
|
||||
writer.Write(b);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_Chance = reader.ReadInt();
|
||||
m_Minion = reader.ReadString();
|
||||
Refractory = reader.ReadTimeSpan();
|
||||
TimeSpan remaining = reader.ReadTimeSpan();
|
||||
m_EndTime = DateTime.UtcNow + remaining;
|
||||
int nminions = reader.ReadInt();
|
||||
for(int i = 0;i<nminions;i++)
|
||||
{
|
||||
BaseCreature b = (BaseCreature)reader.ReadMobile();
|
||||
MinionList.Add(b);
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
string msg = null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
msg = String.Format("Minion : {0} {1}% chance expires in {2} mins", m_Minion, Chance, Expiration.TotalMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = String.Format("Minion : {0}",m_Minion);
|
||||
}
|
||||
|
||||
if(Refractory > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{0} : {1} secs between uses",msg, Refractory.TotalSeconds);
|
||||
}
|
||||
else
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlMorph : XmlAttachment
|
||||
{
|
||||
private string m_Word = null; // no word activation by default
|
||||
private int m_OriginalID = -1; // default value indicating that it has not been morphed
|
||||
private int m_MorphID;
|
||||
private int proximityrange = 2; // default movement activation from 5 tiles away
|
||||
private TimeSpan m_Duration = TimeSpan.FromSeconds(30.0); // default 30 second duration
|
||||
private MorphTimer m_MorphTimer;
|
||||
private DateTime m_MorphEnd;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int MorphID { get { return m_MorphID; } set { m_MorphID = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan Duration { get { return m_Duration; } set { m_Duration = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public DateTime MorphEnd { get { return m_MorphEnd; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string ActivationWord { get { return m_Word; } set { m_Word = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Range { get { return proximityrange; } set { proximityrange = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlMorph(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMorph(int morphID)
|
||||
{
|
||||
m_MorphID = morphID;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMorph(int morphID, double duration)
|
||||
{
|
||||
m_MorphID = morphID;
|
||||
m_Duration = TimeSpan.FromMinutes(duration);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlMorph(int morphID, double duration, string word)
|
||||
{
|
||||
m_MorphID = morphID;
|
||||
m_Duration = TimeSpan.FromMinutes(duration);
|
||||
ActivationWord = word;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 1 );
|
||||
// version 1
|
||||
writer.Write(proximityrange);
|
||||
// version 0
|
||||
writer.Write(m_OriginalID);
|
||||
writer.Write(m_MorphID);
|
||||
writer.Write(m_Duration);
|
||||
writer.Write(m_Word);
|
||||
if(m_MorphTimer != null)
|
||||
{
|
||||
writer.Write(m_MorphEnd - DateTime.UtcNow);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write(TimeSpan.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch(version)
|
||||
{
|
||||
case 1:
|
||||
Range = reader.ReadInt();
|
||||
goto case 0;
|
||||
case 0:
|
||||
// version 0
|
||||
|
||||
m_OriginalID = reader.ReadInt();
|
||||
m_MorphID = reader.ReadInt();
|
||||
m_Duration = reader.ReadTimeSpan();
|
||||
ActivationWord = reader.ReadString();
|
||||
TimeSpan remaining = (TimeSpan)reader.ReadTimeSpan();
|
||||
|
||||
if(remaining > TimeSpan.Zero)
|
||||
DoTimer(remaining);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
base.OnIdentify(from);
|
||||
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
string msg = null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
msg = String.Format("Morph to {0} expires in {1} mins",m_MorphID,Expiration.TotalMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = String.Format("Morph to {0} duration {1} mins",m_MorphID, m_Duration.TotalMinutes);
|
||||
}
|
||||
|
||||
if(ActivationWord != null)
|
||||
{
|
||||
return String.Format("{0} activated by '{1}'",msg, ActivationWord);
|
||||
}
|
||||
else
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
// remove the mod
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
((Mobile)AttachedTo).BodyMod = m_OriginalID;
|
||||
}
|
||||
else
|
||||
if(AttachedTo is Item)
|
||||
{
|
||||
((Item)AttachedTo).ItemID = m_OriginalID;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HandlesOnSpeech { get { return (ActivationWord != null); } }
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e )
|
||||
{
|
||||
base.OnSpeech(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
// dont respond to other players speech if this is attached to a mob
|
||||
if(AttachedTo is Mobile && (Mobile)AttachedTo != e.Mobile) return;
|
||||
|
||||
if(e.Speech == ActivationWord)
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement { get { return (ActivationWord == null); } }
|
||||
|
||||
public override void OnMovement(MovementEventArgs e )
|
||||
{
|
||||
base.OnMovement(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
if(AttachedTo is Item && (((Item)AttachedTo).Parent == null) && Utility.InRange( e.Mobile.Location, ((Item)AttachedTo).Location, proximityrange ))
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod immediately if attached to a mob
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
Mobile m = AttachedTo as Mobile;
|
||||
m_OriginalID = m.BodyMod;
|
||||
m.BodyMod = m_MorphID;
|
||||
Expiration = m_Duration;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnReattach()
|
||||
{
|
||||
base.OnReattach();
|
||||
|
||||
// reapply the mod if attached to a mob
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
((Mobile)AttachedTo).BodyMod = m_MorphID;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------
|
||||
// Private methods
|
||||
// ----------------------------------------------
|
||||
private void DoTimer(TimeSpan delay)
|
||||
{
|
||||
m_MorphEnd = DateTime.UtcNow + delay;
|
||||
|
||||
if ( m_MorphTimer != null )
|
||||
m_MorphTimer.Stop();
|
||||
|
||||
m_MorphTimer = new MorphTimer( this, delay);
|
||||
m_MorphTimer.Start();
|
||||
}
|
||||
|
||||
// a timer that can be implement limited lifetime morph
|
||||
private class MorphTimer : Timer
|
||||
{
|
||||
private XmlMorph m_Attachment;
|
||||
|
||||
public MorphTimer( XmlMorph attachment, TimeSpan delay) : base( delay )
|
||||
{
|
||||
Priority = TimerPriority.OneSecond;
|
||||
|
||||
m_Attachment = attachment;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if(m_Attachment != null && !m_Attachment.Deleted && m_Attachment.AttachedTo is Item && !((Item)m_Attachment.AttachedTo).Deleted)
|
||||
{
|
||||
Item i = m_Attachment.AttachedTo as Item;
|
||||
i.ItemID = m_Attachment.m_OriginalID;
|
||||
m_Attachment.m_OriginalID = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnTrigger(object activator, Mobile m)
|
||||
{
|
||||
if(m == null ) return;
|
||||
|
||||
// if attached to an item then morph and then reset after duration
|
||||
// note that OriginalID will be -1 if the target is not already morphed
|
||||
if(AttachedTo is Item && m_OriginalID == -1)
|
||||
{
|
||||
Item i = AttachedTo as Item;
|
||||
m_OriginalID = i.ItemID;
|
||||
i.ItemID = m_MorphID;
|
||||
|
||||
// start the timer to reset the ID
|
||||
DoTimer(m_Duration);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlSpawnTime : XmlAttachment
|
||||
{
|
||||
private TimeSpan m_MinDelay = TimeSpan.MinValue;
|
||||
private TimeSpan m_MaxDelay = TimeSpan.MinValue;
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlSpawnTime(ASerial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSpawnTime(double mindelay, double maxdelay)
|
||||
{
|
||||
this.MinDelay = TimeSpan.FromMinutes(mindelay);
|
||||
this.MaxDelay = TimeSpan.FromMinutes(maxdelay);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSpawnTime()
|
||||
{
|
||||
// min/maxdelay values will be taken from the spawner
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan MinDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
XmlSpawner spawner = this.MySpawner;
|
||||
|
||||
// try to get the min/maxdelay based on spawner values if not specified on the attachment.
|
||||
if (spawner != null && this.m_MinDelay < TimeSpan.Zero)
|
||||
{
|
||||
return spawner.MinDelay;
|
||||
}
|
||||
return this.m_MinDelay;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_MinDelay = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan MaxDelay
|
||||
{
|
||||
get
|
||||
{
|
||||
XmlSpawner spawner = this.MySpawner;
|
||||
|
||||
// try to get the min/maxdelay based on spawner values if not specified on the attachment.
|
||||
if (spawner != null && this.m_MaxDelay < TimeSpan.Zero)
|
||||
{
|
||||
return spawner.MaxDelay;
|
||||
}
|
||||
|
||||
return this.m_MaxDelay;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_MaxDelay = value;
|
||||
}
|
||||
}
|
||||
public override bool HandlesOnKilled
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
private XmlSpawner MySpawner
|
||||
{
|
||||
get
|
||||
{
|
||||
// figure out the spawner that spawned the object
|
||||
if (this.AttachedTo is Item)
|
||||
{
|
||||
return ((Item)this.AttachedTo).Spawner as XmlSpawner;
|
||||
}
|
||||
else if (this.AttachedTo is Mobile)
|
||||
{
|
||||
return ((Mobile)this.AttachedTo).Spawner as XmlSpawner;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
public static void ResetXmlSpawnTime(Mobile killed)
|
||||
{
|
||||
if (killed == null)
|
||||
return;
|
||||
|
||||
// set the spawner's NextSpawn time based on min/maxdelay
|
||||
XmlSpawner spawner = killed.Spawner as XmlSpawner;
|
||||
|
||||
if (spawner != null)
|
||||
{
|
||||
int mind = (int)spawner.MinDelay.TotalSeconds;
|
||||
int maxd = (int)spawner.MaxDelay.TotalSeconds;
|
||||
|
||||
if (mind >= 0 && maxd >= 0)
|
||||
{
|
||||
spawner.NextSpawn = TimeSpan.FromSeconds(Utility.RandomMinMax(mind, maxd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0);
|
||||
// version 0
|
||||
writer.Write(this.m_MinDelay);
|
||||
writer.Write(this.m_MaxDelay);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch (version)
|
||||
{
|
||||
case 0:
|
||||
this.m_MinDelay = reader.ReadTimeSpan();
|
||||
this.m_MaxDelay = reader.ReadTimeSpan();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnKilled(Mobile killed, Mobile killer)
|
||||
{
|
||||
base.OnKilled(killed, killer);
|
||||
|
||||
if (killed == null)
|
||||
return;
|
||||
|
||||
// set the spawner's NextSpawn time based on min/maxdelay
|
||||
XmlSpawner spawner = this.MySpawner;
|
||||
|
||||
int mind = (int)this.MinDelay.TotalSeconds;
|
||||
int maxd = (int)this.MaxDelay.TotalSeconds;
|
||||
|
||||
if (spawner != null && mind >= 0 && maxd >= 0)
|
||||
{
|
||||
spawner.NextSpawn = TimeSpan.FromSeconds(Utility.RandomMinMax(mind, maxd));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
using System;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlPoison : XmlAttachment
|
||||
{
|
||||
private int p_level = 0;
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlPoison(ASerial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlPoison(int level)
|
||||
{
|
||||
this.p_level = level;
|
||||
}
|
||||
|
||||
// when attached to a mobile, it should gain poison immunity and a poison
|
||||
|
||||
//attack, but no poisoning skill
|
||||
public Poison PoisonImmune
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.p_level < 1)
|
||||
{
|
||||
return Poison.Lesser;
|
||||
}
|
||||
else if (this.p_level == 1)
|
||||
{
|
||||
return Poison.Regular;
|
||||
}
|
||||
else if (this.p_level == 2)
|
||||
{
|
||||
return Poison.Greater;
|
||||
}
|
||||
else if (this.p_level == 3)
|
||||
{
|
||||
return Poison.Deadly;
|
||||
}
|
||||
else if (this.p_level > 3)
|
||||
{
|
||||
return Poison.Lethal;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Poison.Regular;
|
||||
}
|
||||
}
|
||||
}
|
||||
public Poison HitPoison
|
||||
{
|
||||
get
|
||||
{
|
||||
if (this.p_level < 1)
|
||||
{
|
||||
return Poison.Lesser;
|
||||
}
|
||||
else if (this.p_level == 1)
|
||||
{
|
||||
return Poison.Regular;
|
||||
}
|
||||
else if (this.p_level == 2)
|
||||
{
|
||||
return Poison.Greater;
|
||||
}
|
||||
else if (this.p_level == 3)
|
||||
{
|
||||
return Poison.Deadly;
|
||||
}
|
||||
else if (this.p_level > 3)
|
||||
{
|
||||
return Poison.Lethal;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Poison.Regular;
|
||||
}
|
||||
}
|
||||
}
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0);
|
||||
// version 0
|
||||
writer.Write(this.p_level);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch(version)
|
||||
{
|
||||
case 0:
|
||||
// version 0
|
||||
this.p_level = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlRestrictEquip : XmlAttachment
|
||||
{
|
||||
private string m_TestValue = null;// default Test condition
|
||||
private string m_FailMsg = null;// message given when equipping fails
|
||||
private string m_PropertyListString = null;// string displayed in the properties list
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlRestrictEquip(ASerial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlRestrictEquip()
|
||||
{
|
||||
this.Test = String.Empty;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlRestrictEquip(string name)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Test = String.Empty;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlRestrictEquip(string name, string test)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Test = test;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlRestrictEquip(string name, string test, double expiresin)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Test = test;
|
||||
this.Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Test
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_TestValue;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_TestValue = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string FailMsg
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_FailMsg;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_FailMsg = value;
|
||||
}
|
||||
}
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string PropertyListString
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_PropertyListString;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_PropertyListString = value;
|
||||
this.InvalidateParentProperties();
|
||||
}
|
||||
}
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
public override bool CanEquip(Mobile from)
|
||||
{
|
||||
if (from == null)
|
||||
return false;
|
||||
|
||||
bool allowequip = true;
|
||||
|
||||
// test the condition if there is one
|
||||
if (this.Test != null && this.Test.Length > 0)
|
||||
{
|
||||
string status_str;
|
||||
|
||||
allowequip = BaseXmlSpawner.CheckPropertyString(null, this.AttachedTo, this.Test, from, out status_str);
|
||||
|
||||
if (!allowequip && this.FailMsg != null)
|
||||
{
|
||||
from.SendMessage(this.FailMsg);
|
||||
}
|
||||
}
|
||||
|
||||
return allowequip;
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)1);
|
||||
// version 1
|
||||
writer.Write(this.m_PropertyListString);
|
||||
writer.Write(this.m_FailMsg);
|
||||
// version 0
|
||||
writer.Write(this.m_TestValue);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
this.m_PropertyListString = reader.ReadString();
|
||||
this.m_FailMsg = reader.ReadString();
|
||||
goto case 0;
|
||||
case 0:
|
||||
this.m_TestValue = reader.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string DisplayedProperties(Mobile from)
|
||||
{
|
||||
return this.PropertyListString;
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if (from == null || from.AccessLevel < AccessLevel.Counselor)
|
||||
return null;
|
||||
|
||||
if (this.Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{0}: RestrictEquip '{1}' expires in {2} mins", this.Name, this.Test, this.Expiration.TotalMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{0}: RestrictEquip '{1}'", this.Name, this.Test);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlSaveItem : XmlAttachment
|
||||
{
|
||||
private class SaveItemPack : Container
|
||||
{
|
||||
public override int MaxWeight { get { return 0; }}
|
||||
|
||||
public SaveItemPack() : base( 0x9B2 )
|
||||
{
|
||||
}
|
||||
|
||||
public SaveItemPack( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
private Item m_SavedItem;
|
||||
private Container m_Container;
|
||||
private Mobile m_WasOwnedBy;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Container Container
|
||||
{
|
||||
get { return m_Container; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Item SavedItem
|
||||
{
|
||||
get
|
||||
{
|
||||
// if the item has been moved off of the internal map, then forget about it
|
||||
if(m_SavedItem != null && (m_SavedItem.Parent != m_Container || m_SavedItem.Deleted))
|
||||
{
|
||||
m_WasOwnedBy = null;
|
||||
m_SavedItem = null;
|
||||
}
|
||||
|
||||
return m_SavedItem;
|
||||
}
|
||||
set
|
||||
{
|
||||
// delete any existing item before assigning a new value
|
||||
if(SavedItem != null)
|
||||
{
|
||||
SafeItemDelete(m_SavedItem);
|
||||
//m_SavedItem.Delete();
|
||||
m_SavedItem = null;
|
||||
}
|
||||
|
||||
// dont allow saving the item if it is attached to it
|
||||
if(value != AttachedTo)
|
||||
{
|
||||
m_SavedItem = value;
|
||||
}
|
||||
|
||||
// automatically internalize any saved item
|
||||
if(m_SavedItem != null)
|
||||
{
|
||||
AddToContainer(m_SavedItem);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool RestoreItem
|
||||
{
|
||||
get{ return false; }
|
||||
set
|
||||
{
|
||||
if(value == true && SavedItem != null && AttachedTo is IEntity && ((IEntity)AttachedTo).Map != Map.Internal && ((IEntity)AttachedTo).Map != null)
|
||||
{
|
||||
|
||||
// move the item to the location of the object the attachment is attached to
|
||||
if(AttachedTo is Item)
|
||||
{
|
||||
m_SavedItem.Map = ((Item)AttachedTo).Map;
|
||||
m_SavedItem.Location = ((Item)AttachedTo).Location;
|
||||
m_SavedItem.Parent = ((Item)AttachedTo).Parent;
|
||||
} else
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
m_SavedItem.Map = ((Mobile)AttachedTo).Map;
|
||||
m_SavedItem.Location = ((Mobile)AttachedTo).Location;
|
||||
m_SavedItem.Parent = null;
|
||||
}
|
||||
|
||||
|
||||
m_SavedItem = null;
|
||||
m_WasOwnedBy = null;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Mobile WasOwnedBy { get{ return m_WasOwnedBy; } set { m_WasOwnedBy = value; } }
|
||||
|
||||
private void AddToContainer(Item item)
|
||||
{
|
||||
if(item == null) return;
|
||||
|
||||
if(m_Container == null)
|
||||
{
|
||||
m_Container = new SaveItemPack();
|
||||
}
|
||||
|
||||
// need to place in a container to prevent internal map cleanup of the item
|
||||
m_Container.DropItem(item);
|
||||
m_Container.Internalize();
|
||||
}
|
||||
|
||||
public Item GetItem()
|
||||
{
|
||||
Item returneditem = SavedItem;
|
||||
|
||||
m_SavedItem = null;
|
||||
m_WasOwnedBy = null;
|
||||
|
||||
return returneditem;
|
||||
}
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlSaveItem(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSaveItem()
|
||||
{
|
||||
m_Container = new SaveItemPack();
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSaveItem(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
|
||||
public XmlSaveItem(string name, Item saveditem)
|
||||
{
|
||||
Name = name;
|
||||
SavedItem = saveditem;
|
||||
|
||||
}
|
||||
|
||||
public XmlSaveItem(string name, Item saveditem, Mobile wasownedby)
|
||||
{
|
||||
Name = name;
|
||||
SavedItem = saveditem;
|
||||
WasOwnedBy = wasownedby;
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
// delete the item
|
||||
if(SavedItem != null)
|
||||
{
|
||||
//SavedItem.Delete();
|
||||
SafeItemDelete(SavedItem);
|
||||
}
|
||||
|
||||
if(m_Container != null)
|
||||
{
|
||||
SafeItemDelete(m_Container);
|
||||
//m_Container.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
if(SavedItem != null)
|
||||
{
|
||||
writer.Write(m_SavedItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write((Item)null);
|
||||
}
|
||||
writer.Write(m_WasOwnedBy);
|
||||
writer.Write(m_Container);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_SavedItem = reader.ReadItem();
|
||||
m_WasOwnedBy = reader.ReadMobile();
|
||||
m_Container = (Container)reader.ReadItem();
|
||||
|
||||
AddToContainer(m_SavedItem);
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{2}: Item {0} expires in {1} mins",SavedItem, Expiration.TotalMinutes, Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{1}: Item {0}",SavedItem, Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,202 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlSkill : XmlAttachment
|
||||
{
|
||||
private string m_Word = null; // not speech activated by default
|
||||
private TimeSpan m_Duration = TimeSpan.FromMinutes(30.0); // 30 min default duration for effects
|
||||
private int m_Value = 10; // default value of 10
|
||||
private SkillName m_Skill;
|
||||
|
||||
// note that support for player identification requires modification of the identification skill (see the installation notes for details)
|
||||
private bool m_Identified = false; // optional identification flag that can suppress application of the mod until identified when applied to items
|
||||
|
||||
private bool m_RequireIdentification = false; // by default no identification is required for the mod to be activatable
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
// this property can be set allowing individual items to determine whether they must be identified for the mod to be activatable
|
||||
public bool RequireIdentification { get { return m_RequireIdentification; } set {m_RequireIdentification = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Value { get { return m_Value; } set { m_Value = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public SkillName Skill { get { return m_Skill; } set { m_Skill = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan Duration { get { return m_Duration; } set { m_Duration = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string ActivationWord { get { return m_Word; } set { m_Word = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlSkill(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSkill(string name, string skill)
|
||||
{
|
||||
Name = name;
|
||||
try
|
||||
{
|
||||
m_Skill = (SkillName)Enum.Parse( typeof( SkillName ), skill, true );
|
||||
}
|
||||
catch {}
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSkill(string name, string skill, int value)
|
||||
{
|
||||
Name = name;
|
||||
try
|
||||
{
|
||||
m_Skill = (SkillName)Enum.Parse( typeof( SkillName ), skill, true );
|
||||
}
|
||||
catch {}
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSkill(string name, string skill, int value, double duration)
|
||||
{
|
||||
Name = name;
|
||||
try
|
||||
{
|
||||
m_Skill = (SkillName)Enum.Parse( typeof( SkillName ), skill, true );
|
||||
}
|
||||
catch {}
|
||||
m_Value = value;
|
||||
m_Duration = TimeSpan.FromMinutes(duration);
|
||||
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSkill(string name, string skill, int value, double duration, string word)
|
||||
{
|
||||
Name = name;
|
||||
try
|
||||
{
|
||||
m_Skill = (SkillName)Enum.Parse( typeof( SkillName ), skill, true );
|
||||
}
|
||||
catch {}
|
||||
m_Value = value;
|
||||
m_Duration = TimeSpan.FromMinutes(duration);
|
||||
m_Word = word;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(m_Word);
|
||||
writer.Write((int)m_Skill);
|
||||
writer.Write(m_Value);
|
||||
writer.Write(m_Duration);
|
||||
writer.Write(m_RequireIdentification);
|
||||
writer.Write(m_Identified);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_Word = reader.ReadString();
|
||||
m_Skill = (SkillName) reader.ReadInt();
|
||||
m_Value = reader.ReadInt();
|
||||
m_Duration = reader.ReadTimeSpan();
|
||||
m_RequireIdentification = reader.ReadBool();
|
||||
m_Identified = reader.ReadBool();
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if(AttachedTo is BaseArmor || AttachedTo is BaseWeapon)
|
||||
{
|
||||
// can force identification before the skill mods can be applied
|
||||
if(from != null && from.AccessLevel == AccessLevel.Player)
|
||||
{
|
||||
m_Identified = true;
|
||||
}
|
||||
return String.Format("activated by {0} : skill {1} mod of {2} when equipped",m_Word, m_Skill, m_Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("activated by {0} : skill {1} mod of {2} lasting {3} mins",m_Word, m_Skill, m_Value, m_Duration.TotalMinutes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public override bool HandlesOnSpeech { get { return true; } }
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e )
|
||||
{
|
||||
base.OnSpeech(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
// dont respond to other players speech if this is attached to a mob
|
||||
if(AttachedTo is Mobile && (Mobile)AttachedTo != e.Mobile) return;
|
||||
|
||||
if(e.Speech == m_Word)
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod immediately
|
||||
if(AttachedTo is Mobile && m_Word == null)
|
||||
{
|
||||
OnTrigger(null, (Mobile)AttachedTo);
|
||||
// and then remove the attachment
|
||||
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Delete));
|
||||
//Delete();
|
||||
}
|
||||
else
|
||||
if(AttachedTo is Item && m_Word == null)
|
||||
{
|
||||
// no way to activate if it is on an item and is not speech activated so just delete it
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnTrigger(object activator, Mobile m)
|
||||
{
|
||||
if(m == null || (RequireIdentification && !m_Identified)) return;
|
||||
|
||||
if((AttachedTo is BaseArmor || AttachedTo is BaseWeapon) && (((Item)AttachedTo).Layer != Layer.Invalid))
|
||||
{
|
||||
// when activated via speech will apply mod when equipped by the speaker
|
||||
SkillMod sm = new EquipedSkillMod( m_Skill, true, m_Value, (Item)AttachedTo, m );
|
||||
m.AddSkillMod( sm );
|
||||
// and then remove the attachment
|
||||
Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
// when activated it will apply the skill mod that will last for the specified duration
|
||||
SkillMod sm = new TimedSkillMod( m_Skill, true, m_Value, m_Duration );
|
||||
m.AddSkillMod( sm );
|
||||
// and then remove the attachment
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlSound : XmlAttachment
|
||||
{
|
||||
private int m_SoundValue = 500; // default sound
|
||||
private string m_Word = null; // no word activation by default
|
||||
private TimeSpan m_Refractory = TimeSpan.FromSeconds(5); // 5 seconds default time between activations
|
||||
private DateTime m_EndTime;
|
||||
private int m_Charges = 0; // no charge limit
|
||||
private int proximityrange = 5; // default movement activation from 5 tiles away
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Range { get { return proximityrange; } set { proximityrange = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int SoundValue { get { return m_SoundValue; } set { m_SoundValue = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string ActivationWord { get { return m_Word; } set { m_Word = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Charges { get { return m_Charges; } set { m_Charges = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan Refractory { get { return m_Refractory; } set { m_Refractory = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlSound(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSound()
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSound(int sound)
|
||||
{
|
||||
SoundValue = sound;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSound(int sound, double refractory)
|
||||
{
|
||||
SoundValue = sound;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSound(int sound, double refractory, string word )
|
||||
{
|
||||
ActivationWord = word;
|
||||
SoundValue = sound;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSound(int sound, double refractory, string word, int charges )
|
||||
{
|
||||
ActivationWord = word;
|
||||
SoundValue = sound;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
Charges = charges;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlSound(int sound, double refractory, int charges )
|
||||
{
|
||||
SoundValue = sound;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
Charges = charges;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 1 );
|
||||
// version 1
|
||||
writer.Write(proximityrange);
|
||||
// version 0
|
||||
writer.Write(m_SoundValue);
|
||||
writer.Write(m_Word);
|
||||
writer.Write(m_Charges);
|
||||
writer.Write(m_Refractory);
|
||||
writer.Write(m_EndTime - DateTime.UtcNow);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch(version)
|
||||
{
|
||||
case 1:
|
||||
// version 1
|
||||
proximityrange = reader.ReadInt();
|
||||
goto case 0;
|
||||
case 0:
|
||||
// version 0
|
||||
SoundValue = reader.ReadInt();
|
||||
ActivationWord = reader.ReadString();
|
||||
Charges = reader.ReadInt();
|
||||
Refractory = reader.ReadTimeSpan();
|
||||
TimeSpan remaining = reader.ReadTimeSpan();
|
||||
m_EndTime = DateTime.UtcNow + remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
string msg = null;
|
||||
|
||||
if(Charges > 0)
|
||||
{
|
||||
msg = String.Format("Sound #{0} : {1} secs between uses - {2} charges left",SoundValue,Refractory.TotalSeconds, Charges);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = String.Format("Sound #{0} : {1} secs between uses",SoundValue,Refractory.TotalSeconds);
|
||||
}
|
||||
|
||||
if(ActivationWord == null)
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{0} : trigger on '{1}'",msg, ActivationWord);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override bool HandlesOnSpeech { get { return (ActivationWord != null); } }
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e )
|
||||
{
|
||||
base.OnSpeech(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
if(e.Speech == ActivationWord)
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement { get { return (ActivationWord == null); } }
|
||||
|
||||
public override void OnMovement(MovementEventArgs e )
|
||||
{
|
||||
base.OnMovement(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
if(AttachedTo is Item && (((Item)AttachedTo).Parent == null) && Utility.InRange( e.Mobile.Location, ((Item)AttachedTo).Location, proximityrange ))
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
public override void OnTrigger(object activator, Mobile m)
|
||||
{
|
||||
if(m == null ) return;
|
||||
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
|
||||
// play a sound
|
||||
if(AttachedTo is Mobile )
|
||||
{
|
||||
try
|
||||
{
|
||||
Effects.PlaySound(((Mobile)AttachedTo).Location, ((IEntity)AttachedTo).Map, SoundValue);
|
||||
}
|
||||
catch{}
|
||||
}
|
||||
else
|
||||
if(AttachedTo is Item )
|
||||
{
|
||||
Item i = AttachedTo as Item;
|
||||
|
||||
if(i.Parent == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Effects.PlaySound(i.Location, i.Map, SoundValue);
|
||||
}
|
||||
catch{}
|
||||
}
|
||||
else
|
||||
if(i.RootParent is IEntity)
|
||||
{
|
||||
try
|
||||
{
|
||||
Effects.PlaySound(((IEntity)i.RootParent).Location, ((IEntity)i.RootParent).Map, SoundValue);
|
||||
}
|
||||
catch{}
|
||||
}
|
||||
}
|
||||
|
||||
Charges--;
|
||||
|
||||
// remove the attachment either after the charges run out or if refractory is zero, then it is one use only
|
||||
if(Refractory == TimeSpan.Zero || Charges == 0)
|
||||
{
|
||||
Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlStamDrain : XmlAttachment
|
||||
{
|
||||
private int m_Drain = 0;
|
||||
private TimeSpan m_Refractory = TimeSpan.FromSeconds(5); // 5 seconds default time between activations
|
||||
private DateTime m_EndTime;
|
||||
private int proximityrange = 5; // default movement activation from 5 tiles away
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Drain { get{ return m_Drain; } set { m_Drain = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Range { get { return proximityrange; } set { proximityrange = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan Refractory { get { return m_Refractory; } set { m_Refractory = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlStamDrain(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlStamDrain(int drain)
|
||||
{
|
||||
m_Drain = drain;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlStamDrain(int drain, double refractory)
|
||||
{
|
||||
m_Drain = drain;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlStamDrain(int drain, double refractory, double expiresin)
|
||||
{
|
||||
m_Drain = drain;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
|
||||
// note that this method will be called when attached to either a mobile or a weapon
|
||||
// when attached to a weapon, only that weapon will do additional damage
|
||||
// when attached to a mobile, any weapon the mobile wields will do additional damage
|
||||
public override void OnWeaponHit(Mobile attacker, Mobile defender, BaseWeapon weapon, int damageGiven)
|
||||
{
|
||||
// if it is still refractory then return
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
int drain = 0;
|
||||
|
||||
if(m_Drain > 0)
|
||||
drain = Utility.Random(m_Drain);
|
||||
|
||||
if(defender != null && attacker != null && drain > 0)
|
||||
{
|
||||
defender.Stam -= drain;
|
||||
if(defender.Stam < 0) defender.Stam = 0;
|
||||
|
||||
attacker.Stam += drain;
|
||||
if(attacker.Stam < 0) attacker.Stam = 0;
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement { get { return true; } }
|
||||
|
||||
public override void OnMovement(MovementEventArgs e )
|
||||
{
|
||||
base.OnMovement(e);
|
||||
|
||||
if(e.Mobile == null || e.Mobile.AccessLevel > AccessLevel.Player) return;
|
||||
|
||||
if(AttachedTo is Item && (((Item)AttachedTo).Parent == null) && Utility.InRange( e.Mobile.Location, ((Item)AttachedTo).Location, proximityrange ))
|
||||
{
|
||||
OnTrigger(null, e.Mobile);
|
||||
}
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 1 );
|
||||
// version 1
|
||||
writer.Write(proximityrange);
|
||||
// version 0
|
||||
writer.Write(m_Drain);
|
||||
writer.Write(m_Refractory);
|
||||
writer.Write(m_EndTime - DateTime.UtcNow);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch(version)
|
||||
{
|
||||
case 1:
|
||||
// version 1
|
||||
Range = reader.ReadInt();
|
||||
goto case 0;
|
||||
case 0:
|
||||
// version 0
|
||||
m_Drain = reader.ReadInt();
|
||||
Refractory = reader.ReadTimeSpan();
|
||||
TimeSpan remaining = reader.ReadTimeSpan();
|
||||
m_EndTime = DateTime.UtcNow + remaining;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
string msg = null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
msg = String.Format("Stamina drain {0} expires in {1} mins", m_Drain, Expiration.TotalMinutes);
|
||||
}
|
||||
else
|
||||
{
|
||||
msg = String.Format("Stamina drain {0}",m_Drain);
|
||||
}
|
||||
|
||||
if(Refractory > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{0} : {1} secs between uses",msg, Refractory.TotalSeconds);
|
||||
}
|
||||
else
|
||||
return msg;
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// announce it to the mob
|
||||
if(AttachedTo is Mobile)
|
||||
{
|
||||
if(m_Drain > 0)
|
||||
((Mobile)AttachedTo).SendMessage("You have been granted the power of Stamina Drain!");
|
||||
else
|
||||
((Mobile)AttachedTo).SendMessage("You have been cursed with Stamina Drain!");
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnTrigger(object activator, Mobile m)
|
||||
{
|
||||
if(m == null ) return;
|
||||
|
||||
// if it is still refractory then return
|
||||
if(DateTime.UtcNow < m_EndTime) return;
|
||||
|
||||
int drain = 0;
|
||||
|
||||
if(m_Drain > 0)
|
||||
drain = Utility.Random(m_Drain);
|
||||
|
||||
if(drain > 0)
|
||||
{
|
||||
m.Stam -= drain;
|
||||
if(m.Stam < 0) m.Stam = 0;
|
||||
|
||||
}
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlStr : XmlAttachment
|
||||
{
|
||||
private TimeSpan m_Duration = TimeSpan.FromSeconds(30.0); // default 30 sec duration
|
||||
private int m_Value = 10; // default value of 10
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Value { get { return m_Value; } set { m_Value = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlStr(ASerial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlStr()
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlStr(int value)
|
||||
{
|
||||
m_Value = value;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlStr(int value, double duration)
|
||||
{
|
||||
m_Value = value;
|
||||
m_Duration = TimeSpan.FromSeconds(duration);
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the mod
|
||||
if (AttachedTo is Mobile)
|
||||
{
|
||||
((Mobile)AttachedTo).AddStatMod(new StatMod(StatType.Str, "XmlStr" + Name, m_Value, m_Duration));
|
||||
}
|
||||
// and then remove the attachment
|
||||
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(Delete));
|
||||
|
||||
//Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlTitle : XmlAttachment
|
||||
{
|
||||
private string m_Title = null;// title string
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlTitle(ASerial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlTitle(string name)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Title = String.Empty;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlTitle(string name, string title)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Title = title;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlTitle(string name, string title, double expiresin)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Title = title;
|
||||
this.Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Title
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.m_Title;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.m_Title = value;
|
||||
// change the title
|
||||
if (this.AttachedTo is Mobile)
|
||||
{
|
||||
((Mobile)this.AttachedTo).InvalidateProperties();
|
||||
}
|
||||
if (this.AttachedTo is Item)
|
||||
{
|
||||
((Item)this.AttachedTo).InvalidateProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void AddTitles(object o, ObjectPropertyList list)
|
||||
{
|
||||
List<XmlAttachment> alist = XmlAttach.FindAttachments(o, typeof(XmlTitle));
|
||||
|
||||
if (alist != null && alist.Count > 0)
|
||||
{
|
||||
string titlestring = null;
|
||||
bool hastitle = false;
|
||||
foreach (XmlTitle t in alist)
|
||||
{
|
||||
if (t == null || t.Deleted)
|
||||
continue;
|
||||
|
||||
if (hastitle)
|
||||
{
|
||||
titlestring += '\n';
|
||||
}
|
||||
titlestring += Utility.FixHtml(t.Title);
|
||||
hastitle = true;
|
||||
}
|
||||
if (hastitle)
|
||||
list.Add(1070722, "<BASEFONT COLOR=#E6CC80>{0}<BASEFONT COLOR=#FFFFFF>", titlestring);
|
||||
}
|
||||
}
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)0);
|
||||
// version 0
|
||||
writer.Write((string)this.m_Title);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
this.m_Title = reader.ReadString();
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
// remove the title when deleted
|
||||
if (this.AttachedTo is Mobile)
|
||||
{
|
||||
((Mobile)this.AttachedTo).InvalidateProperties();
|
||||
}
|
||||
if (this.AttachedTo is Item)
|
||||
{
|
||||
((Item)this.AttachedTo).InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAttach()
|
||||
{
|
||||
base.OnAttach();
|
||||
|
||||
// apply the title immediately when attached
|
||||
if (this.AttachedTo is Mobile)
|
||||
{
|
||||
((Mobile)this.AttachedTo).InvalidateProperties();
|
||||
}
|
||||
if (this.AttachedTo is Item)
|
||||
{
|
||||
((Item)this.AttachedTo).InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if (from == null || from.AccessLevel < AccessLevel.Counselor)
|
||||
return null;
|
||||
|
||||
if (this.Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{2}: Title {0} expires in {1} mins", this.Title, this.Expiration.TotalMinutes, this.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{1}: Title {0}", this.Title, this.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,491 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlUse : XmlAttachment
|
||||
{
|
||||
private bool m_BlockDefaultUse;
|
||||
private string m_Condition; // additional condition required for use
|
||||
private string m_TargetingAction; // action performed when the target cursor is brought up
|
||||
private string m_TargetCondition; // condition test applied when target is selected to determine whether it is appropriate
|
||||
private string m_TargetFailureAction; // action performed if target condition is not met
|
||||
private string m_SuccessAction; // action performed on successful use or targeting
|
||||
private string m_FailureAction; // action performed if the player cannot use the object for reasons other than range, refractory, or maxuses
|
||||
private string m_RefractoryAction; // action performed if the object is used before the refractory interval expires
|
||||
private string m_MaxUsesAction; // action performed if the object is used when the maxuses are exceeded
|
||||
private int m_NUses = 0;
|
||||
private int m_MaxRange = 3; // must be within 3 tiles to use by default
|
||||
private int m_MaxTargetRange = 30; // must be within 30 tiles to target by default
|
||||
private int m_MaxUses = 0;
|
||||
private TimeSpan m_Refractory = TimeSpan.Zero;
|
||||
public DateTime m_EndTime;
|
||||
private bool m_RequireLOS = false;
|
||||
private bool m_AllowCarried = true;
|
||||
private bool m_TargetingEnabled = false;
|
||||
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool TargetingEnabled { get { return m_TargetingEnabled; } set { m_TargetingEnabled = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool AllowCarried { get { return m_AllowCarried; } set { m_AllowCarried = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool RequireLOS { get { return m_RequireLOS; } set { m_RequireLOS = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int MaxRange { get { return m_MaxRange; } set { m_MaxRange = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int MaxTargetRange { get { return m_MaxTargetRange; } set { m_MaxTargetRange = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int NUses { get { return m_NUses; } set { m_NUses = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int MaxUses { get { return m_MaxUses; } set { m_MaxUses = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TimeSpan Refractory { get { return m_Refractory; } set { m_Refractory = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool BlockDefaultUse { get { return m_BlockDefaultUse; } set { m_BlockDefaultUse = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Condition { get { return m_Condition; } set { m_Condition = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string TargetCondition { get { return m_TargetCondition; } set { m_TargetCondition = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string TargetingAction { get { return m_TargetingAction; } set { m_TargetingAction = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string TargetFailureAction { get { return m_TargetFailureAction; } set { m_TargetFailureAction = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string SuccessAction { get { return m_SuccessAction; } set { m_SuccessAction = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string FailureAction { get { return m_FailureAction; } set { m_FailureAction = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string RefractoryAction { get { return m_RefractoryAction; } set { m_RefractoryAction = value; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string MaxUsesAction { get { return m_MaxUsesAction; } set { m_MaxUsesAction = value; } }
|
||||
|
||||
public XmlUse(ASerial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
[Attachable]
|
||||
public XmlUse()
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlUse(int maxuses)
|
||||
{
|
||||
MaxUses = maxuses;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlUse(int maxuses, double refractory)
|
||||
{
|
||||
MaxUses = maxuses;
|
||||
Refractory = TimeSpan.FromSeconds(refractory);
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)3);
|
||||
// version 3
|
||||
writer.Write(m_MaxTargetRange);
|
||||
// version 2
|
||||
writer.Write(m_TargetingEnabled);
|
||||
writer.Write(m_TargetingAction);
|
||||
writer.Write(m_TargetCondition);
|
||||
writer.Write(m_TargetFailureAction);
|
||||
// version 1
|
||||
writer.Write(m_AllowCarried);
|
||||
// version 0
|
||||
writer.Write(m_RequireLOS);
|
||||
writer.Write(m_MaxRange);
|
||||
writer.Write(m_Refractory);
|
||||
writer.Write(m_EndTime - DateTime.UtcNow);
|
||||
writer.Write(m_MaxUses);
|
||||
writer.Write(m_NUses);
|
||||
writer.Write(m_BlockDefaultUse);
|
||||
writer.Write(m_Condition);
|
||||
writer.Write(m_SuccessAction);
|
||||
writer.Write(m_FailureAction);
|
||||
writer.Write(m_RefractoryAction);
|
||||
writer.Write(m_MaxUsesAction);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
switch (version)
|
||||
{
|
||||
case 3:
|
||||
m_MaxTargetRange = reader.ReadInt();
|
||||
goto case 2;
|
||||
case 2:
|
||||
m_TargetingEnabled = reader.ReadBool();
|
||||
m_TargetingAction = reader.ReadString();
|
||||
m_TargetCondition = reader.ReadString();
|
||||
m_TargetFailureAction = reader.ReadString();
|
||||
goto case 1;
|
||||
case 1:
|
||||
m_AllowCarried = reader.ReadBool();
|
||||
goto case 0;
|
||||
case 0:
|
||||
// version 0
|
||||
m_RequireLOS = reader.ReadBool();
|
||||
m_MaxRange = reader.ReadInt();
|
||||
Refractory = reader.ReadTimeSpan();
|
||||
TimeSpan remaining = reader.ReadTimeSpan();
|
||||
m_EndTime = DateTime.UtcNow + remaining;
|
||||
m_MaxUses = reader.ReadInt();
|
||||
m_NUses = reader.ReadInt();
|
||||
m_BlockDefaultUse = reader.ReadBool();
|
||||
m_Condition = reader.ReadString();
|
||||
m_SuccessAction = reader.ReadString();
|
||||
m_FailureAction = reader.ReadString();
|
||||
m_RefractoryAction = reader.ReadString();
|
||||
m_MaxUsesAction = reader.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteActions(Mobile mob, object target, string actions)
|
||||
{
|
||||
if (actions == null || actions.Length <= 0) return;
|
||||
// execute any action associated with it
|
||||
// allow for multiple action strings on a single line separated by a semicolon
|
||||
|
||||
string[] args = actions.Split(';');
|
||||
|
||||
for (int j = 0; j < args.Length; j++)
|
||||
{
|
||||
ExecuteAction(mob, target, args[j]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void ExecuteAction(Mobile mob, object target, string action)
|
||||
{
|
||||
if (action == null || action.Length <= 0) return;
|
||||
|
||||
string status_str = null;
|
||||
Server.Mobiles.XmlSpawner.SpawnObject TheSpawn = new Server.Mobiles.XmlSpawner.SpawnObject(null, 0);
|
||||
|
||||
TheSpawn.TypeName = action;
|
||||
string substitutedtypeName = BaseXmlSpawner.ApplySubstitution(null, target, mob, action);
|
||||
string typeName = BaseXmlSpawner.ParseObjectType(substitutedtypeName);
|
||||
|
||||
Point3D loc = new Point3D(0, 0, 0);
|
||||
Map map = null;
|
||||
|
||||
|
||||
if (target is Item)
|
||||
{
|
||||
Item ti = target as Item;
|
||||
if (ti.Parent == null)
|
||||
{
|
||||
loc = ti.Location;
|
||||
map = ti.Map;
|
||||
}
|
||||
else if (ti.RootParent is Item)
|
||||
{
|
||||
loc = ((Item)ti.RootParent).Location;
|
||||
map = ((Item)ti.RootParent).Map;
|
||||
}
|
||||
else if (ti.RootParent is Mobile)
|
||||
{
|
||||
loc = ((Mobile)ti.RootParent).Location;
|
||||
map = ((Mobile)ti.RootParent).Map;
|
||||
}
|
||||
|
||||
}
|
||||
else if (target is Mobile)
|
||||
{
|
||||
Mobile ti = target as Mobile;
|
||||
|
||||
loc = ti.Location;
|
||||
map = ti.Map;
|
||||
|
||||
}
|
||||
|
||||
if (BaseXmlSpawner.IsTypeOrItemKeyword(typeName))
|
||||
{
|
||||
BaseXmlSpawner.SpawnTypeKeyword(target, TheSpawn, typeName, substitutedtypeName, true, mob, loc, map, out status_str);
|
||||
}
|
||||
else
|
||||
{
|
||||
// its a regular type descriptor so find out what it is
|
||||
Type type = SpawnerType.GetType(typeName);
|
||||
try
|
||||
{
|
||||
string[] arglist = BaseXmlSpawner.ParseString(substitutedtypeName, 3, "/");
|
||||
object o = Server.Mobiles.XmlSpawner.CreateObject(type, arglist[0]);
|
||||
|
||||
if (o == null)
|
||||
{
|
||||
status_str = "invalid type specification: " + arglist[0];
|
||||
}
|
||||
else
|
||||
if (o is Mobile)
|
||||
{
|
||||
Mobile m = (Mobile)o;
|
||||
if (m is BaseCreature)
|
||||
{
|
||||
BaseCreature c = (BaseCreature)m;
|
||||
c.Home = loc; // Spawners location is the home point
|
||||
}
|
||||
|
||||
m.Location = loc;
|
||||
m.Map = map;
|
||||
|
||||
BaseXmlSpawner.ApplyObjectStringProperties(null, substitutedtypeName, m, mob, target, out status_str);
|
||||
}
|
||||
else
|
||||
if (o is Item)
|
||||
{
|
||||
Item item = (Item)o;
|
||||
BaseXmlSpawner.AddSpawnItem(null, target, TheSpawn, item, loc, map, mob, false, substitutedtypeName, out status_str);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
ReportError(mob, status_str);
|
||||
}
|
||||
|
||||
private void ReportError(Mobile mob, string status_str)
|
||||
{
|
||||
if (status_str != null && mob != null && !mob.Deleted && mob is PlayerMobile && mob.AccessLevel > AccessLevel.Player)
|
||||
{
|
||||
mob.SendMessage(33, String.Format("{0}:{1}", Name, status_str));
|
||||
}
|
||||
}
|
||||
|
||||
// return true to allow use
|
||||
private bool CheckCondition(Mobile from, object target)
|
||||
{
|
||||
// test the condition if there is one
|
||||
if (Condition != null && Condition.Length > 0)
|
||||
{
|
||||
string status_str;
|
||||
|
||||
return BaseXmlSpawner.CheckPropertyString(null, target, Condition, from, out status_str);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// return true to allow use
|
||||
private bool CheckTargetCondition(Mobile from, object target)
|
||||
{
|
||||
// test the condition if there is one
|
||||
if (TargetCondition != null && TargetCondition.Length > 0)
|
||||
{
|
||||
string status_str;
|
||||
|
||||
return BaseXmlSpawner.CheckPropertyString(null, target, TargetCondition, from, out status_str);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// return true to allow use
|
||||
private bool CheckRange(Mobile from, object target)
|
||||
{
|
||||
if (from == null || !(target is IEntity) || MaxRange < 0) return false;
|
||||
|
||||
Map map = ((IEntity)target).Map;
|
||||
Point3D loc = ((IEntity)target).Location;
|
||||
|
||||
if (map != from.Map) return false;
|
||||
|
||||
// check for allowed use in pack
|
||||
if (target is Item)
|
||||
{
|
||||
Item targetitem = (Item)target;
|
||||
// is it carried by the user?
|
||||
if (targetitem.RootParent == from)
|
||||
{
|
||||
return AllowCarried;
|
||||
}
|
||||
else
|
||||
// block use in other containers or on other mobiles
|
||||
if (targetitem.Parent != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool haslos = true;
|
||||
if (RequireLOS)
|
||||
{
|
||||
// check los as well
|
||||
haslos = from.InLOS(target);
|
||||
}
|
||||
|
||||
return from.InRange(loc, MaxRange) && haslos;
|
||||
}
|
||||
|
||||
public bool CheckMaxUses
|
||||
{
|
||||
get
|
||||
{
|
||||
// is there a use limit?
|
||||
if (MaxUses > 0 && NUses >= MaxUses) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CheckRefractory
|
||||
{
|
||||
get
|
||||
{
|
||||
// is there a refractory limit?
|
||||
// if it is still refractory then return
|
||||
if (Refractory > TimeSpan.Zero && DateTime.UtcNow < m_EndTime) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public void OutOfRange(Mobile from)
|
||||
{
|
||||
if (from == null) return;
|
||||
|
||||
from.SendLocalizedMessage(500446); // That is too far away.
|
||||
}
|
||||
|
||||
public class XmlUseTarget : Target
|
||||
{
|
||||
private object m_objectused;
|
||||
private XmlUse m_xa;
|
||||
|
||||
public XmlUseTarget(int range, object objectused, XmlUse xa)
|
||||
: base(range, true, TargetFlags.None)
|
||||
{
|
||||
m_objectused = objectused;
|
||||
m_xa = xa;
|
||||
CheckLOS = false;
|
||||
}
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if (from == null || targeted == null || m_xa == null) return;
|
||||
|
||||
// success
|
||||
if (m_xa.CheckTargetCondition(from, targeted))
|
||||
{
|
||||
m_xa.ExecuteActions(from, targeted, m_xa.SuccessAction);
|
||||
|
||||
m_xa.m_EndTime = DateTime.UtcNow + m_xa.Refractory;
|
||||
m_xa.NUses++;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_xa.ExecuteActions(from, targeted, m_xa.TargetFailureAction);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void TryToTarget(Mobile from, object target, XmlUse xa)
|
||||
{
|
||||
if (from == null) return;
|
||||
|
||||
ExecuteActions(from, target, TargetingAction);
|
||||
|
||||
if (xa != null)
|
||||
{
|
||||
from.Target = new XmlUseTarget(xa.MaxTargetRange, target, xa);
|
||||
}
|
||||
}
|
||||
|
||||
private void TryToUse(Mobile from, object target)
|
||||
{
|
||||
if (CheckRange(from, target) && CheckCondition(from, target) && CheckMaxUses && CheckRefractory)
|
||||
{
|
||||
// check for targeting
|
||||
if (TargetingEnabled)
|
||||
{
|
||||
TryToTarget(from, target, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// success
|
||||
ExecuteActions(from, target, SuccessAction);
|
||||
|
||||
m_EndTime = DateTime.UtcNow + Refractory;
|
||||
NUses++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// failure
|
||||
if (!CheckRange(from, target))
|
||||
{
|
||||
OutOfRange(from);
|
||||
}
|
||||
else if (!CheckRefractory)
|
||||
{
|
||||
ExecuteActions(from, target, RefractoryAction);
|
||||
}
|
||||
else if (!CheckMaxUses)
|
||||
{
|
||||
ExecuteActions(from, target, MaxUsesAction);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
ExecuteActions(from, target, FailureAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// disable the default use of the target
|
||||
public override bool BlockDefaultOnUse(Mobile from, object target)
|
||||
{
|
||||
return (BlockDefaultUse || !(CheckRange(from, target) && CheckCondition(from, target) && CheckMaxUses && CheckRefractory));
|
||||
}
|
||||
|
||||
// this is called when the attachment is on the user
|
||||
public override void OnUser(object target)
|
||||
{
|
||||
Mobile from = AttachedTo as Mobile;
|
||||
|
||||
TryToUse(from, target);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// this is called when the attachment is on the target being used
|
||||
public override void OnUse(Mobile from)
|
||||
{
|
||||
object target = AttachedTo;
|
||||
|
||||
// if a target tries to use itself, then ignore it, it will be handled by OnUser
|
||||
if (target == from) return;
|
||||
|
||||
TryToUse(from, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlValue : XmlAttachment
|
||||
{
|
||||
private int m_DataValue;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Value { get{ return m_DataValue; } set { m_DataValue = value; } }
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlValue(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlValue(string name, int value)
|
||||
{
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlValue(string name, int value, double expiresin)
|
||||
{
|
||||
Name = name;
|
||||
Value = value;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(m_DataValue);
|
||||
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
m_DataValue = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{2}: Value {0} expires in {1} mins",Value,Expiration.TotalMinutes, Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{1}: Value {0}",Value, Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.Mobiles;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Server.Engines.XmlSpawner2
|
||||
{
|
||||
public class XmlWeaponAbility : XmlAttachment
|
||||
{
|
||||
private WeaponAbility m_Ability = null; // default data
|
||||
|
||||
public WeaponAbility WeaponAbility
|
||||
{
|
||||
get { return m_Ability; }
|
||||
set { m_Ability = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Ability
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_Ability != null)
|
||||
{
|
||||
return m_Ability.GetType().Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value != null)
|
||||
{
|
||||
FieldInfo finfo = typeof(WeaponAbility).GetField(value);
|
||||
if (finfo != null && finfo.IsStatic && finfo.FieldType == typeof(WeaponAbility))
|
||||
{
|
||||
try
|
||||
{
|
||||
m_Ability = (WeaponAbility)finfo.GetValue(null);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Ability = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// These are the various ways in which the message attachment can be constructed.
|
||||
// These can be called via the [addatt interface, via scripts, via the spawner ATTACH keyword.
|
||||
// Other overloads could be defined to handle other types of arguments
|
||||
|
||||
// a serial constructor is REQUIRED
|
||||
public XmlWeaponAbility(ASerial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlWeaponAbility(string weaponability)
|
||||
{
|
||||
Ability = weaponability;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlWeaponAbility(string name, string weaponability)
|
||||
{
|
||||
Name = name;
|
||||
Ability = weaponability;
|
||||
}
|
||||
|
||||
[Attachable]
|
||||
public XmlWeaponAbility(string name, string weaponability, double expiresin)
|
||||
{
|
||||
Name = name;
|
||||
Ability = weaponability;
|
||||
Expiration = TimeSpan.FromMinutes(expiresin);
|
||||
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
// version 0
|
||||
writer.Write(Ability);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
// version 0
|
||||
Ability = reader.ReadString();
|
||||
}
|
||||
|
||||
public override string OnIdentify(Mobile from)
|
||||
{
|
||||
if(from == null || from.AccessLevel == AccessLevel.Player) return null;
|
||||
|
||||
if(Expiration > TimeSpan.Zero)
|
||||
{
|
||||
return String.Format("{2}: Weapon ability {0} expires in {1} mins", Ability, Expiration.TotalMinutes, Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Format("{1}: Weapon ability {0}", Ability, Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user