Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -0,0 +1,49 @@
using System;
using Server.Items;
namespace Server.Items
{
public abstract class Artifact : Item, IArtifact
{
[Constructable]
public Artifact(int itemID) : base(itemID)
{
}
public Artifact( Serial serial ) : base( serial )
{
}
[CommandProperty( AccessLevel.GameMaster )]
public virtual int ArtifactRarity
{
get{ return 0; }
set {}
}
public override bool ForceShowProperties{ get{ return true; } }
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
if(ArtifactRarity > 0)
list.Add( 1061078, ArtifactRarity.ToString() );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using Server.Items;
namespace Server.Items
{
public class SimpleArtifact : Artifact
{
private int m_ArtifactRarity = 0;
[CommandProperty( AccessLevel.GameMaster )]
public override int ArtifactRarity
{
get{ return m_ArtifactRarity; }
set {m_ArtifactRarity = value; InvalidateProperties();}
}
[Constructable]
public SimpleArtifact(int itemID) : base(itemID)
{
}
public SimpleArtifact( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( m_ArtifactRarity );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_ArtifactRarity = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,263 @@
using System;
using System.IO;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Commands;
using Server.Commands.Generic;
/*
** Sno's distro spawner importer/exporter
**
** [exportspawner filename - Saves distro spawners to XML to 'Saves/Spawners/filename'
**
** [importspawner filename - Restores distro spawners from 'Saves/Spawners/filename'. Note, this command does not check for
** duplication, so if you run it more than once you will end up with multiple spawners.
**
** These spawns can also be imported back in as XmlSpawners by using the '[xmlimportspawners Saves/Spawners/filename' command.
*/
namespace Server.Mobiles
{
public class SpawnerExporter
{
public static void Initialize()
{
TargetCommands.Register( new ExportSpawnerCommand() );
CommandSystem.Register("ImportSpawners", AccessLevel.Administrator, new CommandEventHandler(ImportSpawners_OnCommand));
}
public class ExportSpawnerCommand : BaseCommand
{
public ExportSpawnerCommand()
{
AccessLevel = AccessLevel.Administrator;
Supports = CommandSupport.Area | CommandSupport.Region | CommandSupport.Global | CommandSupport.Multi | CommandSupport.Single;
Commands = new string[]{ "ExportSpawner" };
ObjectTypes = ObjectTypes.Items;
Usage = "ExportSpawner <filename>";
Description = "Exports all Spawner objects to the specified filename.";
ListOptimized = true;
}
public override void ExecuteList( CommandEventArgs e, ArrayList list )
{
string filename = e.GetString( 0 );
ArrayList spawners = new ArrayList();
for ( int i = 0; i < list.Count; ++i )
{
if ( list[i] is Spawner )
{
Spawner spawner = (Spawner)list[i];
if ( spawner != null && !spawner.Deleted && spawner.Map != Map.Internal && spawner.Parent == null )
spawners.Add( spawner );
}
}
AddResponse( String.Format( "{0} spawners exported to Saves/Spawners/{1}.", spawners.Count.ToString(), filename ) );
ExportSpawners( spawners, filename );
}
public override bool ValidateArgs( BaseCommandImplementor impl, CommandEventArgs e )
{
if ( e.Arguments.Length >= 1 )
return true;
e.Mobile.SendMessage( "Usage: " + Usage );
return false;
}
private void ExportSpawners( ArrayList spawners, string filename )
{
if ( spawners.Count == 0 )
return;
if ( !Directory.Exists( "Saves/Spawners" ) )
Directory.CreateDirectory( "Saves/Spawners" );
string filePath = Path.Combine( "Saves/Spawners", filename );
using ( StreamWriter op = new StreamWriter( filePath ) )
{
XmlTextWriter xml = new XmlTextWriter( op );
xml.Formatting = Formatting.Indented;
xml.IndentChar = '\t';
xml.Indentation = 1;
xml.WriteStartDocument( true );
xml.WriteStartElement( "spawners" );
xml.WriteAttributeString( "count", spawners.Count.ToString() );
foreach ( Spawner spawner in spawners )
ExportSpawner( spawner, xml );
xml.WriteEndElement();
xml.Close();
}
}
private void ExportSpawner( Spawner spawner, XmlTextWriter xml )
{
xml.WriteStartElement( "spawner" );
xml.WriteStartElement( "count" );
xml.WriteString( spawner.MaxCount.ToString() );
xml.WriteEndElement();
xml.WriteStartElement( "group" );
xml.WriteString( spawner.Group.ToString() );
xml.WriteEndElement();
xml.WriteStartElement( "homerange" );
xml.WriteString( spawner.HomeRange.ToString() );
xml.WriteEndElement();
xml.WriteStartElement("walkingrange");
xml.WriteString(spawner.WalkingRange.ToString());
xml.WriteEndElement();
xml.WriteStartElement( "maxdelay" );
xml.WriteString( spawner.MaxDelay.ToString() );
xml.WriteEndElement();
xml.WriteStartElement( "mindelay" );
xml.WriteString( spawner.MinDelay.ToString() );
xml.WriteEndElement();
xml.WriteStartElement( "team" );
xml.WriteString( spawner.Team.ToString() );
xml.WriteEndElement();
xml.WriteStartElement( "creaturesname" );
foreach(var kvp in spawner.SpawnObjects)
{
xml.WriteStartElement( "creaturename" );
xml.WriteString(kvp.SpawnName);
xml.WriteEndElement();
}
xml.WriteEndElement();
// Item properties
xml.WriteStartElement( "name" );
xml.WriteString( spawner.Name );
xml.WriteEndElement();
xml.WriteStartElement( "location" );
xml.WriteString( spawner.Location.ToString() );
xml.WriteEndElement();
xml.WriteStartElement( "map" );
xml.WriteString( spawner.Map.ToString() );
xml.WriteEndElement();
xml.WriteEndElement();
}
}
[Usage( "ImportSpawners" )]
[Description( "Recreates Spawner items from the specified file." )]
public static void ImportSpawners_OnCommand( CommandEventArgs e )
{
if ( e.Arguments.Length >= 1 )
{
string filename = e.GetString( 0 );
string filePath = Path.Combine( "Saves/Spawners", filename );
if ( File.Exists( filePath ) )
{
XmlDocument doc = new XmlDocument();
doc.Load( filePath );
XmlElement root = doc["spawners"];
int successes = 0, failures = 0;
foreach ( XmlElement spawner in root.GetElementsByTagName( "spawner" ) )
{
try
{
ImportSpawner( spawner );
successes++;
}
catch { failures++; }
}
e.Mobile.SendMessage( "{0} spawners loaded successfully from {1}, {2} failures.", successes, filePath, failures );
}
else
{
e.Mobile.SendMessage( "File {0} does not exist.", filePath );
}
}
else
{
e.Mobile.SendMessage( "Usage: [ImportSpawners <filename>" );
}
}
private static string GetText( XmlElement node, string defaultValue )
{
if ( node == null )
return defaultValue;
return node.InnerText;
}
private static void ImportSpawner( XmlElement node )
{
int count = int.Parse( GetText( node["count"], "1" ) );
int homeRange = int.Parse( GetText( node["homerange"], "4" ) );
int walkingRange = int.Parse(GetText(node["walkingrange"], "-1"));
int team = int.Parse( GetText( node["team"], "0" ) );
bool group = bool.Parse( GetText( node["group"], "False" ) );
TimeSpan maxDelay = TimeSpan.Parse( GetText( node["maxdelay"], "10:00" ) );
TimeSpan minDelay = TimeSpan.Parse( GetText( node["mindelay"], "05:00" ) );
List<string> creaturesName = LoadCreaturesName( node["creaturesname"] );
string name = GetText( node["name"], "Spawner" );
Point3D location = Point3D.Parse( GetText( node["location"], "Error" ) );
Map map = Map.Parse( GetText( node["map"], "Error" ) );
Spawner spawner = new Spawner( count, minDelay, maxDelay, team, homeRange, creaturesName );
if (walkingRange >= 0)
spawner.WalkingRange = walkingRange;
spawner.Name = name;
spawner.MoveToWorld( location, map );
if ( spawner.Map == Map.Internal )
{
spawner.Delete();
throw new Exception( "Spawner created on Internal map." );
}
spawner.Respawn();
}
private static List<string> LoadCreaturesName(XmlElement node)
{
List<string> names = new List<string>();
if ( node != null )
{
foreach ( XmlElement ele in node.GetElementsByTagName( "creaturename" ) )
{
if ( ele != null )
names.Add( ele.InnerText );
}
}
return names;
}
}
}

View File

@@ -0,0 +1,163 @@
using System;
using Server.Mobiles;
/*
** Allows staff to quickly switch between player and their assigned staff levels by equipping or removing the cloak
** Also allows instant teleportation to a specified destination when double-clicked by the staff member.
*/
namespace Server.Items
{
public class StaffCloak : Cloak
{
private AccessLevel m_StaffLevel;
private Point3D m_HomeLoc;
private Map m_HomeMap;
[CommandProperty( AccessLevel.Administrator )]
public AccessLevel StaffLevel {
get
{
return m_StaffLevel;
}
set
{
m_StaffLevel = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public Point3D HomeLoc { get { return m_HomeLoc;} set { m_HomeLoc = value;} }
[CommandProperty( AccessLevel.GameMaster )]
public Map HomeMap { get { return m_HomeMap;} set { m_HomeMap = value;} }
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties(list);
list.Add( 1060658, "Level\t{0}", StaffLevel ); // ~1_val~: ~2_val~
}
#if(NEWPARENT)
public override void OnAdded(IEntity parent)
#else
public override void OnAdded(object parent)
#endif
{
base.OnAdded( parent );
// delete this if someone without the necessary access level picks it up or tries to equip it
if(RootParent is Mobile)
{
if (((Mobile) RootParent).AccessLevel != StaffLevel)
{
Delete();
return;
}
}
// when equipped, change access level to player
if ( parent is Mobile )
{
Mobile m =(Mobile) parent;
if (m.AccessLevel == StaffLevel)
{
m.AccessLevel = AccessLevel.Player;
// and make vuln
m.Blessed = false;
}
}
}
#if(NEWPARENT)
public override void OnRemoved( IEntity parent )
#else
public override void OnRemoved( object parent )
#endif
{
base.OnRemoved( parent );
// restore access level to the specified level
if ( parent is Mobile && !Deleted)
{
Mobile m = (Mobile) parent;
// restore their assigned staff level
m.AccessLevel = StaffLevel;
// and make invuln
m.Blessed = true;
}
}
public override void OnDoubleClick( Mobile from )
{
if(from == null) return;
if(HomeMap != Map.Internal && HomeMap != null && from.AccessLevel == StaffLevel)
{
// teleport them to the specific location
from.MoveToWorld(HomeLoc, HomeMap);
}
}
[Constructable]
public StaffCloak() : base()
{
StaffLevel= AccessLevel.Administrator; // assign admin staff level by default
LootType = LootType.Blessed;
Name = "Staff Cloak";
Weight = 0;
}
public StaffCloak( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
// version
writer.Write( (int) 0 );
// version 0
writer.Write( (int) m_StaffLevel );
writer.Write( m_HomeLoc );
string mapname = null;
if(m_HomeMap != null)
{
mapname = m_HomeMap.Name;
}
writer.Write( mapname );
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch(version)
{
case 0:
m_StaffLevel = (AccessLevel)reader.ReadInt();
m_HomeLoc = reader.ReadPoint3D();
string mapname = reader.ReadString();
try{
m_HomeMap = Map.Parse(mapname);
} catch{}
break;
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
using System;
using System.Text;
using Server;
using Server.Targeting;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Items
{
public class ItemFlags
{
public const int StealableFlag = 0x00200000;
public const int TakenFlag = 0x00100000;
public static void Initialize()
{
CommandSystem.Register( "Stealable", AccessLevel.GameMaster, new CommandEventHandler( SetStealable_OnCommand ) );
CommandSystem.Register( "Flag", AccessLevel.GameMaster, new CommandEventHandler( GetFlag_OnCommand ) );
}
public static void SetStealable(Item target, bool value)
{
if(target != null)
target.SetSavedFlag( StealableFlag, value);
}
public static bool GetStealable(Item target)
{
if(target != null)
return target.GetSavedFlag(StealableFlag);
else
return false;
}
public static void SetTaken(Item target, bool value)
{
if(target != null)
{
target.SetSavedFlag( TakenFlag, value);
}
}
public static bool GetTaken(Item target)
{
if(target != null)
return target.GetSavedFlag(TakenFlag);
else
return false;
}
[Usage( "Flag flagfield" )]
[Description( "Gets the state of the specified SavedFlag on any item" )]
public static void GetFlag_OnCommand( CommandEventArgs e )
{
int flag=0;
bool error = false;
if( e.Arguments.Length > 0 )
{
if(e.Arguments[0].StartsWith( "0x" ))
{
try{flag = Convert.ToInt32( e.Arguments[0].Substring( 2 ), 16 ); } catch { error = true;}
} else
{
try{flag = int.Parse(e.Arguments[0]); } catch { error = true;}
}
}
if(!error)
{
e.Mobile.Target = new GetFlagTarget(e,flag);
} else
{
try{
e.Mobile.SendMessage(33,"Flag: Bad flagfield argument");
} catch {}
}
}
private class GetFlagTarget : Target
{
private CommandEventArgs m_e;
private int m_flag;
public GetFlagTarget( CommandEventArgs e, int flag) : base ( 30, false, TargetFlags.None )
{
m_e = e;
m_flag = flag;
}
protected override void OnTarget( Mobile from, object targeted )
{
if(targeted is Item)
{
bool state = ((Item)targeted).GetSavedFlag(m_flag);
from.SendMessage("Flag (0x{0:X}) = {1}",m_flag,state);
} else
{
from.SendMessage("Must target an Item");
}
}
}
[Usage( "Stealable [true/false]" )]
[Description( "Sets/gets the stealable flag on any item" )]
public static void SetStealable_OnCommand( CommandEventArgs e )
{
bool state = false;
bool error = false;
if( e.Arguments.Length > 0 ){
try{state = bool.Parse(e.Arguments[0]); } catch { error = true;}
}
if(!error)
{
e.Mobile.Target = new SetStealableTarget(e, state);
}
}
private class SetStealableTarget : Target
{
private CommandEventArgs m_e;
private bool m_state;
private bool set = false;
public SetStealableTarget( CommandEventArgs e, bool state) : base ( 30, false, TargetFlags.None )
{
m_e = e;
m_state = state;
if( e.Arguments.Length > 0 )
{
set = true;
}
}
protected override void OnTarget( Mobile from, object targeted )
{
if(targeted is Item)
{
if(set)
{
SetStealable(((Item)targeted), m_state);
}
bool state = GetStealable((Item)targeted);
from.SendMessage("Stealable = {0}",state);
} else
{
from.SendMessage("Must target an Item");
}
}
}
}
}

View File

@@ -0,0 +1,65 @@
#define CLIENT6017
using System;
using System.IO;
using System.Text;
using Server;
using Server.Network;
using Server.Items;
using Server.Mobiles;
using Server.Engines.Quests;
namespace Server.Engines.XmlSpawner2
{
public class PacketHandlerOverrides
{
public static void Initialize()
{
//
// this will replace the default packet handlers with XmlSpawner2 versions.
// The delay call is to make sure they are assigned after the core default assignments.
//
// If you dont want these packet handler overrides to be applied, just comment them out here.
//
// This will replace the default packet handler for basebooks content change. This allows the
// use of the text entry book interface for editing spawner entries.
// Regular BaseBooks will still call their default handlers for ContentChange and HeaderChange
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(ContentChangeOverride));
// this replaces the default packet handler for Use requests. Items and Mobiles will still
// behave exactly the same way, it simply adds a hook in to call the OnUse method for attachments
// they might have.
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( UseReqOverride ) );
// This will REPLACE the default packet handler called when the quest button on the paperdoll is pressed with the xmlquest gump.
//Timer.DelayCall(TimeSpan.Zero, new TimerCallback(QuestButtonOverride));
// This will ADD the xmlquest gump to the default packet handler called when the quest button on the paperdoll is pressed.
EventSink.QuestGumpRequest += new QuestGumpRequestHandler(XmlQuest.QuestButton);
}
public static void ContentChangeOverride()
{
PacketHandlers.Register(0x66, 0, true, new OnPacketReceive(XmlTextEntryBook.ContentChange));
#if(CLIENT6017)
PacketHandlers.Register6017(0x66, 0, true, new OnPacketReceive(XmlTextEntryBook.ContentChange));
#endif
}
public static void UseReqOverride()
{
PacketHandlers.Register(0x06, 5, true, new OnPacketReceive(XmlAttach.UseReq));
#if(CLIENT6017)
PacketHandlers.Register6017(0x06, 5, true, new OnPacketReceive(XmlAttach.UseReq));
#endif
}
public static void QuestButtonOverride()
{
PacketHandlers.RegisterEncoded( 0x32, true, new OnEncodedPacketReceive( XmlQuest.QuestButton ) );
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,527 @@
using System;
using System.Text;
using Server;
using Server.Commands;
using Server.Network;
using System.Collections.Generic;
using Server.Mobiles;
using Server.Targeting;
using Server.Items;
namespace Server.Engines.XmlSpawner2
{
public interface IXmlAttachment
{
ASerial Serial { get; }
string Name { get; set; }
TimeSpan Expiration { get; set; }
DateTime ExpirationEnd { get; }
DateTime CreationTime { get; }
bool Deleted { get; }
bool DoDelete { get; set; }
bool CanActivateInBackpack { get; }
bool CanActivateEquipped { get; }
bool CanActivateInWorld { get; }
bool HandlesOnSpeech { get; }
void OnSpeech(SpeechEventArgs args);
bool HandlesOnMovement { get; }
void OnMovement(MovementEventArgs args);
bool HandlesOnKill { get; }
void OnKill(Mobile killed, Mobile killer);
void OnBeforeKill(Mobile killed, Mobile killer);
bool HandlesOnKilled { get; }
void OnKilled(Mobile killed, Mobile killer);
void OnBeforeKilled(Mobile killed, Mobile killer);
/*
bool HandlesOnSkillUse { get; }
void OnSkillUse( Mobile m, Skill skill, bool success);
*/
object AttachedTo { get; set; }
object OwnedBy { get; set; }
bool CanEquip(Mobile from);
void OnEquip(Mobile from);
void OnRemoved(object parent);
void OnAttach();
void OnReattach();
void OnUse(Mobile from);
void OnUser(object target);
bool BlockDefaultOnUse(Mobile from, object target);
bool OnDragLift(Mobile from, Item item);
string OnIdentify(Mobile from);
string DisplayedProperties(Mobile from);
void AddProperties(ObjectPropertyList list);
string AttachedBy { get; }
void OnDelete();
void Delete();
void InvalidateParentProperties();
void SetAttachedBy(string name);
void OnTrigger(object activator, Mobile from);
void OnWeaponHit(Mobile attacker, Mobile defender, BaseWeapon weapon, int damageGiven);
int OnArmorHit(Mobile attacker, Mobile defender, Item armor, BaseWeapon weapon, int damageGiven);
void Serialize(GenericWriter writer);
void Deserialize(GenericReader reader);
}
public abstract class XmlAttachment : IXmlAttachment
{
// ----------------------------------------------
// Private fields
// ----------------------------------------------
private ASerial m_Serial;
private string m_Name;
private object m_AttachedTo;
private object m_OwnedBy;
private string m_AttachedBy;
private bool m_Deleted;
private AttachmentTimer m_ExpirationTimer;
private TimeSpan m_Expiration = TimeSpan.Zero; // no expiration by default
private DateTime m_ExpirationEnd;
private DateTime m_CreationTime; // when the attachment was made
// ----------------------------------------------
// Public properties
// ----------------------------------------------
[CommandProperty(AccessLevel.GameMaster)]
public DateTime CreationTime { get { return m_CreationTime; } }
public bool Deleted { get { return m_Deleted; } }
public bool DoDelete { get { return false; } set { if (value == true) Delete(); } }
[CommandProperty(AccessLevel.GameMaster)]
public int SerialValue { get { return m_Serial.Value; } }
public ASerial Serial { get { return m_Serial; } set { m_Serial = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public TimeSpan Expiration
{
get
{
// if the expiration timer is running then return the remaining time
if (m_ExpirationTimer != null)
{
return m_ExpirationEnd - DateTime.UtcNow;
}
else
return m_Expiration;
}
set
{
m_Expiration = value;
// if it is already attached to something then set the expiration timer
if (m_AttachedTo != null)
{
DoTimer(m_Expiration);
}
}
}
public DateTime ExpirationEnd
{
get { return m_ExpirationEnd; }
}
[CommandProperty(AccessLevel.GameMaster)]
public virtual bool CanActivateInBackpack { get { return true; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual bool CanActivateEquipped { get { return true; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual bool CanActivateInWorld { get { return true; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual bool HandlesOnSpeech { get { return false; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual bool HandlesOnMovement { get { return false; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual bool HandlesOnKill { get { return false; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual bool HandlesOnKilled { get { return false; } }
/*
[CommandProperty( AccessLevel.GameMaster )]
public virtual bool HandlesOnSkillUse { get{return false; } }
*/
[CommandProperty(AccessLevel.GameMaster)]
public virtual string Name { get { return m_Name; } set { m_Name = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual object Attached { get { return m_AttachedTo; } }
public virtual object AttachedTo { get { return m_AttachedTo; } set { m_AttachedTo = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual string AttachedBy { get { return m_AttachedBy; } }
public virtual object OwnedBy { get { return m_OwnedBy; } set { m_OwnedBy = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual object Owner { get { return m_OwnedBy; } }
// ----------------------------------------------
// Private methods
// ----------------------------------------------
private void DoTimer(TimeSpan delay)
{
m_ExpirationEnd = DateTime.UtcNow + delay;
if (m_ExpirationTimer != null)
m_ExpirationTimer.Stop();
m_ExpirationTimer = new AttachmentTimer(this, delay);
m_ExpirationTimer.Start();
}
// a timer that can be implement limited lifetime attachments
private class AttachmentTimer : Timer
{
private XmlAttachment m_Attachment;
public AttachmentTimer(XmlAttachment attachment, TimeSpan delay)
: base(delay)
{
Priority = TimerPriority.OneSecond;
m_Attachment = attachment;
}
protected override void OnTick()
{
m_Attachment.Delete();
}
}
// ----------------------------------------------
// Constructors
// ----------------------------------------------
public XmlAttachment()
{
m_CreationTime = DateTime.UtcNow;
// get the next unique serial id
m_Serial = ASerial.NewSerial();
// register the attachment in the serial keyed dictionary
XmlAttach.HashSerial(m_Serial, this);
}
// needed for deserialization
public XmlAttachment(ASerial serial)
{
m_Serial = serial;
}
// ----------------------------------------------
// Public methods
// ----------------------------------------------
public static void Initialize()
{
XmlAttach.CleanUp();
}
public virtual bool CanEquip(Mobile from)
{
return true;
}
public virtual void OnEquip(Mobile from)
{
}
public virtual void OnRemoved(object parent)
{
}
public virtual void OnAttach()
{
// start up the expiration timer on attachment
if (m_Expiration > TimeSpan.Zero)
DoTimer(m_Expiration);
}
public virtual void OnReattach()
{
}
public virtual void OnUse(Mobile from)
{
}
public virtual void OnUser(object target)
{
}
public virtual bool BlockDefaultOnUse(Mobile from, object target)
{
return false;
}
public virtual bool OnDragLift(Mobile from, Item item)
{
return true;
}
public void SetAttachedBy(string name)
{
m_AttachedBy = name;
}
public virtual void OnSpeech(SpeechEventArgs args)
{
}
public virtual void OnMovement(MovementEventArgs args)
{
}
public virtual void OnKill(Mobile killed, Mobile killer)
{
}
public virtual void OnBeforeKill(Mobile killed, Mobile killer)
{
}
public virtual void OnKilled(Mobile killed, Mobile killer)
{
}
public virtual void OnBeforeKilled(Mobile killed, Mobile killer)
{
}
/*
public virtual void OnSkillUse( Mobile m, Skill skill, bool success)
{
}
*/
public virtual void OnWeaponHit(Mobile attacker, Mobile defender, BaseWeapon weapon, int damageGiven)
{
}
public virtual int OnArmorHit(Mobile attacker, Mobile defender, Item armor, BaseWeapon weapon, int damageGiven)
{
return 0;
}
public virtual string OnIdentify(Mobile from)
{
return null;
}
public virtual string DisplayedProperties(Mobile from)
{
return OnIdentify(from);
}
public virtual void AddProperties(ObjectPropertyList list)
{
}
public void InvalidateParentProperties()
{
if (AttachedTo is Item)
{
((Item)AttachedTo).InvalidateProperties();
}
}
public void SafeItemDelete(Item item)
{
Timer.DelayCall(TimeSpan.Zero, new TimerStateCallback(DeleteItemCallback), new object[] { item });
}
public void DeleteItemCallback(object state)
{
object[] args = (object[])state;
Item item = args[0] as Item;
if (item != null)
{
// delete the item
item.Delete();
}
}
public void SafeMobileDelete(Mobile mob)
{
Timer.DelayCall(TimeSpan.Zero, new TimerStateCallback(DeleteMobileCallback), new object[] { mob });
}
public void DeleteMobileCallback(object state)
{
object[] args = (object[])state;
Mobile mob = args[0] as Mobile;
if (mob != null)
{
// delete the mobile
mob.Delete();
}
}
public void Delete()
{
if (m_Deleted) return;
m_Deleted = true;
if (m_ExpirationTimer != null)
m_ExpirationTimer.Stop();
OnDelete();
// dereference the attachment object
AttachedTo = null;
OwnedBy = null;
}
public virtual void OnDelete()
{
}
public virtual void OnTrigger(object activator, Mobile from)
{
}
public virtual void Serialize(GenericWriter writer)
{
writer.Write((int)2);
// version 2
writer.Write(m_AttachedBy);
// version 1
if (OwnedBy is Item)
{
writer.Write((int)0);
writer.Write((Item)OwnedBy);
}
else
if (OwnedBy is Mobile)
{
writer.Write((int)1);
writer.Write((Mobile)OwnedBy);
}
else
writer.Write((int)-1);
// version 0
writer.Write(Name);
// if there are any active timers, then serialize
writer.Write(m_Expiration);
if (m_ExpirationTimer != null)
{
writer.Write(m_ExpirationEnd - DateTime.UtcNow);
}
else
{
writer.Write(TimeSpan.Zero);
}
writer.Write(m_CreationTime);
}
public virtual void Deserialize(GenericReader reader)
{
int version = reader.ReadInt();
switch (version)
{
case 2:
m_AttachedBy = reader.ReadString();
goto case 1;
case 1:
int owned = reader.ReadInt();
if (owned == 0)
{
OwnedBy = reader.ReadItem();
}
else
if (owned == 1)
{
OwnedBy = reader.ReadMobile();
}
else
OwnedBy = null;
goto case 0;
case 0:
// version 0
Name = (string)reader.ReadString();
m_Expiration = reader.ReadTimeSpan();
TimeSpan remaining = (TimeSpan)reader.ReadTimeSpan();
if (remaining > TimeSpan.Zero)
DoTimer(remaining);
m_CreationTime = reader.ReadDateTime();
break;
}
}
}
}

View File

@@ -0,0 +1,711 @@
using System;
using System.Data;
using System.IO;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Network;
using Server.Gumps;
using Server.Targeting;
using System.Reflection;
using Server.Commands;
using Server.Commands.Generic;
using CPA = Server.CommandPropertyAttribute;
using System.Xml;
using Server.Spells;
using System.Text;
using Server.Accounting;
using Server.Engines.XmlSpawner2;
/*
** XmlGetAtt
** Version 1.00
** updated 10/24/04
** ArteGordon
**
*/
namespace Server.Mobiles
{
public class XmlGetAttGump : Gump
{
private const int MaxEntries = 18;
private const int MaxEntriesPerPage = 18;
private object m_TargetObject;
private bool Dosearchtype;
private bool Dosearchname;
private bool Dosearchage;
private bool Searchagedirection;
private double Searchage;
private string Searchtype;
private string Searchname;
private bool Sorttype;
private bool Sortname;
private Mobile m_From;
private bool Descendingsort;
private int Selected;
private int DisplayFrom;
private bool [] m_SelectionList;
private bool SelectAll = false;
private List<XmlAttachment> m_SearchList;
public static void Initialize()
{
CommandSystem.Register( "XmlGetAtt", AccessLevel.GameMaster, new CommandEventHandler( XmlGetAtt_OnCommand ) );
}
private bool TestAge(object o)
{
if(Searchage <= 0) return true;
if(o is XmlAttachment){
XmlAttachment a = (XmlAttachment)o;
if(Searchagedirection)
{
// true means allow only mobs greater than the age
if((DateTime.UtcNow - a.CreationTime) > TimeSpan.FromHours(Searchage)) return true;
}
else
{
// false means allow only mobs less than the age
if((DateTime.UtcNow - a.CreationTime) < TimeSpan.FromHours(Searchage)) return true;
}
}
return false;
}
private List<XmlAttachment> Search(object target, out string status_str)
{
status_str = null;
List<XmlAttachment> newarray = new List<XmlAttachment>();
Type targetType = null;
// if the type is specified then get the search type
if(Dosearchtype && Searchtype != null){
targetType = SpawnerType.GetType( Searchtype );
if(targetType == null){
status_str = "Invalid type: " + Searchtype;
return newarray;
}
}
List<XmlAttachment> attachments = XmlAttach.FindAttachments(target);
// do the search through attachments
if(attachments != null)
foreach(XmlAttachment i in attachments)
{
bool hastype = false;
bool hasname = false;
if(i == null || i.Deleted ) continue;
// check for type
if(Dosearchtype && (i.GetType().IsSubclassOf(targetType) || i.GetType().Equals(targetType)))
{
hastype = true;
}
if(Dosearchtype && !hastype) continue;
// check for name
if (Dosearchname && (i.Name != null) && (Searchname != null) && (i.Name.ToLower().IndexOf(Searchname.ToLower()) >= 0))
{
hasname = true;
}
if(Dosearchname && !hasname) continue;
// satisfied all conditions so add it
newarray.Add(i);
}
return newarray;
}
private class GetAttachTarget : Target
{
private CommandEventArgs m_e;
public GetAttachTarget( CommandEventArgs e) : base ( 30, false, TargetFlags.None )
{
m_e = e;
}
protected override void OnTarget( Mobile from, object targeted )
{
if(from == null || targeted == null) return;
from.SendGump( new XmlGetAttGump(from, targeted, 0,0));
}
}
[Usage( "XmlGetAtt" )]
[Description( "Gets attachments on an object" )]
public static void XmlGetAtt_OnCommand( CommandEventArgs e )
{
e.Mobile.Target = new GetAttachTarget(e);
}
public XmlGetAttGump(Mobile from, object targeted, int x, int y) : this(from, targeted, true, false,
false, false, false,
null,null, false, 0,
null, -1, 0,
false,false,
false, null, x, y)
{
}
public XmlGetAttGump( Mobile from, object targeted, bool firststart, bool descend,
bool dosearchtype, bool dosearchname, bool dosearchage,
string searchtype, string searchname, bool searchagedirection, double searchage,
List<XmlAttachment> searchlist, int selected, int displayfrom,
bool sorttype, bool sortname,
bool selectall, bool [] selectionlist, int X, int Y ) : base( X,Y )
{
m_TargetObject = targeted;
m_From = from;
m_SelectionList = selectionlist;
if(m_SelectionList == null){
m_SelectionList = new bool[MaxEntries];
}
SelectAll = selectall;
Sorttype = sorttype;
Sortname = sortname;
DisplayFrom = displayfrom;
Selected = selected;
Descendingsort = descend;
Dosearchtype = dosearchtype;
Dosearchname = dosearchname;
Dosearchage = dosearchage;
Searchagedirection = searchagedirection;
Searchage = searchage;
Searchtype = searchtype;
Searchname = searchname;
m_SearchList = searchlist;
if(firststart)
{
string status_str;
m_SearchList = Search(m_TargetObject,out status_str);
}
// prepare the page
AddPage( 0 );
AddBackground( 0, 0, 640, 474, 5054 );
AddAlphaRegion( 0, 0, 640, 474 );
string tnamestr = null;
if(targeted is Item)
{
tnamestr = ((Item)targeted).Name;
} else
if(targeted is Mobile)
{
tnamestr = ((Mobile)targeted).Name;
}
AddLabel( 2, 0, 0x33, String.Format( "Attachments on {0} : {1}", targeted.GetType().Name, tnamestr ) );
// add the Sort button
AddButton( 5, 450, 0xFAB, 0xFAD, 700, GumpButtonType.Reply, 0 );
AddLabel( 38, 450, 0x384, "Sort" );
// add the sort direction button
if(Descendingsort){
AddButton( 75, 453, 0x15E2, 0x15E6, 701, GumpButtonType.Reply, 0 );
AddLabel( 100, 450, 0x384, "descend" );
} else {
AddButton( 75, 453, 0x15E0, 0x15E4, 701, GumpButtonType.Reply, 0 );
AddLabel( 100, 450, 0x384, "ascend" );
}
// add the Sort on type toggle
AddRadio( 155, 450, 0xD2,0xD3, Sorttype, 0 );
AddLabel( 155, 425, 0x384, "type" );
// add the Sort on name toggle
AddRadio( 200, 450, 0xD2,0xD3, Sortname, 1 );
AddLabel( 200, 425, 0x384, "name" );
AddLabel( 42, 13, 0x384, "Name" );
AddLabel( 145, 13, 0x384, "Type" );
AddLabel( 285, 13, 0x384, "Created" );
AddLabel( 425, 13, 0x384, "Expires In" );
AddLabel( 505, 13, 0x384, "Attached By" );
// add the Delete button
AddButton( 250, 450, 0xFB1, 0xFB3, 156, GumpButtonType.Reply, 0 );
AddLabel( 283, 450, 0x384, "Delete" );
// add the page buttons
for(int i = 0;i<(int)(MaxEntries/MaxEntriesPerPage);i++){
//AddButton( 38+i*30, 365, 2206, 2206, 0, GumpButtonType.Page, 1+i );
AddButton( 418+i*25, 450, 0x8B1+i, 0x8B1+i, 0, GumpButtonType.Page, 1+i );
}
// add the advance pageblock buttons
AddButton( 415+25*(int)(MaxEntries/MaxEntriesPerPage), 450, 0x15E1, 0x15E5, 201, GumpButtonType.Reply, 0 ); // block forward
AddButton( 395, 450, 0x15E3, 0x15E7, 202, GumpButtonType.Reply, 0 ); // block backward
// add the displayfrom entry
AddLabel( 460, 450, 0x384, "Display" );
AddImageTiled( 500, 450, 60, 21, 0xBBC );
AddTextEntry( 501, 450, 60, 21, 0, 400, DisplayFrom.ToString() );
AddButton( 560, 450, 0xFAB, 0xFAD, 9998, GumpButtonType.Reply, 0 );
// display the item list
if(m_SearchList != null){
AddLabel( 320, 425, 68, String.Format("Found {0} attachments",m_SearchList.Count) );
AddLabel( 500, 425, 68, String.Format("Displaying {0}-{1}",DisplayFrom,
(DisplayFrom + MaxEntries < m_SearchList.Count ? DisplayFrom + MaxEntries : m_SearchList.Count)) );
}
// display the select-all-displayed toggle
AddButton( 620, 5, 0xD2, 0xD3, 3999, GumpButtonType.Reply, 0 );
// display the select-all toggle
AddButton( 600, 5, (SelectAll? 0xD3:0xD2), (SelectAll? 0xD2:0xD3), 3998, GumpButtonType.Reply, 0 );
for ( int i = 0; i < MaxEntries; i++ )
{
int index = i + DisplayFrom;
if(m_SearchList == null || index >= m_SearchList.Count) break;
int page = (int)(i/MaxEntriesPerPage);
if(i%MaxEntriesPerPage == 0){
AddPage(page+1);
}
// background for search results area
//AddImageTiled( 235, 22 * (i%MaxEntriesPerPage) + 30, 386, 23, 0x52 );
//AddImageTiled( 236, 22 * (i%MaxEntriesPerPage) + 31, 384, 21, 0xBBC );
// add the Props button for each entry
AddButton( 5, 22 * (i%MaxEntriesPerPage) + 30, 0xFAB, 0xFAD, 3000+i, GumpButtonType.Reply, 0 );
string namestr = null;
string typestr = null;
string expirestr = null;
//string description = null;
string attachedby = null;
string created = null;
int texthue = 0;
object o = (object)m_SearchList[index];
if(o is XmlAttachment){
XmlAttachment a = m_SearchList[index];
namestr = a.Name;
typestr = a.GetType().Name;
expirestr = a.Expiration.ToString();
//description = a.OnIdentify(m_From);
created = a.CreationTime.ToString();
attachedby = a.AttachedBy;
}
bool sel=false;
if(m_SelectionList != null && i < m_SelectionList.Length){
sel = m_SelectionList[i];
}
if(sel) texthue = 33;
if(i == Selected) texthue = 68;
// display the name
AddImageTiled( 36, 22 * (i%MaxEntriesPerPage) + 31, 102, 21, 0xBBC );
AddLabelCropped( 38, 22 * (i%MaxEntriesPerPage) + 31, 100, 21, texthue, namestr );
// display the type
AddImageTiled( 140, 22 * (i%MaxEntriesPerPage) + 31, 133, 21, 0xBBC );
AddLabelCropped( 140, 22 * (i%MaxEntriesPerPage) + 31, 133, 21, texthue, typestr );
// display the creation time
AddImageTiled( 275, 22 * (i%MaxEntriesPerPage) + 31, 138, 21, 0xBBC );
AddLabelCropped( 275, 22 * (i%MaxEntriesPerPage) + 31, 138, 21, texthue, created );
// display the expiration
AddImageTiled( 415, 22 * (i%MaxEntriesPerPage) + 31, 78, 21, 0xBBC );
AddLabelCropped( 415, 22 * (i%MaxEntriesPerPage) + 31, 78, 21, texthue, expirestr );
// display the attachedby
AddImageTiled( 495, 22 * (i%MaxEntriesPerPage) + 31, 125, 21, 0xBBC );
AddLabelCropped( 495, 22 * (i%MaxEntriesPerPage) + 31,105, 21, texthue, attachedby );
// display the descriptio button
AddButton( 600, 22 * (i%MaxEntriesPerPage) + 32, 0x5689, 0x568A, 5000+i, GumpButtonType.Reply, 0 );
// display the selection button
AddButton( 620, 22 * (i%MaxEntriesPerPage) + 32, (sel? 0xD3:0xD2), (sel? 0xD2:0xD3), 4000+i, GumpButtonType.Reply, 0 );
}
}
private void DoShowProps(int index)
{
if(m_From == null || m_From.Deleted) return;
if(index < m_SearchList.Count)
{
XmlAttachment x = m_SearchList[index];
if(x == null || x.Deleted ) return;
m_From.SendGump( new PropertiesGump( m_From, x ) );
}
}
private void SortFindList()
{
if(m_SearchList != null && m_SearchList.Count > 0){
if(Sorttype){
this.m_SearchList.Sort( new ListTypeSorter(Descendingsort) );
} else
if(Sortname){
this.m_SearchList.Sort( new ListNameSorter(Descendingsort) );
}
}
}
private class ListTypeSorter : IComparer<XmlAttachment>
{
private bool Dsort;
public ListTypeSorter(bool descend) : base ()
{
Dsort = descend;
}
public int Compare( XmlAttachment x, XmlAttachment y )
{
string xstr=null;
string ystr=null;
string str=null;
str = x.GetType().ToString();
if(str != null){
string [] arglist = str.Split('.');
xstr = arglist[arglist.Length-1];
}
str = null;
str = y.GetType().ToString();
if(str != null){
string [] arglist = str.Split('.');
ystr = arglist[arglist.Length-1];
}
if(Dsort)
return String.Compare(ystr, xstr, true);
else
return String.Compare(xstr, ystr, true);
}
}
private class ListNameSorter : IComparer<XmlAttachment>
{
private bool Dsort;
public ListNameSorter(bool descend) : base ()
{
Dsort = descend;
}
public int Compare( XmlAttachment x, XmlAttachment y )
{
string xstr=null;
string ystr=null;
xstr = x.Name;
ystr = y.Name;
if(Dsort)
return String.Compare(ystr, xstr, true);
else
return String.Compare(xstr, ystr, true);
}
}
private void Refresh(NetState state)
{
state.Mobile.SendGump( new XmlGetAttGump(this.m_From, this.m_TargetObject, false, this.Descendingsort,
this.Dosearchtype, this.Dosearchname, this.Dosearchage,
this.Searchtype, this.Searchname, this.Searchagedirection, this.Searchage,
this.m_SearchList, this.Selected, this.DisplayFrom,
this.Sorttype, this.Sortname,
this.SelectAll, this.m_SelectionList, this.X, this.Y));
}
public override void OnResponse( NetState state, RelayInfo info )
{
if(info == null || state == null || state.Mobile == null) return;
int radiostate = -1;
if(info.Switches.Length > 0){
radiostate = info.Switches[0];
}
// read the text entries for the search criteria
Searchage = 0;
TextRelay tr = info.GetTextEntry( 400 ); // displayfrom info
try{
DisplayFrom = int.Parse(tr.Text);
} catch{}
switch ( info.ButtonID )
{
case 0: // Close
{
return;
}
case 156: // Delete selected items
{
Refresh(state);
int allcount = 0;
if(m_SearchList != null)
allcount = m_SearchList.Count;
state.Mobile.SendGump( new XmlConfirmDeleteGump(state.Mobile, m_TargetObject, m_SearchList, m_SelectionList, DisplayFrom, SelectAll, allcount) );
return;
}
case 201: // forward block
{
// clear the selections
if(m_SelectionList != null && !SelectAll) Array.Clear(m_SelectionList,0,m_SelectionList.Length);
if(m_SearchList != null && DisplayFrom + MaxEntries < m_SearchList.Count) {
DisplayFrom += MaxEntries;
// clear any selection
Selected = -1;
}
break;
}
case 202: // backward block
{
// clear the selections
if(m_SelectionList != null && !SelectAll) Array.Clear(m_SelectionList,0,m_SelectionList.Length);
DisplayFrom -= MaxEntries;
if(DisplayFrom < 0) DisplayFrom = 0;
// clear any selection
Selected = -1;
break;
}
case 700: // Sort
{
// clear any selection
Selected = -1;
// clear the selections
if(m_SelectionList != null && !SelectAll) Array.Clear(m_SelectionList,0,m_SelectionList.Length);
Sorttype = false;
Sortname = false;
// read the toggle switches that determine the sort
if ( radiostate == 0 ) // sort by type
{
Sorttype = true;
}
if ( radiostate == 1 ) // sort by name
{
Sortname = true;
}
SortFindList();
break;
}
case 701: // descending sort
{
Descendingsort = !Descendingsort;
break;
}
case 9998: // refresh the gump
{
// clear any selection
Selected = -1;
break;
}
default:
{
if(info.ButtonID >= 3000 && info.ButtonID < 3000+ MaxEntries){
Selected = info.ButtonID - 3000;
// Show the props window
Refresh(state);
DoShowProps(info.ButtonID - 3000 + DisplayFrom);
return;
}
if(info.ButtonID == 3998){
SelectAll = !SelectAll;
// dont allow individual selection with the selectall button selected
if(m_SelectionList != null)
{
for(int i = 0; i < MaxEntries;i++)
{
if(i < m_SelectionList.Length){
// only toggle the selection list entries for things that actually have entries
m_SelectionList[i] = SelectAll;
} else
{
break;
}
}
}
}
if(info.ButtonID == 3999){
// dont allow individual selection with the selectall button selected
if(m_SelectionList != null && m_SearchList != null && !SelectAll)
{
for(int i = 0; i < MaxEntries;i++)
{
if(i < m_SelectionList.Length){
// only toggle the selection list entries for things that actually have entries
if((m_SearchList.Count - DisplayFrom > i)) {
m_SelectionList[i] = !m_SelectionList[i];
}
} else
{
break;
}
}
}
}
if(info.ButtonID >= 4000 && info.ButtonID < 4000+ MaxEntries){
int i = info.ButtonID - 4000;
// dont allow individual selection with the selectall button selected
if(m_SelectionList != null && i >= 0 && i < m_SelectionList.Length && !SelectAll){
// only toggle the selection list entries for things that actually have entries
if(m_SearchList != null && (m_SearchList.Count - DisplayFrom > i)) {
m_SelectionList[i] = !m_SelectionList[i];
}
}
}
if(info.ButtonID >= 5000 && info.ButtonID < 5000+ MaxEntries){
int i = info.ButtonID - 5000;
// dont allow individual selection with the selectall button selected
if(m_SelectionList != null && i >= 0 && i < m_SelectionList.Length && !SelectAll){
// only toggle the selection list entries for things that actually have entries
if(m_SearchList != null && (m_SearchList.Count - DisplayFrom > i)) {
XmlAttachment a = m_SearchList[i+DisplayFrom];
if(a != null)
{
state.Mobile.SendMessage(a.OnIdentify(state.Mobile));
}
}
}
}
break;
}
}
// Create a new gump
//m_Spawner.OnDoubleClick( state.Mobile);
Refresh(state);
}
public class XmlConfirmDeleteGump : Gump
{
private List<XmlAttachment> SearchList;
private bool [] SelectedList;
private Mobile From;
private int DisplayFrom;
private bool selectAll;
private object m_target;
public XmlConfirmDeleteGump(Mobile from, object target, List<XmlAttachment> searchlist, bool [] selectedlist, int displayfrom, bool selectall, int allcount) : base ( 0, 0 )
{
SearchList = searchlist;
SelectedList = selectedlist;
DisplayFrom = displayfrom;
selectAll = selectall;
m_target = target;
From = from;
Closable = false;
Dragable = true;
AddPage( 0 );
AddBackground( 10, 200, 200, 130, 5054 );
int count = 0;
if(selectall)
{
count = allcount;
} else
{
for(int i =0;i<SelectedList.Length;i++){
if(SelectedList[i]) count++;
}
}
AddLabel( 20, 225, 33, String.Format("Delete {0} attachments?",count) );
AddRadio( 35, 255, 9721, 9724, false, 1 ); // accept/yes radio
AddRadio( 135, 255, 9721, 9724, true, 2 ); // decline/no radio
AddHtmlLocalized(72, 255, 200, 30, 1049016, 0x7fff , false , false ); // Yes
AddHtmlLocalized(172, 255, 200, 30, 1049017, 0x7fff , false , false ); // No
AddButton( 80, 289, 2130, 2129, 3, GumpButtonType.Reply, 0 ); // Okay button
}
public override void OnResponse( NetState state, RelayInfo info )
{
if(info == null || state == null || state.Mobile == null) return;
int radiostate = -1;
if(info.Switches.Length > 0){
radiostate = info.Switches[0];
}
switch(info.ButtonID)
{
default:
{
if(radiostate == 1 && SearchList != null && SelectedList != null)
{ // accept
for(int i = 0;i < SearchList.Count;i++){
int index = i-DisplayFrom;
if((index >= 0 && index < SelectedList.Length && SelectedList[index] == true) || selectAll){
XmlAttachment o = SearchList[i];
// some objects may not delete gracefully (null map items are particularly error prone) so trap them
try {
o.Delete();
} catch {}
}
}
// refresh the gump
state.Mobile.CloseGump(typeof(XmlGetAttGump));
state.Mobile.SendGump(new XmlGetAttGump(state.Mobile,m_target,0,0));
}
break;
}
}
}
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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 { }
}
}
}
}

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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));
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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();
}
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -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);
}
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Mobiles;
/*
** QuestNote
** ArteGordon
**
*/
namespace Server.Items
{
public class QuestHolder : XmlQuestHolder
{
[Constructable]
public QuestHolder()
: base()
{
Name = "A quest";
TitleString = "A quest";
}
public QuestHolder(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
public override void OnDoubleClick(Mobile from)
{
base.OnDoubleClick(from);
from.CloseGump(typeof(XmlQuestStatusGump));
from.SendGump(new XmlQuestStatusGump(this, this.TitleString));
}
public override void OnSnoop(Mobile from)
{
if (from.AccessLevel > AccessLevel.Player)
{
from.CloseGump(typeof(XmlQuestStatusGump));
from.SendGump(new XmlQuestStatusGump(this, this.TitleString));
}
}
}
}

View File

@@ -0,0 +1,252 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Mobiles;
/*
** QuestNote
** ArteGordon
**
** Version 1.02
** updated 9/14/04
** - changed the QuestNote to open the status gump directly, and removed the serialized properties related to the scroll gump
** - added the OriginalQuestNote that has the scroll gump and behaves like the old QuestNote
**
** Version 1.01
** updated 3/25/04
** - Moved the TitleString and NoteString properties from the QuestNote class to the XmlQuestToken class.
**
** Version 1.0
** updated 1/07/04
** adds a item that displays text messages in a scroll gump and maintains quest state information. The size can be varied and the note text and text-color can be specified.
** The title of the note and its color can also be set.
*/
namespace Server.Items
{
public class QuestNote : XmlQuestToken
{
[Constructable]
public QuestNote() : base( 0x14EE )
{
Name = "A quest note";
TitleString = "A quest note";
}
public QuestNote( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 2 ); // version
// Version 2 has no serialized variables
// Version 0
//writer.Write( this.m_NoteString ); // moved to the XmlQuestToken class in version 1
//writer.Write( this.m_TitleString ); // moved to the XmlQuestToken class in version 1
// Version 1
//writer.Write( this.m_TextColor ); // no longer used
//writer.Write( this.m_TitleColor ); // no longer used
//writer.Write( this.m_size ); // no longer used
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 1:
{
reader.ReadInt();
reader.ReadInt();
reader.ReadInt();
//this.m_TextColor = reader.ReadInt();
//this.m_TitleColor = reader.ReadInt();
//this.m_size = reader.ReadInt();
}
break;
case 0:
{
reader.ReadString();
reader.ReadString();
reader.ReadInt();
reader.ReadInt();
reader.ReadInt();
//this.NoteString = reader.ReadString();
//this.TitleString = reader.ReadString();
//this.m_TextColor = reader.ReadInt();
//this.m_TitleColor = reader.ReadInt();
//this.m_size = reader.ReadInt();
}
break;
}
}
public override void OnDoubleClick( Mobile from )
{
base.OnDoubleClick(from);
from.CloseGump( typeof( XmlQuestStatusGump ) );
from.SendGump( new XmlQuestStatusGump(this, this.TitleString) );
}
}
public class OriginalQuestNote : XmlQuestToken
{
private int m_size = 1;
private int m_TextColor = 0x3e8;
private int m_TitleColor = 0xef0000; // cyan 0xf70000, black 0x3e8, brown 0xef0000 darkblue 0x7fff
[Constructable]
public OriginalQuestNote() : base( 0x14EE )
{
Name = "A quest note";
TitleString = "A quest note";
}
public OriginalQuestNote( Serial serial ) : base( serial )
{
}
[CommandProperty( AccessLevel.GameMaster )]
public int Size
{
get{ return m_size; }
set
{
m_size = value;
if(m_size < 1) m_size = 1;
//InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int TextColor
{
get{ return m_TextColor; }
set
{
m_TextColor = value;
//InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int TitleColor
{
get{ return m_TitleColor; }
set
{
m_TitleColor = value;
//InvalidateProperties();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 1 ); // version
// Version 1
writer.Write( this.m_TextColor );
writer.Write( this.m_TitleColor );
writer.Write( this.m_size );
// Version 0
//writer.Write( this.m_NoteString ); // moved to the XmlQuestToken class in version 1
//writer.Write( this.m_TitleString ); // moved to the XmlQuestToken class in version 1
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 1:
{
this.m_TextColor = reader.ReadInt();
this.m_TitleColor = reader.ReadInt();
this.m_size = reader.ReadInt();
}
break;
case 0:
{
this.NoteString = reader.ReadString();
this.TitleString = reader.ReadString();
this.m_TextColor = reader.ReadInt();
this.m_TitleColor = reader.ReadInt();
this.m_size = reader.ReadInt();
}
break;
}
}
public override void OnDoubleClick( Mobile from )
{
base.OnDoubleClick(from);
from.CloseGump( typeof( QuestNoteGump ) );
from.SendGump( new QuestNoteGump( this ) );
}
}
public class QuestNoteGump : Gump
{
private OriginalQuestNote m_Note;
public static string HtmlFormat( string text, int color )
{
return String.Format( "<BASEFONT COLOR=#{0}>{1}</BASEFONT>", color, text);
}
public QuestNoteGump( OriginalQuestNote note ) : base( 0, 0 )
{
m_Note = note;
AddPage( 0 );
AddAlphaRegion( 40, 41, 225, /*371*/70*note.Size );
// scroll top
AddImageTiled( 3, 5, 300, 37, 0x820 );
// scroll middle, upper portion
AddImageTiled( 19, 41, 263, 70, 0x821 );
for(int i=1;i<note.Size;i++)
{
// scroll middle , lower portion
AddImageTiled( 19, 41+70*i, 263, 70, 0x822 );
}
// scroll bottom
AddImageTiled( 20, 111+70*(note.Size-1), 273, 34, 0x823 );
// title string
AddHtml( 55, 10, 200, 37, QuestNoteGump.HtmlFormat( note.TitleString, note.TitleColor), false , false );
// text string
AddHtml( 40, 41, 225, 70*note.Size, QuestNoteGump.HtmlFormat( note.NoteString, note.TextColor ), false , false );
// add the quest status gump button
AddButton( 40, 50+ note.Size*70, 0x037, 0x037, 1, GumpButtonType.Reply, 0 );
}
public override void OnResponse( Server.Network.NetState state, RelayInfo info )
{
Mobile from = state.Mobile;
if ( info.ButtonID == 1 )
{
XmlQuestStatusGump g = new XmlQuestStatusGump(m_Note, m_Note.TitleString);
from.SendGump( g );
}
}
}
}

View File

@@ -0,0 +1,144 @@
using System;
using Server;
namespace Server.Items
{
public class SimpleMap : MapItem
{
private int m_PinIndex;
[CommandProperty( AccessLevel.GameMaster )]
public int CurrentPin
{
// get/set the index (one-based) of the pin that will be referred to by PinLocation
get{ return m_PinIndex; }
set{ m_PinIndex = value;}
}
[CommandProperty( AccessLevel.GameMaster )]
public int NPins
{
get
{
if(Pins != null)
{
return Pins.Count;
}
else
{
return 0;
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public Point2D PinLocation
{
set
{
// change the coordinates of the current pin
if(Pins != null && CurrentPin > 0 && CurrentPin <=Pins.Count)
{
int mapx, mapy;
ConvertToMap(value.X, value.Y, out mapx, out mapy);
Pins[CurrentPin -1] = new Point2D(mapx, mapy);
}
}
get
{
// get the coordinates of the current pin
if(Pins != null && CurrentPin > 0 && CurrentPin <=Pins.Count)
{
int mapx, mapy;
ConvertToWorld(((Point2D)Pins[CurrentPin -1]).X, ((Point2D)Pins[CurrentPin -1]).Y, out mapx, out mapy);
return new Point2D(mapx, mapy);
}
else
{
return Point2D.Zero;
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public Point2D NewPin
{
set
{
// add a new pin at the specified world coordinate
AddWorldPin(value.X, value.Y);
CurrentPin = NPins;
}
get
{
// return the last pin added to the Pins arraylist
if(Pins != null && NPins > 0)
{
int mapx, mapy;
ConvertToWorld(((Point2D)Pins[NPins -1]).X, ((Point2D)Pins[NPins -1]).Y, out mapx, out mapy);
return new Point2D(mapx, mapy);
}
else
{
return Point2D.Zero;
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool ClearAllPins
{
get { return false; }
set { if(value == true) ClearPins(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int PinRemove
{
set { RemovePin(value); }
get { return 0; }
}
[CommandProperty( AccessLevel.GameMaster )]
public Mobile ShowTo
{
set
{
if(value != null)
{
//DisplayTo(value);
OnDoubleClick(value);
}
}
get { return null; }
}
[Constructable]
public SimpleMap()
{
SetDisplay( 0, 0, 5119, 4095, 400, 400 );
}
public override int LabelNumber{ get{ return 1025355; } } // map
public SimpleMap( 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();
}
}
}

View File

@@ -0,0 +1,143 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
/*
** SimpleNote
** updated 1/3/04
** ArteGordon
** adds a simple item that displays text messages in a scroll gump. The size can be varied and the note text and text-color can be specified.
** The title of the note and its color can also be set.
*/
namespace Server.Items
{
public class SimpleNote : Item
{
private int m_size = 1;
private string m_NoteString;
private string m_TitleString;
private int m_TextColor = 0x3e8;
private int m_TitleColor = 0xef0000; // cyan 0xf70000, black 0x3e8, brown 0xef0000 darkblue 0x7fff
[Constructable]
public SimpleNote() : base( 0x14EE )
{
Name = "A note";
TitleString = "A note";
}
public SimpleNote( Serial serial ) : base( serial )
{
}
[CommandProperty( AccessLevel.GameMaster )]
public string NoteString
{
get{ return m_NoteString; }
set { m_NoteString = value; InvalidateProperties();}
}
[CommandProperty( AccessLevel.GameMaster )]
public string TitleString
{
get{ return m_TitleString; }
set { m_TitleString = value; InvalidateProperties();}
}
[CommandProperty( AccessLevel.GameMaster )]
public int Size
{
get{ return m_size; }
set
{
m_size = value;
if(m_size < 1) m_size = 1;
InvalidateProperties();}
}
[CommandProperty( AccessLevel.GameMaster )]
public int TextColor
{
get{ return m_TextColor; }
set { m_TextColor = value; InvalidateProperties();}
}
[CommandProperty( AccessLevel.GameMaster )]
public int TitleColor
{
get{ return m_TitleColor; }
set { m_TitleColor = value; InvalidateProperties();}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( this.m_NoteString );
writer.Write( this.m_TitleString );
writer.Write( this.m_TextColor );
writer.Write( this.m_TitleColor );
writer.Write( this.m_size );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
this.m_NoteString = reader.ReadString();
this.m_TitleString = reader.ReadString();
this.m_TextColor = reader.ReadInt();
this.m_TitleColor = reader.ReadInt();
this.m_size = reader.ReadInt();
}
break;
}
}
public override void OnDoubleClick( Mobile from )
{
SimpleNoteGump g = new SimpleNoteGump( this );
from.SendGump( g );
}
}
public class SimpleNoteGump : Gump
{
private SimpleNote m_Note;
public static string HtmlFormat( string text, int color )
{
return String.Format( "<BASEFONT COLOR=#{0}>{1}</BASEFONT>", color, text);
}
public SimpleNoteGump( SimpleNote note ) : base( 0, 0 )
{
m_Note = note;
AddPage( 0 );
AddAlphaRegion( 40, 41, 225, /*371*/70*note.Size );
// scroll top
AddImageTiled( 3, 5, 300, 37, 0x820 );
// scroll middle, upper portion
AddImageTiled( 19, 41, 263, 70, 0x821 );
for(int i=1;i<note.Size;i++)
{
// scroll middle , lower portion
AddImageTiled( 19, 41+70*i, 263, 70, 0x822 );
}
// scroll bottom
AddImageTiled( 20, 111+70*(note.Size-1), 273, 34, 0x823 );
// title string
AddHtml( 55, 10, 200, 37, SimpleNoteGump.HtmlFormat( note.TitleString, note.TitleColor), false , false );
// text string
AddHtml( 40, 41, 225, 70*note.Size, SimpleNoteGump.HtmlFormat( note.NoteString, note.TextColor ), false , false );
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,167 @@
using System;
using Server;
using Server.Mobiles;
/*
SimpleTileTrap
Written by Alari
based off SimpleSwitch. (did a search and replace on simpleswitch->simpletiletrap
and then modified the code as appropriate.)
For this tile trap, 0 is the state when the player moves off or is not standing, and 1 is what is triggered when the player moves directly over the tile trap.
*/
namespace Server.Items
{
public class SimpleTileTrap : Item
{
private int m_SwitchSound = 939;
private Item m_TargetItem0 = null;
private string m_TargetProperty0 = null;
private Item m_TargetItem1 = null;
private string m_TargetProperty1 = null;
[Constructable]
public SimpleTileTrap() : base( 7107 )
{
Name = "A tile trap";
Movable = false;
Visible = false;
}
public SimpleTileTrap( Serial serial ) : base( serial )
{
}
[CommandProperty( AccessLevel.GameMaster )]
public int SwitchSound
{
get{ return m_SwitchSound; }
set
{
m_SwitchSound = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public Item Target0Item
{
get{ return m_TargetItem0; }
set { m_TargetItem0 = value;InvalidateProperties();}
}
[CommandProperty( AccessLevel.GameMaster )]
public string Target0Property
{
get{ return m_TargetProperty0; }
set { m_TargetProperty0 = value;InvalidateProperties();}
}
[CommandProperty( AccessLevel.GameMaster )]
public string Target0ItemName
{ get{ if(m_TargetItem0 != null && !m_TargetItem0.Deleted) return m_TargetItem0.Name; else return null;} }
[CommandProperty( AccessLevel.GameMaster )]
public Item Target1Item
{
get{ return m_TargetItem1; }
set { m_TargetItem1 = value;InvalidateProperties();}
}
[CommandProperty( AccessLevel.GameMaster )]
public string Target1Property
{
get{ return m_TargetProperty1; }
set { m_TargetProperty1 = value;InvalidateProperties();}
}
[CommandProperty( AccessLevel.GameMaster )]
public string Target1ItemName
{ get{ if(m_TargetItem1 != null && !m_TargetItem1.Deleted) return m_TargetItem1.Name; else return null;} }
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( this.m_SwitchSound );
writer.Write( this.m_TargetItem0 );
writer.Write( this.m_TargetProperty0 );
writer.Write( this.m_TargetItem1 );
writer.Write( this.m_TargetProperty1 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
this.m_SwitchSound = reader.ReadInt();
this.m_TargetItem0 = reader.ReadItem();
this.m_TargetProperty0 = reader.ReadString();
this.m_TargetItem1 = reader.ReadItem();
this.m_TargetProperty1 = reader.ReadString();
}
break;
}
}
public bool CheckRange( Point3D loc, Point3D oldLoc, int range )
{
return CheckRange( loc, range ) && !CheckRange( oldLoc, range );
}
public bool CheckRange( Point3D loc, int range )
{
return ( (this.Z + 8) >= loc.Z && (loc.Z + 16) > this.Z )
&& Utility.InRange( GetWorldLocation(), loc, range );
}
public override bool HandlesOnMovement{ get{ return true; } } // Tell the core that we implement OnMovement
public override void OnMovement( Mobile m, Point3D oldLocation )
{
base.OnMovement( m, oldLocation );
if ( m.Location == oldLocation )
return;
if( ( m.Player && m.AccessLevel == AccessLevel.Player ) )
{
if ( CheckRange( m.Location, oldLocation, 0 ) )
OnEnter( m );
else if ( oldLocation == this.Location )
OnExit( m );
}
}
public virtual void OnEnter( Mobile m )
{
string status_str;
m.PlaySound(SwitchSound);
BaseXmlSpawner.ApplyObjectStringProperties(null, m_TargetProperty1, m_TargetItem1, m, this, out status_str);
}
public virtual void OnExit( Mobile m )
{
string status_str;
BaseXmlSpawner.ApplyObjectStringProperties(null, m_TargetProperty0, m_TargetItem0, m, this, out status_str);
}
}
}

View File

@@ -0,0 +1,49 @@
using System;
using Server;
namespace Server.Items
{
public class SingleUseSwitch : SimpleSwitch
{
[Constructable]
public SingleUseSwitch()
{
}
public SingleUseSwitch(Serial serial)
: base(serial)
{
}
public override void OnDoubleClick(Mobile from)
{
if (from == null || Disabled) return;
if (!from.InRange(GetWorldLocation(), 2) || !from.InLOS(this))
{
from.SendLocalizedMessage(500446); // That is too far away.
return;
}
base.OnDoubleClick(from);
// delete after use
Delete();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); // version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,82 @@
using System;
using Server;
namespace Server.Items
{
public abstract class BaseRewardScroll : Item
{
public override double DefaultWeight
{
get { return 0.0; }
}
public BaseRewardScroll() : base( 0x2D51 ){}
public BaseRewardScroll( 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();}
}
public class RewardScrollDeed : Item
{
[Constructable]
public RewardScrollDeed() : this( 1 )
{
ItemID = 5360;
Movable = true;
Hue = 1165;
Name = "Reward Scroll Deed";
}
public override void OnDoubleClick( Mobile from )
{
from.AddToBackpack( new RewardScroll() );
this.Delete();
}
[Constructable]
public RewardScrollDeed( int amount )
{
}
public RewardScrollDeed( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class RewardScroll : BaseRewardScroll
{
[Constructable]
public RewardScroll()
{
Stackable = true;
Name = "Reward Scroll";
Hue = 1165;
LootType = LootType.Blessed;
}
public RewardScroll( 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();}
}
}

View File

@@ -0,0 +1,73 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Mobiles;
using System.IO;
using System.Collections;
using Server.Targeting;
using Server.Engines.PartySystem;
using System.Data;
using System.Xml;
/*
** XmlQuestMaker
**
** Version 1.00
** updated 9/03/04
** ArteGordon
**
*/
namespace Server.Items
{
public class XmlQuestMaker : Item
{
public XmlQuestMaker( Serial serial ) : base( serial )
{
}
[Constructable]
public XmlQuestMaker() : base(0xED4)
{
Name = "XmlQuestMaker";
Movable = false;
Visible = true;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void OnDoubleClick( Mobile from )
{
base.OnDoubleClick(from);
if(!(from is PlayerMobile)) return;
// make a quest note
QuestHolder newquest = new QuestHolder();
newquest.PlayerMade = true;
newquest.Creator = from as PlayerMobile;
newquest.Hue = 500;
from.AddToBackpack(newquest);
from.SendMessage("A blank quest has been added to your pack!");
}
}
}

View File

@@ -0,0 +1,279 @@
using System;
using Server;
using System.IO;
using System.Collections;
using Server.Multis;
using Server.Items;
using Server.Mobiles;
namespace Server.Engines.XmlSpawner2
{
public class XmlSpawnerAddon : BaseAddon
{
public override bool ShareHue { get { return false; } }
[CommandProperty(AccessLevel.GameMaster)]
public virtual int PartialVisibility
{
get
{
int nvisible = 0;
// figure out what percentage of components is visible and return that value
// go through the components
for (int i = 0; i < Components.Count; i++)
{
if (Components[i].Visible) nvisible++;
}
return (int)(100.0 * nvisible / Components.Count + 0.5);
}
set
{
if (Components == null || Components.Count < 1) return;
// assign visibility to the components based upon the percentage value
int nvisible = value * (Components.Count - 1) / 100;
// go through the components and assign visibility to the specified percentage
// starting at the beginning of the component list
for (int i = 0; i < Components.Count; i++)
{
Components[i].Visible = (i < nvisible);
}
}
}
// create an addon with the static components described in the multi.txt file
public static XmlSpawnerAddon ReadMultiFile(string filename, out string status_str)
{
status_str = null;
if (filename == null) return null;
XmlSpawnerAddon newaddon = null;
// look for the file in the default spawner locations
string dirname = XmlSpawner.LocateFile(filename);
if (System.IO.File.Exists(dirname))
{
int ncomponents = 0;
newaddon = new XmlSpawnerAddon();
try
{
ncomponents = LoadAddonFromMulti(newaddon, dirname, out status_str);
}
catch
{
newaddon.Delete();
status_str = "Bad Multi file : " + filename;
return null;
}
if (ncomponents == 0)
{
newaddon.Delete();
status_str += " : " + filename;
return null;
}
}
else
{
status_str = "No such file : " + filename;
}
return newaddon;
}
// adds components from a multi.txt file to an existing addon
public static int LoadAddonFromMulti(XmlSpawnerAddon newaddon, string filename, out string status_str)
{
status_str = null;
if (filename == null)
{
status_str = "Invalid filename";
return 0;
}
if (newaddon == null)
{
status_str = "Invalid addon";
return 0;
}
bool badformat = false;
int ncomponents = 0;
if (System.IO.File.Exists(filename))
{
using (StreamReader sr = new StreamReader(filename))
{
string line;
int linenumber = 0;
// Read and process lines from the file until the end of the file is reached.
// Individual lines have the format of
// itemid x y z visible [hue] ; attachment[,args]
// where visible is a 0/1 and hue can be optionally specified for individual itemid entries.
while ((line = sr.ReadLine()) != null)
{
linenumber++;
// process the line
if (line.Length == 0) continue;
// first parse out the component specification from any optional attachment specifications
string[] specs = line.Split(';');
// the component spec will always be first
if (specs == null || specs.Length < 1) continue;
string[] args = specs[0].Trim().Split(' ');
AddonComponent newcomponent = null;
if (args != null && args.Length >= 5)
{
int itemid = -1;
int x = 0;
int y = 0;
int z = 0;
int visible = 0;
int hue = -1;
try
{
itemid = int.Parse(args[0]);
x = int.Parse(args[1]);
y = int.Parse(args[2]);
z = int.Parse(args[3]);
visible = int.Parse(args[4]);
// handle the optional fields that are not part of the original multi.txt specification
if (args.Length > 5)
{
hue = int.Parse(args[5]);
}
}
catch { badformat = true; }
if (itemid < 0 || badformat)
{
status_str = String.Format("Error line {0}", linenumber);
break;
}
// create the new component
newcomponent = new AddonComponent(itemid);
// set the properties according to the specification
newcomponent.Visible = (visible == 1);
if (hue >= 0)
newcomponent.Hue = hue;
// add it to the addon
newaddon.AddComponent(newcomponent, x, y, z);
ncomponents++;
}
// if a valid component was added, then check to see if any additional attachment specifications need to be processed
if (newcomponent != null && specs.Length > 1)
{
for (int j = 1; j < specs.Length; j++)
{
if (specs[j] == null) continue;
string attachstring = specs[j].Trim();
Type type = null;
try
{
type = SpawnerType.GetType(BaseXmlSpawner.ParseObjectType(attachstring));
}
catch { }
// if so then create it
if (type != null && type.IsSubclassOf(typeof(XmlAttachment)))
{
object newo = XmlSpawner.CreateObject(type, attachstring, false, true);
if (newo is XmlAttachment)
{
// add the attachment to the target
XmlAttach.AttachTo(newcomponent, (XmlAttachment)newo);
}
}
}
}
}
sr.Close();
}
}
else
{
status_str = "No such file : " + filename;
}
if (badformat)
{
return 0;
}
else
{
return ncomponents;
}
}
public override BaseAddonDeed Deed
{
get
{
return null;
}
}
public XmlSpawnerAddon()
{
}
public XmlSpawnerAddon(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write(1); // Version
// version 1
writer.Write(PartialVisibility);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 1:
PartialVisibility = reader.ReadInt();
break;
}
}
}
}

View File

@@ -0,0 +1,963 @@
using System;
using System.Data;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using Server.ContextMenus;
using Server;
using Server.Items;
using Server.Network;
using Server.Gumps;
using Server.Targeting;
using System.Reflection;
using Server.Commands;
using CPA = Server.CommandPropertyAttribute;
using System.Xml;
using Server.Spells;
using System.Text;
using Server.Accounting;
using System.Diagnostics;
using System.Text.RegularExpressions;
using Server.Engines.XmlSpawner2;
/*
** TalkingBaseCreature
** A mobile that can be programmed with branching conversational sequences that are advanced by keywords at each sequence point.
**
** 2/10/05
** modified to use the XmlDialog attachment
*/
namespace Server.Mobiles
{
public class TalkingBaseCreature : BaseCreature
{
private XmlDialog m_DialogAttachment;
public XmlDialog DialogAttachment {get { return m_DialogAttachment; } set {m_DialogAttachment = value; }}
private DateTime lasteffect;
private int m_EItemID = 0; // 0 = disable, 14202 = sparkle, 6251 = round stone, 7885 = light pyramid
private int m_Duration = 70;
private Point3D m_Offset = new Point3D(0,0,20); // overhead
private int m_EHue = 68; // green
[CommandProperty( AccessLevel.GameMaster )]
public int EItemID {
get{ return m_EItemID; }
set {
m_EItemID = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public Point3D EOffset
{
get{ return m_Offset; }
set
{
m_Offset = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int EDuration
{
get{ return m_Duration; }
set
{
m_Duration = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int EHue
{
get{ return m_EHue; }
set
{
m_EHue = value;
}
}
public void DisplayHighlight()
{
if(EItemID > 0)
{
//SendOffsetTargetEffect(this, new Point3D(Location.X + EOffset.X, Location.Y + EOffset.Y, Location.Z + EOffset.Z), EItemID, 10, EDuration, EHue, 0);
Effects.SendLocationEffect(new Point3D(Location.X + EOffset.X, Location.Y + EOffset.Y, Location.Z + EOffset.Z), Map, EItemID, EDuration, EHue, 0);
lasteffect = DateTime.UtcNow;
}
}
public static void SendOffsetTargetEffect( IEntity target, Point3D loc, int itemID, int speed, int duration, int hue, int renderMode )
{
if ( target is Mobile )
((Mobile)target).ProcessDelta();
Effects.SendPacket( loc, target.Map, new OffsetTargetEffect( target, loc, itemID, speed, duration, hue, renderMode ) );
}
public sealed class OffsetTargetEffect : HuedEffect
{
public OffsetTargetEffect(IEntity e, Point3D loc, int itemID, int speed, int duration, int hue, int renderMode)
: base(EffectType.FixedFrom, e.Serial, Serial.Zero, itemID, loc, loc, speed, duration, true, false, hue, renderMode)
{
}
}
public override void OnThink()
{
base.OnThink();
if(lasteffect + TimeSpan.FromSeconds(1) < DateTime.UtcNow)
{
DisplayHighlight();
}
}
public override bool Move( Direction d )
{
bool didmove = base.Move( d );
DisplayHighlight();
return didmove;
}
private string m_TalkText;
[CommandProperty( AccessLevel.GameMaster )]
public string TalkText {get{ return m_TalkText; } set { m_TalkText = value; }}
// properties below are modified to access the equivalent XmlDialog properties
// this is largely for backward compatibility, but it does also add some convenience
public Mobile ActivePlayer
{
get
{
if(DialogAttachment != null)
return DialogAttachment.ActivePlayer;
else
return null;
}
set
{
if(DialogAttachment != null)
DialogAttachment.ActivePlayer = value;
}
}
public ArrayList SpeechEntries
{
get
{
if(DialogAttachment != null)
return DialogAttachment.SpeechEntries;
else
return null;
}
set
{
if(DialogAttachment != null)
DialogAttachment.SpeechEntries = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan GameTOD
{
get
{
int hours;
int minutes;
Server.Items.Clock.GetTime(this.Map, this.Location.X, this.Location.Y, out hours, out minutes);
return (new DateTime(DateTime.UtcNow.Year,DateTime.UtcNow.Month,DateTime.UtcNow.Day,hours, minutes,0).TimeOfDay);
}
}
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan RealTOD
{
get
{
return DateTime.UtcNow.TimeOfDay;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int RealDay
{
get
{
return DateTime.UtcNow.Day;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int RealMonth
{
get
{
return DateTime.UtcNow.Month;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public DayOfWeek RealDayOfWeek
{
get
{
return DateTime.UtcNow.DayOfWeek;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public MoonPhase MoonPhase
{
get
{
return Clock.GetMoonPhase( this.Map, this.Location.X, this.Location.Y );
}
}
[CommandProperty( AccessLevel.GameMaster )]
public AccessLevel TriggerAccessLevel
{
get
{
if(DialogAttachment != null)
return DialogAttachment.TriggerAccessLevel;
else
return AccessLevel.Player;
}
set
{
if(DialogAttachment != null)
DialogAttachment.TriggerAccessLevel = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public DateTime LastInteraction
{
get
{
if(DialogAttachment != null)
return DialogAttachment.LastInteraction;
else
return DateTime.MinValue;
}
set
{
if(DialogAttachment != null)
DialogAttachment.LastInteraction = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool DoReset
{
get
{
return false;
}
set
{
if(DialogAttachment != null)
DialogAttachment.DoReset = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool IsActive
{
get
{
if(DialogAttachment != null)
return DialogAttachment.IsActive;
else
return false;
}
set
{
if(DialogAttachment != null)
DialogAttachment.IsActive = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool AllowGhostTrig
{
get
{
if(DialogAttachment != null)
return DialogAttachment.AllowGhostTrig;
else
return false;
}
set
{
if(DialogAttachment != null)
DialogAttachment.AllowGhostTrig = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Running
{
get
{
if(DialogAttachment != null)
return DialogAttachment.Running;
else
return false;
}
set
{
if(DialogAttachment != null)
DialogAttachment.Running = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan ResetTime
{
get
{
if(DialogAttachment != null)
return DialogAttachment.ResetTime;
else
return TimeSpan.Zero;
}
set
{
if(DialogAttachment != null)
DialogAttachment.ResetTime = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int SpeechPace
{
get
{
if(DialogAttachment != null)
return DialogAttachment.SpeechPace;
else
return 0;
}
set
{
if(DialogAttachment != null)
DialogAttachment.SpeechPace = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public string Keywords
{
get
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
{
return DialogAttachment.CurrentEntry.Keywords;
}
else
return null;
}
set
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
DialogAttachment.CurrentEntry.Keywords = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public string Action
{
get
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
{
return DialogAttachment.CurrentEntry.Action;
}
else
return null;
}
set
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
DialogAttachment.CurrentEntry.Action = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public string Condition
{
get
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
{
return DialogAttachment.CurrentEntry.Condition;
}
else
return null;
}
set
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
DialogAttachment.CurrentEntry.Condition = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public string Text
{
get
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
{
return DialogAttachment.CurrentEntry.Text;
}
else
return null;
}
set
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
DialogAttachment.CurrentEntry.Text = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public string DependsOn
{
get
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
{
return DialogAttachment.CurrentEntry.DependsOn;
}
else
return "-1";
}
set
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
DialogAttachment.CurrentEntry.DependsOn = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool LockConversation
{
get
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
{
return DialogAttachment.CurrentEntry.LockConversation;
}
else
return false;
}
set
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
DialogAttachment.CurrentEntry.LockConversation = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public MessageType SpeechStyle
{
get
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
{
return DialogAttachment.CurrentEntry.SpeechStyle;
}
else
return MessageType.Regular;
}
set
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
DialogAttachment.CurrentEntry.SpeechStyle = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool AllowNPCTrigger
{
get
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
{
return DialogAttachment.CurrentEntry.AllowNPCTrigger;
}
else
return false;
}
set
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
DialogAttachment.CurrentEntry.AllowNPCTrigger = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int Pause
{
get
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
{
return DialogAttachment.CurrentEntry.Pause;
}
else
return -1;
}
set
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
DialogAttachment.CurrentEntry.Pause = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int PrePause
{
get
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
{
return DialogAttachment.CurrentEntry.PrePause;
}
else
return -1;
}
set
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
DialogAttachment.CurrentEntry.PrePause = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int ID
{
get
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
{
return DialogAttachment.CurrentEntry.ID;
}
else
return -1;
}
set
{
if(DialogAttachment != null && DialogAttachment.CurrentEntry != null)
DialogAttachment.CurrentEntry.ID = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int EntryNumber
{
get
{
if(DialogAttachment != null)
return DialogAttachment.EntryNumber;
else
return -1;
}
set
{
if(DialogAttachment != null)
{
DialogAttachment.EntryNumber = value;
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int ProximityRange
{
get
{
if(DialogAttachment != null)
return DialogAttachment.ProximityRange;
else
return -1;
}
set
{
if(DialogAttachment != null)
{
DialogAttachment.ProximityRange = value;
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public string ConfigFile
{
get
{
if(DialogAttachment != null)
return DialogAttachment.ConfigFile;
else
return null;
}
set
{
if(DialogAttachment != null)
{
DialogAttachment.ConfigFile = value;
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool LoadConfig
{
get{return false;}
set{ if(value == true && DialogAttachment != null) DialogAttachment.DoLoadNPC(null,ConfigFile);}
}
[CommandProperty( AccessLevel.GameMaster )]
public bool SaveConfig
{
get{return false;}
set
{
if(value == true && DialogAttachment != null)
DialogAttachment.DoSaveNPC(null,ConfigFile, false);
}
}
[CommandProperty( AccessLevel.GameMaster )]
public string TriggerOnCarried
{
get
{
if(DialogAttachment != null)
return DialogAttachment.TriggerOnCarried;
else
return null;
}
set
{
if(DialogAttachment != null)
{
DialogAttachment.TriggerOnCarried = value;
}
}
}
[CommandProperty( AccessLevel.GameMaster )]
public string NoTriggerOnCarried
{
get
{
if(DialogAttachment != null)
return DialogAttachment.NoTriggerOnCarried;
else
return null;
}
set
{
if(DialogAttachment != null)
{
DialogAttachment.NoTriggerOnCarried = value;
}
}
}
public XmlDialog.SpeechEntry CurrentEntry
{
get
{
if(DialogAttachment != null)
return DialogAttachment.CurrentEntry;
else
return null;
}
set
{
if(DialogAttachment != null)
{
DialogAttachment.CurrentEntry = value;
}
}
}
public override bool OnDragDrop( Mobile from, Item item)
{
return XmlQuest.RegisterGive(from, this, item);
//return base.OnDragDrop(from, item);
}
private class TalkEntry : ContextMenuEntry
{
private TalkingBaseCreature m_NPC;
public TalkEntry( TalkingBaseCreature npc ) : base( 6146 )
{
m_NPC = npc;
}
public override void OnClick()
{
Mobile from = Owner.From;
if ( m_NPC == null || m_NPC.Deleted || !from.CheckAlive() || m_NPC.DialogAttachment == null )
return;
// process the talk text
//m_NPC.DialogAttachment.ProcessSpeech(from, m_NPC.TalkText);
from.DoSpeech(m_NPC.TalkText,new int[] {},MessageType.Regular,from.SpeechHue);
}
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
if ( from.Alive )
{
if ( TalkText != null && TalkText.Length > 0 && DialogAttachment != null)
{
list.Add( new TalkEntry( this ) );
}
}
base.GetContextMenuEntries( from, list );
}
public TalkingBaseCreature(AIType ai,
FightMode mode,
int iRangePerception,
int iRangeFight,
double dActiveSpeed,
double dPassiveSpeed): base( ai, mode, iRangePerception, iRangeFight, dActiveSpeed, dPassiveSpeed )
{
// add the XmlDialog attachment
m_DialogAttachment = new XmlDialog(default(string));
XmlAttach.AttachTo(this, m_DialogAttachment);
}
public TalkingBaseCreature( Serial serial ) : base( serial )
{
}
public static void Initialize()
{
// reestablish the DialogAttachment assignment
foreach(Mobile m in World.Mobiles.Values)
{
if(m is TalkingBaseCreature)
{
XmlDialog xa = XmlAttach.FindAttachment(m, typeof(XmlDialog)) as XmlDialog;
((TalkingBaseCreature)m).DialogAttachment = xa;
}
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 7 ); // version
// version 7
writer.Write( m_EItemID);
writer.Write( m_Duration);
writer.Write( m_Offset);
writer.Write( m_EHue);
// version 6
writer.Write( m_TalkText);
// Version 5
// all serialized data now handled by the XmlDialog attachment
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
if(version < 5)
{
// have to add the XmlDialog attachment
m_DialogAttachment = new XmlDialog(default(string));
XmlAttach.AttachTo(this, m_DialogAttachment);
}
switch ( version )
{
case 7:
m_EItemID = reader.ReadInt();
m_Duration = reader.ReadInt();
m_Offset = reader.ReadPoint3D();
m_EHue = reader.ReadInt();
goto case 6;
case 6:
TalkText = reader.ReadString();
break;
case 5:
{
break;
}
case 4:
{
int count = reader.ReadInt();
SpeechEntries = new ArrayList();
for(int i = 0; i<count;i++)
{
XmlDialog.SpeechEntry newentry = new XmlDialog.SpeechEntry();
newentry.Condition = reader.ReadString();
SpeechEntries.Add(newentry);
}
goto case 3;
}
case 3:
{
TriggerOnCarried = reader.ReadString();
NoTriggerOnCarried = reader.ReadString();
goto case 2;
}
case 2:
{
SpeechPace = reader.ReadInt();
int count = reader.ReadInt();
if(version < 4)
{
SpeechEntries = new ArrayList();
}
for(int i = 0; i<count;i++)
{
if(version < 4)
{
XmlDialog.SpeechEntry newentry = new XmlDialog.SpeechEntry();
newentry.PrePause = reader.ReadInt();
newentry.LockConversation = reader.ReadBool();
newentry.AllowNPCTrigger = reader.ReadBool();
newentry.SpeechStyle = (MessageType)reader.ReadInt();
SpeechEntries.Add(newentry);
}
else
{
XmlDialog.SpeechEntry newentry = (XmlDialog.SpeechEntry)SpeechEntries[i];
newentry.PrePause = reader.ReadInt();
newentry.LockConversation = reader.ReadBool();
newentry.AllowNPCTrigger = reader.ReadBool();
newentry.SpeechStyle = (MessageType)reader.ReadInt();
}
}
goto case 1;
}
case 1:
{
ActivePlayer = reader.ReadMobile();
goto case 0;
}
case 0:
{
IsActive = reader.ReadBool();
ResetTime = reader.ReadTimeSpan();
LastInteraction = reader.ReadDateTime();
AllowGhostTrig = reader.ReadBool();
ProximityRange = reader.ReadInt();
Running = reader.ReadBool();
ConfigFile = reader.ReadString();
int count = reader.ReadInt();
if(version < 2)
{
SpeechEntries = new ArrayList();
}
for(int i = 0; i<count;i++)
{
if(version < 2)
{
XmlDialog.SpeechEntry newentry = new XmlDialog.SpeechEntry();
newentry.EntryNumber = reader.ReadInt();
newentry.ID = reader.ReadInt();
newentry.Text = reader.ReadString();
newentry.Keywords = reader.ReadString();
newentry.Action = reader.ReadString();
newentry.DependsOn = reader.ReadInt().ToString();
newentry.Pause = reader.ReadInt();
SpeechEntries.Add(newentry);
}
else
{
XmlDialog.SpeechEntry newentry = (XmlDialog.SpeechEntry)SpeechEntries[i];
newentry.EntryNumber = reader.ReadInt();
newentry.ID = reader.ReadInt();
newentry.Text = reader.ReadString();
newentry.Keywords = reader.ReadString();
newentry.Action = reader.ReadString();
newentry.DependsOn = reader.ReadInt().ToString();
newentry.Pause = reader.ReadInt();
}
}
// read in the current entry number. Note this will also set the current entry
EntryNumber = reader.ReadInt();
// restart the timer if it was active
bool isrunning = reader.ReadBool();
if(isrunning)
{
Mobile trigmob = reader.ReadMobile();
TimeSpan delay = reader.ReadTimeSpan();
if(DialogAttachment != null)
DialogAttachment.DoTimer(delay,trigmob);
}
break;
}
}
}
}
}

View File

@@ -0,0 +1,191 @@
using System;
using System.Data;
using System.IO;
using System.Collections;
using Server;
using Server.Items;
using Server.Network;
using Server.Gumps;
using Server.Targeting;
using System.Reflection;
using Server.Commands;
using CPA = Server.CommandPropertyAttribute;
using System.Xml;
using Server.Spells;
using System.Text;
using Server.Accounting;
using System.Diagnostics;
namespace Server.Mobiles
{
public class XmlQuestNPC : TalkingBaseCreature
{
[Constructable]
public XmlQuestNPC() : this(-1)
{
}
[Constructable]
public XmlQuestNPC(int gender) : base( AIType.AI_Melee, FightMode.None, 10, 1, 0.8, 3.0 )
{
SetStr( 10, 30 );
SetDex( 10, 30 );
SetInt( 10, 30 );
Fame = 50;
Karma = 50;
CanHearGhosts = true;
SpeechHue = Utility.RandomDyedHue();
Title = string.Empty;
Hue = Utility.RandomSkinHue();
switch(gender)
{
case -1: this.Female = Utility.RandomBool(); break;
case 0: this.Female = false; break;
case 1: this.Female = true; break;
}
if ( this.Female)
{
this.Body = 0x191;
this.Name = NameList.RandomName( "female" );
Item hair = new Item( Utility.RandomList( 0x203B, 0x203C, 0x203D, 0x2045, 0x204A, 0x2046 , 0x2049 ) );
hair.Hue = Utility.RandomHairHue();
hair.Layer = Layer.Hair;
hair.Movable = false;
AddItem( hair );
Item hat = null;
switch ( Utility.Random( 5 ) )//4 hats, one empty, for no hat
{
case 0: hat = new FloppyHat( Utility.RandomNeutralHue() ); break;
case 1: hat = new FeatheredHat( Utility.RandomNeutralHue() ); break;
case 2: hat = new Bonnet(); break;
case 3: hat = new Cap( Utility.RandomNeutralHue() ); break;
}
AddItem( hat );
Item pants = null;
switch ( Utility.Random( 3 ) )
{
case 0: pants = new ShortPants( GetRandomHue() ); break;
case 1: pants = new LongPants( GetRandomHue() ); break;
case 2: pants = new Skirt( GetRandomHue() ); break;
}
AddItem( pants );
Item shirt = null;
switch ( Utility.Random( 7 ) )
{
case 0: shirt = new Doublet( GetRandomHue() ); break;
case 1: shirt = new Surcoat( GetRandomHue() ); break;
case 2: shirt = new Tunic( GetRandomHue() ); break;
case 3: shirt = new FancyDress( GetRandomHue() ); break;
case 4: shirt = new PlainDress( GetRandomHue() ); break;
case 5: shirt = new FancyShirt( GetRandomHue() ); break;
case 6: shirt = new Shirt( GetRandomHue() ); break;
}
AddItem( shirt );
}
else
{
this.Body = 0x190;
this.Name = NameList.RandomName( "male" );
Item hair = new Item( Utility.RandomList( 0x203B, 0x203C, 0x203D, 0x2044, 0x2045, 0x2047, 0x2048 ) );
hair.Hue = Utility.RandomHairHue();
hair.Layer = Layer.Hair;
hair.Movable = false;
AddItem( hair );
Item beard = new Item( Utility.RandomList( 0x0000, 0x203E, 0x203F, 0x2040, 0x2041, 0x2067, 0x2068, 0x2069 ) );
beard.Hue = hair.Hue;
beard.Layer = Layer.FacialHair;
beard.Movable = false;
AddItem( beard );
Item hat = null;
switch ( Utility.Random( 7 ) ) //6 hats, one empty, for no hat
{
case 0: hat = new SkullCap( GetRandomHue() ); break;
case 1: hat = new Bandana( GetRandomHue() ); break;
case 2: hat = new WideBrimHat(); break;
case 3: hat = new TallStrawHat( Utility.RandomNeutralHue() ); break;
case 4: hat = new StrawHat( Utility.RandomNeutralHue() ); break;
case 5: hat = new TricorneHat( Utility.RandomNeutralHue() ); break;
}
AddItem( hat );
Item pants = null;
switch ( Utility.Random( 2 ) )
{
case 0: pants = new ShortPants( GetRandomHue() ); break;
case 1: pants = new LongPants( GetRandomHue() ); break;
}
AddItem( pants );
Item shirt = null;
switch ( Utility.Random( 5 ) )
{
case 0: shirt = new Doublet( GetRandomHue() ); break;
case 1: shirt = new Surcoat( GetRandomHue() ); break;
case 2: shirt = new Tunic( GetRandomHue() ); break;
case 3: shirt = new FancyShirt( GetRandomHue() ); break;
case 4: shirt = new Shirt( GetRandomHue() ); break;
}
AddItem( shirt );
}
Item feet = null;
switch ( Utility.Random( 3 ) )
{
case 0: feet = new Boots( Utility.RandomNeutralHue() ); break;
case 1: feet = new Shoes( Utility.RandomNeutralHue() ); break;
case 2: feet = new Sandals( Utility.RandomNeutralHue() ); break;
}
AddItem( feet );
Container pack = new Backpack();
pack.DropItem( new Gold( 0, 50 ) );
pack.Movable = false;
AddItem( pack );
}
public XmlQuestNPC( Serial serial ) : base( serial )
{
}
private static int GetRandomHue()
{
switch ( Utility.Random( 6 ) )
{
default:
case 0: return 0;
case 1: return Utility.RandomBlueHue();
case 2: return Utility.RandomGreenHue();
case 3: return Utility.RandomRedHue();
case 4: return Utility.RandomYellowHue();
case 5: return Utility.RandomNeutralHue();
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,768 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Network;
using Server.Menus;
using Server.Menus.Questions;
using Server.Targeting;
using Server.Commands;
using Server.Commands.Generic;
using CPA = Server.CommandPropertyAttribute;
/*
** modified properties gumps taken from RC0 properties gump scripts to support the special XmlSpawner properties gump
*/
namespace Server.Gumps
{
public class XmlPropertiesGump : Gump
{
private ArrayList m_List;
private int m_Page;
private Mobile m_Mobile;
private object m_Object;
#if (NEWTIMERS)
private Stack<PropertiesGump.StackEntry> m_Stack;
#else
private Stack m_Stack;
#endif
public static readonly bool OldStyle = PropsConfig.OldStyle;
public static readonly int GumpOffsetX = PropsConfig.GumpOffsetX;
public static readonly int GumpOffsetY = PropsConfig.GumpOffsetY;
public static readonly int TextHue = PropsConfig.TextHue;
public static readonly int TextOffsetX = PropsConfig.TextOffsetX;
public static readonly int OffsetGumpID = PropsConfig.OffsetGumpID;
public static readonly int HeaderGumpID = PropsConfig.HeaderGumpID;
public static readonly int EntryGumpID = PropsConfig.EntryGumpID;
public static readonly int BackGumpID = PropsConfig.BackGumpID;
public static readonly int SetGumpID = PropsConfig.SetGumpID;
public static readonly int SetWidth = PropsConfig.SetWidth;
public static readonly int SetOffsetX = PropsConfig.SetOffsetX, SetOffsetY = PropsConfig.SetOffsetY;
public static readonly int SetButtonID1 = PropsConfig.SetButtonID1;
public static readonly int SetButtonID2 = PropsConfig.SetButtonID2;
public static readonly int PrevWidth = PropsConfig.PrevWidth;
public static readonly int PrevOffsetX = PropsConfig.PrevOffsetX, PrevOffsetY = PropsConfig.PrevOffsetY;
public static readonly int PrevButtonID1 = PropsConfig.PrevButtonID1;
public static readonly int PrevButtonID2 = PropsConfig.PrevButtonID2;
public static readonly int NextWidth = PropsConfig.NextWidth;
public static readonly int NextOffsetX = PropsConfig.NextOffsetX, NextOffsetY = PropsConfig.NextOffsetY;
public static readonly int NextButtonID1 = PropsConfig.NextButtonID1;
public static readonly int NextButtonID2 = PropsConfig.NextButtonID2;
public static readonly int OffsetSize = PropsConfig.OffsetSize;
public static readonly int EntryHeight = PropsConfig.EntryHeight;
public static readonly int BorderSize = PropsConfig.BorderSize;
private static bool PrevLabel = OldStyle, NextLabel = OldStyle;
private static readonly int PrevLabelOffsetX = PrevWidth + 1;
private static readonly int NameWidth = 103;
private static readonly int ValueWidth = 82;
private static readonly int EntryCount = 66;
private static readonly int ColumnEntryCount = 22;
private static readonly int TypeWidth = NameWidth + OffsetSize + ValueWidth;
private static readonly int TotalWidth = OffsetSize + NameWidth + OffsetSize + ValueWidth + OffsetSize + SetWidth + OffsetSize;
private static readonly int TotalHeight = OffsetSize + ((EntryHeight + OffsetSize) * (EntryCount + 1));
private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
private static readonly int BackHeight = BorderSize + TotalHeight + BorderSize;
public XmlPropertiesGump( Mobile mobile, object o ) : base( GumpOffsetX, GumpOffsetY )
{
m_Mobile = mobile;
m_Object = o;
m_List = BuildList();
Initialize( 0 );
}
#if(NEWTIMERS)
public XmlPropertiesGump( Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, PropertiesGump.StackEntry parent ) : base( GumpOffsetX, GumpOffsetY )
#else
public XmlPropertiesGump( Mobile mobile, object o, Stack stack, object parent ) : base( GumpOffsetX, GumpOffsetY )
#endif
{
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_List = BuildList();
if ( parent != null )
{
if ( m_Stack == null )
#if(NEWTIMERS)
m_Stack = new Stack<PropertiesGump.StackEntry>();
#else
m_Stack = new Stack();
#endif
m_Stack.Push( parent );
}
Initialize( 0 );
}
#if (NEWTIMERS)
public XmlPropertiesGump( Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, ArrayList list, int page ) : base( GumpOffsetX, GumpOffsetY )
#else
public XmlPropertiesGump( Mobile mobile, object o, Stack stack, ArrayList list, int page ) : base( GumpOffsetX, GumpOffsetY )
#endif
{
m_Mobile = mobile;
m_Object = o;
m_List = list;
m_Stack = stack;
Initialize( page );
}
private void Initialize( int page )
{
m_Page = page;
int count = m_List.Count - (page * EntryCount);
if ( count < 0 )
count = 0;
else if ( count > EntryCount )
count = EntryCount;
int lastIndex = (page * EntryCount) + count - 1;
if ( lastIndex >= 0 && lastIndex < m_List.Count && m_List[lastIndex] == null )
--count;
int totalHeight = OffsetSize + ((EntryHeight + OffsetSize) * (ColumnEntryCount + 1));
AddPage( 0 );
AddBackground( 0, 0, TotalWidth*3 + BorderSize*2, BorderSize + totalHeight + BorderSize, BackGumpID );
AddImageTiled( BorderSize, BorderSize + EntryHeight, (TotalWidth - (OldStyle ? SetWidth + OffsetSize : 0))*3, totalHeight-EntryHeight, OffsetGumpID );
int x = BorderSize + OffsetSize;
int y = BorderSize /*+ OffsetSize*/;
int emptyWidth = TotalWidth - PrevWidth - NextWidth - (OffsetSize * 4) - (OldStyle ? SetWidth + OffsetSize : 0);
if(m_Object is Item)
AddLabelCropped( x + TextOffsetX, y, TypeWidth - TextOffsetX, EntryHeight, TextHue, ((Item)m_Object).Name );
int propcount = 0;
for ( int i = 0, index = page * EntryCount; i <= count && index < m_List.Count; ++i, ++index )
{
// do the multi column display
int column = propcount/ColumnEntryCount;
if(propcount%ColumnEntryCount == 0)
y = BorderSize;
x = BorderSize + OffsetSize + column*(ValueWidth + NameWidth +OffsetSize*2 + SetOffsetX + SetWidth);
y += EntryHeight + OffsetSize;
object o = m_List[index];
if ( o == null )
{
AddImageTiled( x - OffsetSize, y, TotalWidth, EntryHeight, BackGumpID + 4 );
propcount++;
}
else
/*if ( o is Type )
{
Type type = (Type)o;
AddImageTiled( x, y, TypeWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, TypeWidth - TextOffsetX, EntryHeight, TextHue, type.Name );
x += TypeWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
}
else
*/
if ( o is PropertyInfo )
{
propcount++;
PropertyInfo prop = (PropertyInfo)o;
// look for the default value of the equivalent property in the XmlSpawnerDefaults.DefaultEntry class
int huemodifier = TextHue;
FieldInfo finfo = null;
Server.Mobiles.XmlSpawnerDefaults.DefaultEntry de = new Server.Mobiles.XmlSpawnerDefaults.DefaultEntry();
Type ftype = de.GetType();
if(ftype != null)
finfo = ftype.GetField(prop.Name);
// is there an equivalent default field?
if(finfo != null){
// see if the value is different from the default
if(ValueToString(finfo.GetValue(de)) != ValueToString(prop))
{
huemodifier = 68;
}
}
AddImageTiled( x, y, NameWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, NameWidth - TextOffsetX, EntryHeight, huemodifier, prop.Name );
x += NameWidth + OffsetSize;
AddImageTiled( x, y, ValueWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, ValueWidth - TextOffsetX, EntryHeight, huemodifier, ValueToString( prop ) );
x += ValueWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
CPA cpa = GetCPA( prop );
if ( prop.CanWrite && cpa != null && m_Mobile.AccessLevel >= cpa.WriteLevel )
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, i + 3, GumpButtonType.Reply, 0 );
}
}
}
public static string[] m_BoolNames = new string[]{ "True", "False" };
public static object[] m_BoolValues = new object[]{ true, false };
public static string[] m_PoisonNames = new string[]{ "None", "Lesser", "Regular", "Greater", "Deadly", "Lethal" };
public static object[] m_PoisonValues = new object[]{ null, Poison.Lesser, Poison.Regular, Poison.Greater, Poison.Deadly, Poison.Lethal };
public override void OnResponse( NetState state, RelayInfo info )
{
Mobile from = state.Mobile;
if ( !BaseCommand.IsAccessible( from, m_Object ) )
{
from.SendMessage( "You may no longer access their properties." );
return;
}
switch ( info.ButtonID )
{
case 0: // Closed
{
if ( m_Stack != null && m_Stack.Count > 0 )
{
#if (NEWTIMERS)
PropertiesGump.StackEntry entry = m_Stack.Pop();
from.SendGump( new XmlPropertiesGump( from, entry.m_Object, m_Stack, null ) );
#else
object obj = m_Stack.Pop();
from.SendGump( new XmlPropertiesGump( from, obj, m_Stack, null ) );
#endif
}
break;
}
case 1: // Previous
{
if ( m_Page > 0 )
from.SendGump( new XmlPropertiesGump( from, m_Object, m_Stack, m_List, m_Page - 1 ) );
break;
}
case 2: // Next
{
if ( (m_Page + 1) * EntryCount < m_List.Count )
from.SendGump( new XmlPropertiesGump( from, m_Object, m_Stack, m_List, m_Page + 1 ) );
break;
}
default:
{
int index = (m_Page * EntryCount) + (info.ButtonID - 3);
if ( index >= 0 && index < m_List.Count )
{
PropertyInfo prop = m_List[index] as PropertyInfo;
if ( prop == null )
return;
CPA attr = GetCPA( prop );
if ( !prop.CanWrite || attr == null || from.AccessLevel < attr.WriteLevel )
return;
Type type = prop.PropertyType;
if ( IsType( type, typeofMobile ) || IsType( type, typeofItem ) )
from.SendGump( new XmlSetObjectGump( prop, from, m_Object, m_Stack, type, m_Page, m_List ) );
else if ( IsType( type, typeofType ) )
from.Target = new XmlSetObjectTarget( prop, from, m_Object, m_Stack, type, m_Page, m_List );
else if ( IsType( type, typeofPoint3D ) )
from.SendGump( new XmlSetPoint3DGump( prop, from, m_Object, m_Stack, m_Page, m_List ) );
else if ( IsType( type, typeofPoint2D ) )
from.SendGump( new XmlSetPoint2DGump( prop, from, m_Object, m_Stack, m_Page, m_List ) );
else if ( IsType( type, typeofTimeSpan ) )
from.SendGump( new XmlSetTimeSpanGump( prop, from, m_Object, m_Stack, m_Page, m_List ) );
else if ( IsCustomEnum( type ) )
from.SendGump( new XmlSetCustomEnumGump( prop, from, m_Object, m_Stack, m_Page, m_List, GetCustomEnumNames( type ) ) );
else if ( IsType( type, typeofEnum ) )
from.SendGump( new XmlSetListOptionGump( prop, from, m_Object, m_Stack, m_Page, m_List, Enum.GetNames( type ), GetObjects( Enum.GetValues( type ) ) ) );
else if ( IsType( type, typeofBool ) )
from.SendGump( new XmlSetListOptionGump( prop, from, m_Object, m_Stack, m_Page, m_List, m_BoolNames, m_BoolValues ) );
else if ( IsType( type, typeofString ) || IsType( type, typeofReal ) || IsType( type, typeofNumeric ) )
from.SendGump( new XmlSetGump( prop, from, m_Object, m_Stack, m_Page, m_List ) );
else if ( IsType( type, typeofPoison ) )
from.SendGump( new XmlSetListOptionGump( prop, from, m_Object, m_Stack, m_Page, m_List, m_PoisonNames, m_PoisonValues ) );
else if ( IsType( type, typeofMap ) )
from.SendGump( new XmlSetListOptionGump( prop, from, m_Object, m_Stack, m_Page, m_List, Map.GetMapNames(), Map.GetMapValues() ) );
else if ( IsType( type, typeofSkills ) && m_Object is Mobile )
{
from.SendGump( new XmlPropertiesGump( from, m_Object, m_Stack, m_List, m_Page ) );
from.SendGump( new SkillsGump( from, (Mobile)m_Object ) );
}
else if( HasAttribute( type, typeofPropertyObject, true ) )
{
#if (NEWTIMERS)
object obj = prop.GetValue( m_Object, null );
if ( obj != null )
from.SendGump( new XmlPropertiesGump( from, obj, m_Stack, new PropertiesGump.StackEntry( m_Object, prop ) ) );
else
from.SendGump( new XmlPropertiesGump( from, m_Object, m_Stack, m_List, m_Page ) );
#else
from.SendGump( new XmlPropertiesGump( from, prop.GetValue( m_Object, null ), m_Stack, m_Object ) );
#endif
}
}
break;
}
}
}
private static object[] GetObjects( Array a )
{
object[] list = new object[a.Length];
for ( int i = 0; i < list.Length; ++i )
list[i] = a.GetValue( i );
return list;
}
private static bool IsCustomEnum( Type type )
{
return type.IsDefined( typeofCustomEnum, false );
}
private static string[] GetCustomEnumNames( Type type )
{
object[] attrs = type.GetCustomAttributes( typeofCustomEnum, false );
if ( attrs.Length == 0 )
return new string[0];
CustomEnumAttribute ce = attrs[0] as CustomEnumAttribute;
if ( ce == null )
return new string[0];
return ce.Names;
}
private static bool HasAttribute( Type type, Type check, bool inherit )
{
object[] objs = type.GetCustomAttributes( check, inherit );
return ( objs != null && objs.Length > 0 );
}
private static bool IsType( Type type, Type check )
{
return type == check || type.IsSubclassOf( check );
}
private static bool IsType( Type type, Type[] check )
{
for ( int i = 0; i < check.Length; ++i )
if ( IsType( type, check[i] ) )
return true;
return false;
}
private static Type typeofMobile = typeof( Mobile );
private static Type typeofItem = typeof( Item );
private static Type typeofType = typeof( Type );
private static Type typeofPoint3D = typeof( Point3D );
private static Type typeofPoint2D = typeof( Point2D );
private static Type typeofTimeSpan = typeof( TimeSpan );
private static Type typeofCustomEnum = typeof( CustomEnumAttribute );
private static Type typeofEnum = typeof( Enum );
private static Type typeofBool = typeof( Boolean );
private static Type typeofString = typeof( String );
private static Type typeofPoison = typeof( Poison );
private static Type typeofMap = typeof( Map );
private static Type typeofSkills = typeof( Skills );
private static Type typeofPropertyObject = typeof( PropertyObjectAttribute );
private static Type typeofNoSort = typeof( NoSortAttribute );
private static Type[] typeofReal = new Type[]
{
typeof( Single ),
typeof( Double )
};
private static Type[] typeofNumeric = new Type[]
{
typeof( Byte ),
typeof( Int16 ),
typeof( Int32 ),
typeof( Int64 ),
typeof( SByte ),
typeof( UInt16 ),
typeof( UInt32 ),
typeof( UInt64 )
};
private string ValueToString( PropertyInfo prop )
{
return ValueToString( m_Object, prop );
}
public static string ValueToString( object obj, PropertyInfo prop )
{
try
{
return ValueToString( prop.GetValue( obj, null ) );
}
catch ( Exception e )
{
return String.Format( "!{0}!", e.GetType() );
}
}
public static string ValueToString( object o )
{
if ( o == null )
{
return "-null-";
}
else if ( o is string )
{
return String.Format( "\"{0}\"", (string)o );
}
else if ( o is bool )
{
return o.ToString();
}
else if ( o is char )
{
return String.Format( "0x{0:X} '{1}'", (int)(char)o, (char)o );
}
else if ( o is Serial )
{
Serial s = (Serial)o;
if ( s.IsValid )
{
if ( s.IsItem )
{
return String.Format( "(I) 0x{0:X}", s.Value );
}
else if ( s.IsMobile )
{
return String.Format( "(M) 0x{0:X}", s.Value );
}
}
return String.Format( "(?) 0x{0:X}", s.Value );
}
else if ( o is byte || o is sbyte || o is short || o is ushort || o is int || o is uint || o is long || o is ulong )
{
return String.Format( "{0} (0x{0:X})", o );
}
else if ( o is double )
{
return o.ToString();
}
else if ( o is Mobile )
{
return String.Format( "(M) 0x{0:X} \"{1}\"", ((Mobile)o).Serial.Value, ((Mobile)o).Name );
}
else if ( o is Item )
{
return String.Format( "(I) 0x{0:X}", ((Item)o).Serial );
}
else if ( o is Type )
{
return ((Type)o).Name;
}
else
{
return o.ToString();
}
}
private ArrayList BuildList()
{
Type type = m_Object.GetType();
PropertyInfo[] props = type.GetProperties( BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public );
ArrayList groups = GetGroups( type, props );
ArrayList list = new ArrayList();
for ( int i = 0; i < groups.Count; ++i )
{
DictionaryEntry de = (DictionaryEntry)groups[i];
ArrayList groupList = (ArrayList)de.Value;
if ( !HasAttribute( (Type)de.Key, typeofNoSort, false ) )
groupList.Sort( PropertySorter.Instance );
if ( i != 0 )
list.Add( null );
list.Add( de.Key );
list.AddRange( groupList );
}
return list;
}
private static Type typeofCPA = typeof( CPA );
private static Type typeofObject = typeof( object );
private static CPA GetCPA( PropertyInfo prop )
{
object[] attrs = prop.GetCustomAttributes( typeofCPA, false );
if ( attrs.Length > 0 )
return attrs[0] as CPA;
else
return null;
}
private ArrayList GetGroups( Type objectType, PropertyInfo[] props )
{
Hashtable groups = new Hashtable();
for ( int i = 0; i < props.Length; ++i )
{
PropertyInfo prop = props[i];
if ( prop.CanRead )
{
CPA attr = GetCPA( prop );
if ( attr != null && m_Mobile.AccessLevel >= attr.ReadLevel )
{
Type type = prop.DeclaringType;
while ( true )
{
Type baseType = type.BaseType;
if ( baseType == null || baseType == typeofObject )
break;
if ( baseType.GetProperty( prop.Name, prop.PropertyType ) != null )
type = baseType;
else
break;
}
ArrayList list = (ArrayList)groups[type];
if ( list == null )
groups[type] = list = new ArrayList();
list.Add( prop );
}
}
}
ArrayList sorted = new ArrayList( groups );
sorted.Sort( new GroupComparer( objectType ) );
return sorted;
}
public static object GetObjectFromString( Type t, string s )
{
if ( t == typeof( string ) )
{
return s;
}
else if ( t == typeof( byte ) || t == typeof( sbyte ) || t == typeof( short ) || t == typeof( ushort ) || t == typeof( int ) || t == typeof( uint ) || t == typeof( long ) || t == typeof( ulong ) )
{
if ( s.StartsWith( "0x" ) )
{
if ( t == typeof( ulong ) || t == typeof( uint ) || t == typeof( ushort ) || t == typeof( byte ) )
{
return Convert.ChangeType( Convert.ToUInt64( s.Substring( 2 ), 16 ), t );
}
else
{
return Convert.ChangeType( Convert.ToInt64( s.Substring( 2 ), 16 ), t );
}
}
else
{
return Convert.ChangeType( s, t );
}
}
else if ( t == typeof( double ) || t == typeof( float ) )
{
return Convert.ChangeType( s, t );
}
else if ( t.IsDefined( typeof( ParsableAttribute ), false ) )
{
MethodInfo parseMethod = t.GetMethod( "Parse", new Type[]{ typeof( string ) } );
return parseMethod.Invoke( null, new object[]{ s } );
}
throw new Exception( "bad" );
}
private static string GetStringFromObject( object o )
{
if ( o == null )
{
return "-null-";
}
else if ( o is string )
{
return String.Format( "\"{0}\"", (string)o );
}
else if ( o is bool )
{
return o.ToString();
}
else if ( o is char )
{
return String.Format( "0x{0:X} '{1}'", (int)(char)o, (char)o );
}
else if ( o is Serial )
{
Serial s = (Serial)o;
if ( s.IsValid )
{
if ( s.IsItem )
{
return String.Format( "(I) 0x{0:X}", s.Value );
}
else if ( s.IsMobile )
{
return String.Format( "(M) 0x{0:X}", s.Value );
}
}
return String.Format( "(?) 0x{0:X}", s.Value );
}
else if ( o is byte || o is sbyte || o is short || o is ushort || o is int || o is uint || o is long || o is ulong )
{
return String.Format( "{0} (0x{0:X})", o );
}
else if ( o is Mobile )
{
return String.Format( "(M) 0x{0:X} \"{1}\"", ((Mobile)o).Serial.Value, ((Mobile)o).Name );
}
else if ( o is Item )
{
return String.Format( "(I) 0x{0:X}", ((Item)o).Serial );
}
else if ( o is Type )
{
return ((Type)o).Name;
}
else
{
return o.ToString();
}
}
private class PropertySorter : IComparer
{
public static readonly PropertySorter Instance = new PropertySorter();
private PropertySorter()
{
}
public int Compare( object x, object y )
{
if ( x == null && y == null )
return 0;
else if ( x == null )
return -1;
else if ( y == null )
return 1;
PropertyInfo a = x as PropertyInfo;
PropertyInfo b = y as PropertyInfo;
if ( a == null || b == null )
throw new ArgumentException();
return a.Name.CompareTo( b.Name );
}
}
private class GroupComparer : IComparer
{
private Type m_Start;
public GroupComparer( Type start )
{
m_Start = start;
}
private static Type typeofObject = typeof( Object );
private int GetDistance( Type type )
{
Type current = m_Start;
int dist;
for ( dist = 0; current != null && current != typeofObject && current != type; ++dist )
current = current.BaseType;
return dist;
}
public int Compare( object x, object y )
{
if ( x == null && y == null )
return 0;
else if ( x == null )
return -1;
else if ( y == null )
return 1;
if ( !(x is DictionaryEntry) || !(y is DictionaryEntry) )
throw new ArgumentException();
DictionaryEntry de1 = (DictionaryEntry)x;
DictionaryEntry de2 = (DictionaryEntry)y;
Type a = (Type)de1.Key;
Type b = (Type)de2.Key;
return GetDistance( a ).CompareTo( GetDistance( b ) );
}
}
}
}

View File

@@ -0,0 +1,50 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Gumps
{
public class XmlSetCustomEnumGump : XmlSetListOptionGump
{
private string[] m_Names;
#if (NEWTIMERS)
public XmlSetCustomEnumGump( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, int propspage, ArrayList list, string[] names ) : base( prop, mobile, o, stack, propspage, list, names, null )
#else
public XmlSetCustomEnumGump( PropertyInfo prop, Mobile mobile, object o, Stack stack, int propspage, ArrayList list, string[] names ) : base( prop, mobile, o, stack, propspage, list, names, null )
#endif
{
m_Names = names;
}
public override void OnResponse( NetState sender, RelayInfo relayInfo )
{
int index = relayInfo.ButtonID - 1;
if ( index >= 0 && index < m_Names.Length )
{
try
{
MethodInfo info = m_Property.PropertyType.GetMethod( "Parse", new Type[]{ typeof( string ) } );
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, m_Names[index] );
if ( info != null )
m_Property.SetValue( m_Object, info.Invoke( null, new object[]{ m_Names[index] } ), null );
else if ( m_Property.PropertyType == typeof( Enum ) || m_Property.PropertyType.IsSubclassOf( typeof( Enum ) ) )
m_Property.SetValue( m_Object, Enum.Parse( m_Property.PropertyType, m_Names[index], false ), null );
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
}
m_Mobile.SendGump( new XmlPropertiesGump( m_Mobile, m_Object, m_Stack, m_List, m_Page ) );
}
}
}

View File

@@ -0,0 +1,301 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Network;
using Server.HuePickers;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Gumps
{
public class XmlSetGump : Gump
{
private PropertyInfo m_Property;
private Mobile m_Mobile;
private object m_Object;
#if (NEWTIMERS)
private Stack<PropertiesGump.StackEntry> m_Stack;
#else
private Stack m_Stack;
#endif
private int m_Page;
private ArrayList m_List;
public static readonly bool OldStyle = PropsConfig.OldStyle;
public static readonly int GumpOffsetX = PropsConfig.GumpOffsetX;
public static readonly int GumpOffsetY = PropsConfig.GumpOffsetY;
public static readonly int TextHue = PropsConfig.TextHue;
public static readonly int TextOffsetX = PropsConfig.TextOffsetX;
public static readonly int OffsetGumpID = PropsConfig.OffsetGumpID;
public static readonly int HeaderGumpID = PropsConfig.HeaderGumpID;
public static readonly int EntryGumpID = PropsConfig.EntryGumpID;
public static readonly int BackGumpID = PropsConfig.BackGumpID;
public static readonly int SetGumpID = PropsConfig.SetGumpID;
public static readonly int SetWidth = PropsConfig.SetWidth;
public static readonly int SetOffsetX = PropsConfig.SetOffsetX, SetOffsetY = PropsConfig.SetOffsetY;
public static readonly int SetButtonID1 = PropsConfig.SetButtonID1;
public static readonly int SetButtonID2 = PropsConfig.SetButtonID2;
public static readonly int PrevWidth = PropsConfig.PrevWidth;
public static readonly int PrevOffsetX = PropsConfig.PrevOffsetX, PrevOffsetY = PropsConfig.PrevOffsetY;
public static readonly int PrevButtonID1 = PropsConfig.PrevButtonID1;
public static readonly int PrevButtonID2 = PropsConfig.PrevButtonID2;
public static readonly int NextWidth = PropsConfig.NextWidth;
public static readonly int NextOffsetX = PropsConfig.NextOffsetX, NextOffsetY = PropsConfig.NextOffsetY;
public static readonly int NextButtonID1 = PropsConfig.NextButtonID1;
public static readonly int NextButtonID2 = PropsConfig.NextButtonID2;
public static readonly int OffsetSize = PropsConfig.OffsetSize;
public static readonly int EntryHeight = PropsConfig.EntryHeight;
public static readonly int BorderSize = PropsConfig.BorderSize;
private static readonly int EntryWidth = 212;
private static readonly int TotalWidth = OffsetSize + EntryWidth + OffsetSize + SetWidth + OffsetSize;
private static readonly int TotalHeight = OffsetSize + (2 * (EntryHeight + OffsetSize));
private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
private static readonly int BackHeight = BorderSize + TotalHeight + BorderSize;
#if (NEWTIMERS)
public XmlSetGump( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, int page, ArrayList list ) : base( GumpOffsetX, GumpOffsetY )
#else
public XmlSetGump( PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list ) : base( GumpOffsetX, GumpOffsetY )
#endif
{
m_Property = prop;
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_Page = page;
m_List = list;
bool canNull = !prop.PropertyType.IsValueType;
bool canDye = prop.IsDefined( typeof( HueAttribute ), false );
bool isBody = prop.IsDefined( typeof( BodyAttribute ), false );
int xextend = 0;
if(prop.PropertyType == typeof(string))
{
xextend = 300;
}
object val = prop.GetValue( m_Object, null );
string initialText;
if ( val == null )
initialText = "";
else
initialText = val.ToString();
AddPage( 0 );
AddBackground( 0, 0, BackWidth+xextend, BackHeight + (canNull ? (EntryHeight + OffsetSize) : 0) + (canDye ? (EntryHeight + OffsetSize) : 0) + (isBody ? (EntryHeight + OffsetSize) : 0), BackGumpID );
AddImageTiled( BorderSize, BorderSize, TotalWidth+xextend - (OldStyle ? SetWidth + OffsetSize : 0), TotalHeight + (canNull ? (EntryHeight + OffsetSize) : 0) + (canDye ? (EntryHeight + OffsetSize) : 0) + (isBody ? (EntryHeight + OffsetSize) : 0), OffsetGumpID );
int x = BorderSize + OffsetSize;
int y = BorderSize + OffsetSize;
AddImageTiled( x, y, EntryWidth+xextend, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth+xextend - TextOffsetX, EntryHeight, TextHue, prop.Name );
x += EntryWidth+xextend + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth+xextend, EntryHeight, EntryGumpID );
AddTextEntry( x + TextOffsetX, y, EntryWidth+xextend - TextOffsetX, EntryHeight, TextHue, 0, initialText );
x += EntryWidth+xextend + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 1, GumpButtonType.Reply, 0 );
if ( canNull )
{
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth+xextend, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth+xextend - TextOffsetX, EntryHeight, TextHue, "Null" );
x += EntryWidth+xextend + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 2, GumpButtonType.Reply, 0 );
}
if ( canDye )
{
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth+xextend, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth+xextend - TextOffsetX, EntryHeight, TextHue, "Hue Picker" );
x += EntryWidth+xextend + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 3, GumpButtonType.Reply, 0 );
}
if ( isBody )
{
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth+xextend, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth+xextend - TextOffsetX, EntryHeight, TextHue, "Body Picker" );
x += EntryWidth+xextend + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 4, GumpButtonType.Reply, 0 );
}
}
private class InternalPicker : HuePicker
{
private PropertyInfo m_Property;
private Mobile m_Mobile;
private object m_Object;
#if (NEWTIMERS)
private Stack<PropertiesGump.StackEntry> m_Stack;
#else
private Stack m_Stack;
#endif
private int m_Page;
private ArrayList m_List;
#if (NEWTIMERS)
public InternalPicker( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, int page, ArrayList list ) : base( ((IHued)o).HuedItemID )
#else
public InternalPicker( PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list ) : base( ((IHued)o).HuedItemID )
#endif
{
m_Property = prop;
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_Page = page;
m_List = list;
}
public override void OnResponse( int hue )
{
try
{
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, hue.ToString() );
m_Property.SetValue( m_Object, hue, null );
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
m_Mobile.SendGump( new XmlPropertiesGump( m_Mobile, m_Object, m_Stack, m_List, m_Page ) );
}
}
public override void OnResponse( NetState sender, RelayInfo info )
{
object toSet;
bool shouldSet, shouldSend = true;
switch ( info.ButtonID )
{
case 1:
{
TextRelay text = info.GetTextEntry( 0 );
if ( text != null )
{
try
{
toSet = XmlPropertiesGump.GetObjectFromString( m_Property.PropertyType, text.Text );
shouldSet = true;
}
catch
{
toSet = null;
shouldSet = false;
m_Mobile.SendMessage( "Bad format" );
}
}
else
{
toSet = null;
shouldSet = false;
}
break;
}
case 2: // Null
{
toSet = null;
shouldSet = true;
break;
}
case 3: // Hue Picker
{
toSet = null;
shouldSet = false;
shouldSend = false;
m_Mobile.SendHuePicker( new InternalPicker( m_Property, m_Mobile, m_Object, m_Stack, m_Page, m_List ) );
break;
}
case 4: // Body Picker
{
toSet = null;
shouldSet = false;
shouldSend = false;
m_Mobile.SendGump( new SetBodyGump( m_Property, m_Mobile, m_Object, new Stack(m_Stack), m_Page, m_List ) );
break;
}
default:
{
toSet = null;
shouldSet = false;
break;
}
}
if ( shouldSet )
{
try
{
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, toSet==null?"(null)":toSet.ToString() );
m_Property.SetValue( m_Object, toSet, null );
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
}
if ( shouldSend )
m_Mobile.SendGump( new XmlPropertiesGump( m_Mobile, m_Object, m_Stack, m_List, m_Page ) );
}
}
}

View File

@@ -0,0 +1,192 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Gumps
{
public class XmlSetListOptionGump : Gump
{
protected PropertyInfo m_Property;
protected Mobile m_Mobile;
protected object m_Object;
#if (NEWTIMERS)
protected Stack<PropertiesGump.StackEntry> m_Stack;
#else
protected Stack m_Stack;
#endif
protected int m_Page;
protected ArrayList m_List;
public static readonly bool OldStyle = PropsConfig.OldStyle;
public static readonly int GumpOffsetX = PropsConfig.GumpOffsetX;
public static readonly int GumpOffsetY = PropsConfig.GumpOffsetY;
public static readonly int TextHue = PropsConfig.TextHue;
public static readonly int TextOffsetX = PropsConfig.TextOffsetX;
public static readonly int OffsetGumpID = PropsConfig.OffsetGumpID;
public static readonly int HeaderGumpID = PropsConfig.HeaderGumpID;
public static readonly int EntryGumpID = PropsConfig.EntryGumpID;
public static readonly int BackGumpID = PropsConfig.BackGumpID;
public static readonly int SetGumpID = PropsConfig.SetGumpID;
public static readonly int SetWidth = PropsConfig.SetWidth;
public static readonly int SetOffsetX = PropsConfig.SetOffsetX, SetOffsetY = PropsConfig.SetOffsetY;
public static readonly int SetButtonID1 = PropsConfig.SetButtonID1;
public static readonly int SetButtonID2 = PropsConfig.SetButtonID2;
public static readonly int PrevWidth = PropsConfig.PrevWidth;
public static readonly int PrevOffsetX = PropsConfig.PrevOffsetX, PrevOffsetY = PropsConfig.PrevOffsetY;
public static readonly int PrevButtonID1 = PropsConfig.PrevButtonID1;
public static readonly int PrevButtonID2 = PropsConfig.PrevButtonID2;
public static readonly int NextWidth = PropsConfig.NextWidth;
public static readonly int NextOffsetX = PropsConfig.NextOffsetX, NextOffsetY = PropsConfig.NextOffsetY;
public static readonly int NextButtonID1 = PropsConfig.NextButtonID1;
public static readonly int NextButtonID2 = PropsConfig.NextButtonID2;
public static readonly int OffsetSize = PropsConfig.OffsetSize;
public static readonly int EntryHeight = PropsConfig.EntryHeight;
public static readonly int BorderSize = PropsConfig.BorderSize;
private static readonly int EntryWidth = 212;
private static readonly int EntryCount = 13;
private static readonly int TotalWidth = OffsetSize + EntryWidth + OffsetSize + SetWidth + OffsetSize;
private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
private static bool PrevLabel = OldStyle, NextLabel = OldStyle;
private static readonly int PrevLabelOffsetX = PrevWidth + 1;
private static readonly int PrevLabelOffsetY = 0;
private static readonly int NextLabelOffsetX = -29;
private static readonly int NextLabelOffsetY = 0;
protected object[] m_Values;
#if (NEWTIMERS)
public XmlSetListOptionGump( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, int propspage, ArrayList list, string[] names, object[] values ) : base( GumpOffsetX, GumpOffsetY )
#else
public XmlSetListOptionGump( PropertyInfo prop, Mobile mobile, object o, Stack stack, int propspage, ArrayList list, string[] names, object[] values ) : base( GumpOffsetX, GumpOffsetY )
#endif
{
m_Property = prop;
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_Page = propspage;
m_List = list;
m_Values = values;
int pages = (names.Length + EntryCount - 1) / EntryCount;
int index = 0;
for ( int page = 1; page <= pages; ++page )
{
AddPage( page );
int start = (page - 1) * EntryCount;
int count = names.Length - start;
if ( count > EntryCount )
count = EntryCount;
int totalHeight = OffsetSize + ((count + 2) * (EntryHeight + OffsetSize));
int backHeight = BorderSize + totalHeight + BorderSize;
AddBackground( 0, 0, BackWidth, backHeight, BackGumpID );
AddImageTiled( BorderSize, BorderSize, TotalWidth - (OldStyle ? SetWidth + OffsetSize : 0), totalHeight, OffsetGumpID );
int x = BorderSize + OffsetSize;
int y = BorderSize + OffsetSize;
int emptyWidth = TotalWidth - PrevWidth - NextWidth - (OffsetSize * 4) - (OldStyle ? SetWidth + OffsetSize : 0);
AddImageTiled( x, y, PrevWidth, EntryHeight, HeaderGumpID );
if ( page > 1 )
{
AddButton( x + PrevOffsetX, y + PrevOffsetY, PrevButtonID1, PrevButtonID2, 0, GumpButtonType.Page, page - 1 );
if ( PrevLabel )
AddLabel( x + PrevLabelOffsetX, y + PrevLabelOffsetY, TextHue, "Previous" );
}
x += PrevWidth + OffsetSize;
if ( !OldStyle )
AddImageTiled( x - (OldStyle ? OffsetSize : 0), y, emptyWidth + (OldStyle ? OffsetSize * 2 : 0), EntryHeight, HeaderGumpID );
x += emptyWidth + OffsetSize;
if ( !OldStyle )
AddImageTiled( x, y, NextWidth, EntryHeight, HeaderGumpID );
if ( page < pages )
{
AddButton( x + NextOffsetX, y + NextOffsetY, NextButtonID1, NextButtonID2, 0, GumpButtonType.Page, page + 1 );
if ( NextLabel )
AddLabel( x + NextLabelOffsetX, y + NextLabelOffsetY, TextHue, "Next" );
}
AddRect( 0, prop.Name, 0 );
for ( int i = 0; i < count; ++i )
AddRect( i + 1, names[index], ++index );
}
}
private void AddRect( int index, string str, int button )
{
int x = BorderSize + OffsetSize;
int y = BorderSize + OffsetSize + ((index + 1) * (EntryHeight + OffsetSize));
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, str );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
if ( button != 0 )
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, button, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
int index = info.ButtonID - 1;
if ( index >= 0 && index < m_Values.Length )
{
try
{
object toSet = m_Values[index];
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, (toSet == null ? "(-null-)" : toSet.ToString()) );
m_Property.SetValue( m_Object, toSet, null );
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
}
m_Mobile.SendGump( new XmlPropertiesGump( m_Mobile, m_Object, m_Stack, m_List, m_Page ) );
}
}
}

View File

@@ -0,0 +1,323 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Network;
using Server.Prompts;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Gumps
{
public class XmlSetObjectGump : Gump
{
private PropertyInfo m_Property;
private Mobile m_Mobile;
private object m_Object;
#if (NEWTIMERS)
private Stack<PropertiesGump.StackEntry> m_Stack;
#else
private Stack m_Stack;
#endif
private Type m_Type;
private int m_Page;
private ArrayList m_List;
public static readonly bool OldStyle = PropsConfig.OldStyle;
public static readonly int GumpOffsetX = PropsConfig.GumpOffsetX;
public static readonly int GumpOffsetY = PropsConfig.GumpOffsetY;
public static readonly int TextHue = PropsConfig.TextHue;
public static readonly int TextOffsetX = PropsConfig.TextOffsetX;
public static readonly int OffsetGumpID = PropsConfig.OffsetGumpID;
public static readonly int HeaderGumpID = PropsConfig.HeaderGumpID;
public static readonly int EntryGumpID = PropsConfig.EntryGumpID;
public static readonly int BackGumpID = PropsConfig.BackGumpID;
public static readonly int SetGumpID = PropsConfig.SetGumpID;
public static readonly int SetWidth = PropsConfig.SetWidth;
public static readonly int SetOffsetX = PropsConfig.SetOffsetX, SetOffsetY = PropsConfig.SetOffsetY;
public static readonly int SetButtonID1 = PropsConfig.SetButtonID1;
public static readonly int SetButtonID2 = PropsConfig.SetButtonID2;
public static readonly int PrevWidth = PropsConfig.PrevWidth;
public static readonly int PrevOffsetX = PropsConfig.PrevOffsetX, PrevOffsetY = PropsConfig.PrevOffsetY;
public static readonly int PrevButtonID1 = PropsConfig.PrevButtonID1;
public static readonly int PrevButtonID2 = PropsConfig.PrevButtonID2;
public static readonly int NextWidth = PropsConfig.NextWidth;
public static readonly int NextOffsetX = PropsConfig.NextOffsetX, NextOffsetY = PropsConfig.NextOffsetY;
public static readonly int NextButtonID1 = PropsConfig.NextButtonID1;
public static readonly int NextButtonID2 = PropsConfig.NextButtonID2;
public static readonly int OffsetSize = PropsConfig.OffsetSize;
public static readonly int EntryHeight = PropsConfig.EntryHeight;
public static readonly int BorderSize = PropsConfig.BorderSize;
private static readonly int EntryWidth = 212;
private static readonly int TotalWidth = OffsetSize + EntryWidth + OffsetSize + SetWidth + OffsetSize;
private static readonly int TotalHeight = OffsetSize + (5 * (EntryHeight + OffsetSize));
private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
private static readonly int BackHeight = BorderSize + TotalHeight + BorderSize;
#if (NEWTIMERS)
public XmlSetObjectGump( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, Type type, int page, ArrayList list ) : base( GumpOffsetX, GumpOffsetY )
#else
public XmlSetObjectGump( PropertyInfo prop, Mobile mobile, object o, Stack stack, Type type, int page, ArrayList list ) : base( GumpOffsetX, GumpOffsetY )
#endif
{
m_Property = prop;
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_Type = type;
m_Page = page;
m_List = list;
string initialText = XmlPropertiesGump.ValueToString( o, prop );
AddPage( 0 );
AddBackground( 0, 0, BackWidth, BackHeight, BackGumpID );
AddImageTiled( BorderSize, BorderSize, TotalWidth - (OldStyle ? SetWidth + OffsetSize : 0), TotalHeight, OffsetGumpID );
int x = BorderSize + OffsetSize;
int y = BorderSize + OffsetSize;
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, prop.Name );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, initialText );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 1, GumpButtonType.Reply, 0 );
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, "Change by Serial" );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 2, GumpButtonType.Reply, 0 );
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, "Nullify" );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 3, GumpButtonType.Reply, 0 );
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, "View Properties" );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 4, GumpButtonType.Reply, 0 );
}
private class InternalPrompt : Prompt
{
private PropertyInfo m_Property;
private Mobile m_Mobile;
private object m_Object;
#if (NEWTIMERS)
private Stack<PropertiesGump.StackEntry> m_Stack;
#else
private Stack m_Stack;
#endif
private Type m_Type;
private int m_Page;
private ArrayList m_List;
#if (NEWTIMERS)
public InternalPrompt( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, Type type, int page, ArrayList list )
#else
public InternalPrompt( PropertyInfo prop, Mobile mobile, object o, Stack stack, Type type, int page, ArrayList list )
#endif
{
m_Property = prop;
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_Type = type;
m_Page = page;
m_List = list;
}
public override void OnCancel( Mobile from )
{
m_Mobile.SendGump( new XmlSetObjectGump( m_Property, m_Mobile, m_Object, m_Stack, m_Type, m_Page, m_List ) );
}
public override void OnResponse( Mobile from, string text )
{
object toSet;
bool shouldSet;
try
{
int serial = Utility.ToInt32( text );
toSet = World.FindEntity( serial );
if ( toSet == null )
{
shouldSet = false;
m_Mobile.SendMessage( "No object with that serial was found." );
}
else if ( !m_Type.IsAssignableFrom( toSet.GetType() ) )
{
toSet = null;
shouldSet = false;
m_Mobile.SendMessage( "The object with that serial could not be assigned to a property of type : {0}", m_Type.Name );
}
else
{
shouldSet = true;
}
}
catch
{
toSet = null;
shouldSet = false;
m_Mobile.SendMessage( "Bad format" );
}
if ( shouldSet )
{
try
{
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, toSet==null?"(null)":toSet.ToString() );
m_Property.SetValue( m_Object, toSet, null );
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
}
m_Mobile.SendGump( new XmlSetObjectGump( m_Property, m_Mobile, m_Object, m_Stack, m_Type, m_Page, m_List ) );
}
}
public override void OnResponse( NetState sender, RelayInfo info )
{
object toSet;
bool shouldSet, shouldSend = true;
object viewProps = null;
switch ( info.ButtonID )
{
case 0: // closed
{
m_Mobile.SendGump( new XmlPropertiesGump( m_Mobile, m_Object, m_Stack, m_List, m_Page ) );
toSet = null;
shouldSet = false;
shouldSend = false;
break;
}
case 1: // Change by Target
{
m_Mobile.Target = new XmlSetObjectTarget( m_Property, m_Mobile, m_Object, m_Stack, m_Type, m_Page, m_List );
toSet = null;
shouldSet = false;
shouldSend = false;
break;
}
case 2: // Change by Serial
{
toSet = null;
shouldSet = false;
shouldSend = false;
m_Mobile.SendMessage( "Enter the serial you wish to find:" );
m_Mobile.Prompt = new InternalPrompt( m_Property, m_Mobile, m_Object, m_Stack, m_Type, m_Page, m_List );
break;
}
case 3: // Nullify
{
toSet = null;
shouldSet = true;
break;
}
case 4: // View Properties
{
toSet = null;
shouldSet = false;
object obj = m_Property.GetValue( m_Object, null );
if ( obj == null )
m_Mobile.SendMessage( "The property is null and so you cannot view its properties." );
else if ( !BaseCommand.IsAccessible( m_Mobile, obj ) )
m_Mobile.SendMessage( "You may not view their properties." );
else
viewProps = obj;
break;
}
default:
{
toSet = null;
shouldSet = false;
break;
}
}
if ( shouldSet )
{
try
{
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, toSet==null?"(null)":toSet.ToString() );
m_Property.SetValue( m_Object, toSet, null );
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
}
if ( shouldSend )
m_Mobile.SendGump( new XmlSetObjectGump( m_Property, m_Mobile, m_Object, m_Stack, m_Type, m_Page, m_List ) );
if ( viewProps != null )
m_Mobile.SendGump( new XmlPropertiesGump( m_Mobile, viewProps ) );
}
}
}

View File

@@ -0,0 +1,75 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Targeting;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Gumps
{
public class XmlSetObjectTarget : Target
{
private PropertyInfo m_Property;
private Mobile m_Mobile;
private object m_Object;
#if (NEWTIMERS)
private Stack<PropertiesGump.StackEntry> m_Stack;
#else
private Stack m_Stack;
#endif
private Type m_Type;
private int m_Page;
private ArrayList m_List;
#if (NEWTIMERS)
public XmlSetObjectTarget( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, Type type, int page, ArrayList list ) : base( -1, false, TargetFlags.None )
#else
public XmlSetObjectTarget( PropertyInfo prop, Mobile mobile, object o, Stack stack, Type type, int page, ArrayList list ) : base( -1, false, TargetFlags.None )
#endif
{
m_Property = prop;
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_Type = type;
m_Page = page;
m_List = list;
}
protected override void OnTarget( Mobile from, object targeted )
{
try
{
if ( m_Type == typeof( Type ) )
targeted = targeted.GetType();
else if ( (m_Type == typeof( BaseAddon ) || m_Type.IsAssignableFrom( typeof( BaseAddon ) )) && targeted is AddonComponent )
targeted = ((AddonComponent)targeted).Addon;
if ( m_Type.IsAssignableFrom( targeted.GetType() ) )
{
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, targeted.ToString() );
m_Property.SetValue( m_Object, targeted, null );
}
else
{
m_Mobile.SendMessage( "That cannot be assigned to a property of type : {0}", m_Type.Name );
}
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
}
protected override void OnTargetFinish( Mobile from )
{
if ( m_Type == typeof( Type ) )
from.SendGump( new XmlPropertiesGump( m_Mobile, m_Object, m_Stack, m_List, m_Page ) );
else
from.SendGump( new XmlSetObjectGump( m_Property, m_Mobile, m_Object, m_Stack, m_Type, m_Page, m_List ) );
}
}
}

View File

@@ -0,0 +1,253 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Targeting;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Gumps
{
public class XmlSetPoint2DGump : Gump
{
private PropertyInfo m_Property;
private Mobile m_Mobile;
private object m_Object;
#if (NEWTIMERS)
private Stack<PropertiesGump.StackEntry> m_Stack;
#else
private Stack m_Stack;
#endif
private int m_Page;
private ArrayList m_List;
public static readonly bool OldStyle = PropsConfig.OldStyle;
public static readonly int GumpOffsetX = PropsConfig.GumpOffsetX;
public static readonly int GumpOffsetY = PropsConfig.GumpOffsetY;
public static readonly int TextHue = PropsConfig.TextHue;
public static readonly int TextOffsetX = PropsConfig.TextOffsetX;
public static readonly int OffsetGumpID = PropsConfig.OffsetGumpID;
public static readonly int HeaderGumpID = PropsConfig.HeaderGumpID;
public static readonly int EntryGumpID = PropsConfig.EntryGumpID;
public static readonly int BackGumpID = PropsConfig.BackGumpID;
public static readonly int SetGumpID = PropsConfig.SetGumpID;
public static readonly int SetWidth = PropsConfig.SetWidth;
public static readonly int SetOffsetX = PropsConfig.SetOffsetX, SetOffsetY = PropsConfig.SetOffsetY;
public static readonly int SetButtonID1 = PropsConfig.SetButtonID1;
public static readonly int SetButtonID2 = PropsConfig.SetButtonID2;
public static readonly int PrevWidth = PropsConfig.PrevWidth;
public static readonly int PrevOffsetX = PropsConfig.PrevOffsetX, PrevOffsetY = PropsConfig.PrevOffsetY;
public static readonly int PrevButtonID1 = PropsConfig.PrevButtonID1;
public static readonly int PrevButtonID2 = PropsConfig.PrevButtonID2;
public static readonly int NextWidth = PropsConfig.NextWidth;
public static readonly int NextOffsetX = PropsConfig.NextOffsetX, NextOffsetY = PropsConfig.NextOffsetY;
public static readonly int NextButtonID1 = PropsConfig.NextButtonID1;
public static readonly int NextButtonID2 = PropsConfig.NextButtonID2;
public static readonly int OffsetSize = PropsConfig.OffsetSize;
public static readonly int EntryHeight = PropsConfig.EntryHeight;
public static readonly int BorderSize = PropsConfig.BorderSize;
private static readonly int CoordWidth = 105;
private static readonly int EntryWidth = CoordWidth + OffsetSize + CoordWidth;
private static readonly int TotalWidth = OffsetSize + EntryWidth + OffsetSize + SetWidth + OffsetSize;
private static readonly int TotalHeight = OffsetSize + (4 * (EntryHeight + OffsetSize));
private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
private static readonly int BackHeight = BorderSize + TotalHeight + BorderSize;
#if (NEWTIMERS)
public XmlSetPoint2DGump( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, int page, ArrayList list ) : base( GumpOffsetX, GumpOffsetY )
#else
public XmlSetPoint2DGump( PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list ) : base( GumpOffsetX, GumpOffsetY )
#endif
{
m_Property = prop;
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_Page = page;
m_List = list;
Point2D p = (Point2D)prop.GetValue( o, null );
AddPage( 0 );
AddBackground( 0, 0, BackWidth, BackHeight, BackGumpID );
AddImageTiled( BorderSize, BorderSize, TotalWidth - (OldStyle ? SetWidth + OffsetSize : 0), TotalHeight, OffsetGumpID );
int x = BorderSize + OffsetSize;
int y = BorderSize + OffsetSize;
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, prop.Name );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, "Use your location" );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 1, GumpButtonType.Reply, 0 );
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, "Target a location" );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 2, GumpButtonType.Reply, 0 );
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, CoordWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, CoordWidth - TextOffsetX, EntryHeight, TextHue, "X:" );
AddTextEntry( x + 16, y, CoordWidth - 16, EntryHeight, TextHue, 0, p.X.ToString() );
x += CoordWidth + OffsetSize;
AddImageTiled( x, y, CoordWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, CoordWidth - TextOffsetX, EntryHeight, TextHue, "Y:" );
AddTextEntry( x + 16, y, CoordWidth - 16, EntryHeight, TextHue, 1, p.Y.ToString() );
x += CoordWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 3, GumpButtonType.Reply, 0 );
}
private class InternalTarget : Target
{
private PropertyInfo m_Property;
private Mobile m_Mobile;
private object m_Object;
#if (NEWTIMERS)
private Stack<PropertiesGump.StackEntry> m_Stack;
#else
private Stack m_Stack;
#endif
private int m_Page;
private ArrayList m_List;
#if (NEWTIMERS)
public InternalTarget( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, int page, ArrayList list ) : base( -1, true, TargetFlags.None )
#else
public InternalTarget( PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list ) : base( -1, true, TargetFlags.None )
#endif
{
m_Property = prop;
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_Page = page;
m_List = list;
}
protected override void OnTarget( Mobile from, object targeted )
{
IPoint3D p = targeted as IPoint3D;
if ( p != null )
{
try
{
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, new Point2D( p ).ToString() );
m_Property.SetValue( m_Object, new Point2D( p ), null );
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
}
}
protected override void OnTargetFinish( Mobile from )
{
m_Mobile.SendGump( new XmlPropertiesGump( m_Mobile, m_Object, m_Stack, m_List, m_Page ) );
}
}
public override void OnResponse( NetState sender, RelayInfo info )
{
Point2D toSet;
bool shouldSet, shouldSend;
switch ( info.ButtonID )
{
case 1: // Current location
{
toSet = new Point2D( m_Mobile.Location );
shouldSet = true;
shouldSend = true;
break;
}
case 2: // Pick location
{
m_Mobile.Target = new InternalTarget( m_Property, m_Mobile, m_Object, m_Stack, m_Page, m_List );
toSet = Point2D.Zero;
shouldSet = false;
shouldSend = false;
break;
}
case 3: // Use values
{
TextRelay x = info.GetTextEntry( 0 );
TextRelay y = info.GetTextEntry( 1 );
toSet = new Point2D( x == null ? 0 : Utility.ToInt32( x.Text ), y == null ? 0 : Utility.ToInt32( y.Text ) );
shouldSet = true;
shouldSend = true;
break;
}
default:
{
toSet = Point2D.Zero;
shouldSet = false;
shouldSend = true;
break;
}
}
if ( shouldSet )
{
try
{
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, toSet.ToString() );
m_Property.SetValue( m_Object, toSet, null );
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
}
if ( shouldSend )
m_Mobile.SendGump( new XmlPropertiesGump( m_Mobile, m_Object, m_Stack, m_List, m_Page ) );
}
}
}

View File

@@ -0,0 +1,259 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Targeting;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Gumps
{
public class XmlSetPoint3DGump : Gump
{
private PropertyInfo m_Property;
private Mobile m_Mobile;
private object m_Object;
#if (NEWTIMERS)
private Stack<PropertiesGump.StackEntry> m_Stack;
#else
private Stack m_Stack;
#endif
private int m_Page;
private ArrayList m_List;
public static readonly bool OldStyle = PropsConfig.OldStyle;
public static readonly int GumpOffsetX = PropsConfig.GumpOffsetX;
public static readonly int GumpOffsetY = PropsConfig.GumpOffsetY;
public static readonly int TextHue = PropsConfig.TextHue;
public static readonly int TextOffsetX = PropsConfig.TextOffsetX;
public static readonly int OffsetGumpID = PropsConfig.OffsetGumpID;
public static readonly int HeaderGumpID = PropsConfig.HeaderGumpID;
public static readonly int EntryGumpID = PropsConfig.EntryGumpID;
public static readonly int BackGumpID = PropsConfig.BackGumpID;
public static readonly int SetGumpID = PropsConfig.SetGumpID;
public static readonly int SetWidth = PropsConfig.SetWidth;
public static readonly int SetOffsetX = PropsConfig.SetOffsetX, SetOffsetY = PropsConfig.SetOffsetY;
public static readonly int SetButtonID1 = PropsConfig.SetButtonID1;
public static readonly int SetButtonID2 = PropsConfig.SetButtonID2;
public static readonly int PrevWidth = PropsConfig.PrevWidth;
public static readonly int PrevOffsetX = PropsConfig.PrevOffsetX, PrevOffsetY = PropsConfig.PrevOffsetY;
public static readonly int PrevButtonID1 = PropsConfig.PrevButtonID1;
public static readonly int PrevButtonID2 = PropsConfig.PrevButtonID2;
public static readonly int NextWidth = PropsConfig.NextWidth;
public static readonly int NextOffsetX = PropsConfig.NextOffsetX, NextOffsetY = PropsConfig.NextOffsetY;
public static readonly int NextButtonID1 = PropsConfig.NextButtonID1;
public static readonly int NextButtonID2 = PropsConfig.NextButtonID2;
public static readonly int OffsetSize = PropsConfig.OffsetSize;
public static readonly int EntryHeight = PropsConfig.EntryHeight;
public static readonly int BorderSize = PropsConfig.BorderSize;
private static readonly int CoordWidth = 70;
private static readonly int EntryWidth = CoordWidth + OffsetSize + CoordWidth + OffsetSize + CoordWidth;
private static readonly int TotalWidth = OffsetSize + EntryWidth + OffsetSize + SetWidth + OffsetSize;
private static readonly int TotalHeight = OffsetSize + (4 * (EntryHeight + OffsetSize));
private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
private static readonly int BackHeight = BorderSize + TotalHeight + BorderSize;
#if (NEWTIMERS)
public XmlSetPoint3DGump( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, int page, ArrayList list ) : base( GumpOffsetX, GumpOffsetY )
#else
public XmlSetPoint3DGump( PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list ) : base( GumpOffsetX, GumpOffsetY )
#endif
{
m_Property = prop;
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_Page = page;
m_List = list;
Point3D p = (Point3D)prop.GetValue( o, null );
AddPage( 0 );
AddBackground( 0, 0, BackWidth, BackHeight, BackGumpID );
AddImageTiled( BorderSize, BorderSize, TotalWidth - (OldStyle ? SetWidth + OffsetSize : 0), TotalHeight, OffsetGumpID );
int x = BorderSize + OffsetSize;
int y = BorderSize + OffsetSize;
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, prop.Name );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, "Use your location" );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 1, GumpButtonType.Reply, 0 );
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, "Target a location" );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 2, GumpButtonType.Reply, 0 );
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
AddImageTiled( x, y, CoordWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, CoordWidth - TextOffsetX, EntryHeight, TextHue, "X:" );
AddTextEntry( x + 16, y, CoordWidth - 16, EntryHeight, TextHue, 0, p.X.ToString() );
x += CoordWidth + OffsetSize;
AddImageTiled( x, y, CoordWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, CoordWidth - TextOffsetX, EntryHeight, TextHue, "Y:" );
AddTextEntry( x + 16, y, CoordWidth - 16, EntryHeight, TextHue, 1, p.Y.ToString() );
x += CoordWidth + OffsetSize;
AddImageTiled( x, y, CoordWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, CoordWidth - TextOffsetX, EntryHeight, TextHue, "Z:" );
AddTextEntry( x + 16, y, CoordWidth - 16, EntryHeight, TextHue, 2, p.Z.ToString() );
x += CoordWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, 3, GumpButtonType.Reply, 0 );
}
private class InternalTarget : Target
{
private PropertyInfo m_Property;
private Mobile m_Mobile;
private object m_Object;
#if (NEWTIMERS)
private Stack<PropertiesGump.StackEntry> m_Stack;
#else
private Stack m_Stack;
#endif
private int m_Page;
private ArrayList m_List;
#if (NEWTIMERS)
public InternalTarget( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, int page, ArrayList list ) : base( -1, true, TargetFlags.None )
#else
public InternalTarget( PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list ) : base( -1, true, TargetFlags.None )
#endif
{
m_Property = prop;
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_Page = page;
m_List = list;
}
protected override void OnTarget( Mobile from, object targeted )
{
IPoint3D p = targeted as IPoint3D;
if ( p != null )
{
try
{
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, new Point3D( p ).ToString() );
m_Property.SetValue( m_Object, new Point3D( p ), null );
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
}
}
protected override void OnTargetFinish( Mobile from )
{
m_Mobile.SendGump( new XmlPropertiesGump( m_Mobile, m_Object, m_Stack, m_List, m_Page ) );
}
}
public override void OnResponse( NetState sender, RelayInfo info )
{
Point3D toSet;
bool shouldSet, shouldSend;
switch ( info.ButtonID )
{
case 1: // Current location
{
toSet = m_Mobile.Location;
shouldSet = true;
shouldSend = true;
break;
}
case 2: // Pick location
{
m_Mobile.Target = new InternalTarget( m_Property, m_Mobile, m_Object, m_Stack, m_Page, m_List );
toSet = Point3D.Zero;
shouldSet = false;
shouldSend = false;
break;
}
case 3: // Use values
{
TextRelay x = info.GetTextEntry( 0 );
TextRelay y = info.GetTextEntry( 1 );
TextRelay z = info.GetTextEntry( 2 );
toSet = new Point3D( x == null ? 0 : Utility.ToInt32( x.Text ), y == null ? 0 : Utility.ToInt32( y.Text ), z == null ? 0 : Utility.ToInt32( z.Text ) );
shouldSet = true;
shouldSend = true;
break;
}
default:
{
toSet = Point3D.Zero;
shouldSet = false;
shouldSend = true;
break;
}
}
if ( shouldSet )
{
try
{
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, toSet.ToString() );
m_Property.SetValue( m_Object, toSet, null );
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
}
if ( shouldSend )
m_Mobile.SendGump( new XmlPropertiesGump( m_Mobile, m_Object, m_Stack, m_List, m_Page ) );
}
}
}

View File

@@ -0,0 +1,254 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Network;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Gumps
{
public class XmlSetTimeSpanGump : Gump
{
private PropertyInfo m_Property;
private Mobile m_Mobile;
private object m_Object;
#if (NEWTIMERS)
private Stack<PropertiesGump.StackEntry> m_Stack;
#else
private Stack m_Stack;
#endif
private int m_Page;
private ArrayList m_List;
public static readonly bool OldStyle = PropsConfig.OldStyle;
public static readonly int GumpOffsetX = PropsConfig.GumpOffsetX;
public static readonly int GumpOffsetY = PropsConfig.GumpOffsetY;
public static readonly int TextHue = PropsConfig.TextHue;
public static readonly int TextOffsetX = PropsConfig.TextOffsetX;
public static readonly int OffsetGumpID = PropsConfig.OffsetGumpID;
public static readonly int HeaderGumpID = PropsConfig.HeaderGumpID;
public static readonly int EntryGumpID = PropsConfig.EntryGumpID;
public static readonly int BackGumpID = PropsConfig.BackGumpID;
public static readonly int SetGumpID = PropsConfig.SetGumpID;
public static readonly int SetWidth = PropsConfig.SetWidth;
public static readonly int SetOffsetX = PropsConfig.SetOffsetX, SetOffsetY = PropsConfig.SetOffsetY;
public static readonly int SetButtonID1 = PropsConfig.SetButtonID1;
public static readonly int SetButtonID2 = PropsConfig.SetButtonID2;
public static readonly int PrevWidth = PropsConfig.PrevWidth;
public static readonly int PrevOffsetX = PropsConfig.PrevOffsetX, PrevOffsetY = PropsConfig.PrevOffsetY;
public static readonly int PrevButtonID1 = PropsConfig.PrevButtonID1;
public static readonly int PrevButtonID2 = PropsConfig.PrevButtonID2;
public static readonly int NextWidth = PropsConfig.NextWidth;
public static readonly int NextOffsetX = PropsConfig.NextOffsetX, NextOffsetY = PropsConfig.NextOffsetY;
public static readonly int NextButtonID1 = PropsConfig.NextButtonID1;
public static readonly int NextButtonID2 = PropsConfig.NextButtonID2;
public static readonly int OffsetSize = PropsConfig.OffsetSize;
public static readonly int EntryHeight = PropsConfig.EntryHeight;
public static readonly int BorderSize = PropsConfig.BorderSize;
private static readonly int EntryWidth = 212;
private static readonly int TotalWidth = OffsetSize + EntryWidth + OffsetSize + SetWidth + OffsetSize;
private static readonly int TotalHeight = OffsetSize + (7 * (EntryHeight + OffsetSize));
private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
private static readonly int BackHeight = BorderSize + TotalHeight + BorderSize;
#if (NEWTIMERS)
public XmlSetTimeSpanGump( PropertyInfo prop, Mobile mobile, object o, Stack<PropertiesGump.StackEntry> stack, int page, ArrayList list ) : base( GumpOffsetX, GumpOffsetY )
#else
public XmlSetTimeSpanGump( PropertyInfo prop, Mobile mobile, object o, Stack stack, int page, ArrayList list ) : base( GumpOffsetX, GumpOffsetY )
#endif
{
m_Property = prop;
m_Mobile = mobile;
m_Object = o;
m_Stack = stack;
m_Page = page;
m_List = list;
TimeSpan ts = (TimeSpan)prop.GetValue( o, null );
AddPage( 0 );
AddBackground( 0, 0, BackWidth, BackHeight, BackGumpID );
AddImageTiled( BorderSize, BorderSize, TotalWidth - (OldStyle ? SetWidth + OffsetSize : 0), TotalHeight, OffsetGumpID );
AddRect( 0, prop.Name, 0, -1 );
AddRect( 1, ts.ToString(), 0, -1 );
AddRect( 2, "Zero", 1, -1 );
AddRect( 3, "From H:M:S", 2, -1 );
AddRect( 4, "H:", 3, 0 );
AddRect( 5, "M:", 4, 1 );
AddRect( 6, "S:", 5, 2 );
}
private void AddRect( int index, string str, int button, int text )
{
int x = BorderSize + OffsetSize;
int y = BorderSize + OffsetSize + (index * (EntryHeight + OffsetSize));
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y, EntryWidth - TextOffsetX, EntryHeight, TextHue, str );
if ( text != -1 )
AddTextEntry( x + 16 + TextOffsetX, y, EntryWidth - TextOffsetX - 16, EntryHeight, TextHue, text, "" );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
if ( button != 0 )
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, button, GumpButtonType.Reply, 0 );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
TimeSpan toSet;
bool shouldSet, shouldSend;
TextRelay h = info.GetTextEntry( 0 );
TextRelay m = info.GetTextEntry( 1 );
TextRelay s = info.GetTextEntry( 2 );
switch ( info.ButtonID )
{
case 1: // Zero
{
toSet = TimeSpan.Zero;
shouldSet = true;
shouldSend = true;
break;
}
case 2: // From H:M:S
{
if ( h != null && m != null && s != null )
{
try
{
toSet = TimeSpan.Parse( h.Text + ":" + m.Text + ":" + s.Text );
shouldSet = true;
shouldSend = true;
break;
}
catch
{
}
}
toSet = TimeSpan.Zero;
shouldSet = false;
shouldSend = false;
break;
}
case 3: // From H
{
if ( h != null )
{
try
{
toSet = TimeSpan.FromHours( Utility.ToDouble( h.Text ) );
shouldSet = true;
shouldSend = true;
break;
}
catch
{
}
}
toSet = TimeSpan.Zero;
shouldSet = false;
shouldSend = false;
break;
}
case 4: // From M
{
if ( m != null )
{
try
{
toSet = TimeSpan.FromMinutes( Utility.ToDouble( m.Text ) );
shouldSet = true;
shouldSend = true;
break;
}
catch
{
}
}
toSet = TimeSpan.Zero;
shouldSet = false;
shouldSend = false;
break;
}
case 5: // From S
{
if ( s != null )
{
try
{
toSet = TimeSpan.FromSeconds( Utility.ToDouble( s.Text ) );
shouldSet = true;
shouldSend = true;
break;
}
catch
{
}
}
toSet = TimeSpan.Zero;
shouldSet = false;
shouldSend = false;
break;
}
default:
{
toSet = TimeSpan.Zero;
shouldSet = false;
shouldSend = true;
break;
}
}
if ( shouldSet )
{
try
{
CommandLogging.LogChangeProperty( m_Mobile, m_Object, m_Property.Name, toSet.ToString() );
m_Property.SetValue( m_Object, toSet, null );
}
catch
{
m_Mobile.SendMessage( "An exception was caught. The property may not have changed." );
}
}
if ( shouldSend )
m_Mobile.SendGump( new XmlPropertiesGump( m_Mobile, m_Object, m_Stack, m_List, m_Page ) );
}
}
}

View File

@@ -0,0 +1,41 @@
using System;
using Server;
using Server.Gumps;
using Server.Engines.XmlSpawner2;
namespace Server.Items
{
[Flipable( 0x1E5E, 0x1E5F )]
public class QuestLeadersBoard : Item
{
public QuestLeadersBoard( Serial serial ) : base( serial )
{
}
[Constructable]
public QuestLeadersBoard() : base( 0x1e5e )
{
Movable = false;
Name = "Quest Leaders Board";
}
public override void OnDoubleClick( Mobile from )
{
from.SendGump( new XmlQuestLeaders.TopQuestPlayersGump( XmlAttach.FindAttachment(from,typeof(XmlQuestPoints)) as XmlQuestPoints) );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,67 @@
using System;
using Server;
using System.Collections;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Engines.XmlSpawner2
{
public class QuestLeadersStone: Item
{
[Constructable]
public QuestLeadersStone() : base( 0xED4)
{
Movable = false;
Visible = false;
Name = "Quest LeaderboardSave Stone";
// is there already another?
ArrayList dlist = new ArrayList();
foreach( Item i in World.Items.Values)
{
if(i is QuestLeadersStone && i != this)
{
dlist.Add(i);
}
}
foreach(Item d in dlist)
{
d.Delete();
}
}
public QuestLeadersStone( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile m )
{
if( m != null && m.AccessLevel >= AccessLevel.Administrator)
{
CommandEventArgs e = new CommandEventArgs(m, "", "", new string[0]);
XmlQuestLeaders.QuestLeaderboardSave_OnCommand(e);
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
XmlQuestLeaders.QuestLBSSerialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize( reader );
XmlQuestLeaders.QuestLBSDeserialize( reader );
int version = reader.ReadInt();
// version 0
}
}
}

View File

@@ -0,0 +1,417 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Prompts;
using Server.Engines.XmlSpawner2;
//
// XmlLogGump
// modified from RC0 BOBGump.cs
//
namespace Server.Gumps
{
public class XMLQuestLogGump : Gump
{
private Mobile m_From;
private List<object> m_List;
private int m_Page;
private const int LabelColor = 0x7FFF;
public int GetIndexForPage( int page )
{
int index = 0;
while ( page-- > 0 )
index += GetCountForIndex( index );
return index;
}
public int GetCountForIndex( int index )
{
int slots = 0;
int count = 0;
List<object> list = m_List;
for ( int i = index; i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
int add;
add = 1;
if ( (slots + add) > 10 )
break;
slots += add;
++count;
}
return count;
}
public XMLQuestLogGump( Mobile from ) : this( from, 0, null )
{
}
public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
{
if(info == null || m_From == null) return;
switch ( info.ButtonID )
{
case 0: // EXIT
{
break;
}
case 2: // Previous page
{
if ( m_Page > 0 )
m_From.SendGump( new XMLQuestLogGump( m_From, m_Page - 1, m_List ) );
return;
}
case 3: // Next page
{
if ( GetIndexForPage( m_Page + 1 ) < m_List.Count )
m_From.SendGump( new XMLQuestLogGump( m_From, m_Page + 1, m_List ) );
break;
}
case 10: // Top players
{
// if this player has an XmlQuestPoints attachment, find it
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m_From,typeof(XmlQuestPoints));
m_From.CloseGump(typeof(XmlQuestLeaders.TopQuestPlayersGump));
m_From.SendGump(new XmlQuestLeaders.TopQuestPlayersGump(p));
break;
}
default:
{
if ( info.ButtonID >= 2000 )
{
int index = info.ButtonID - 2000;
if ( index < 0 || index >= m_List.Count )
break;
if(m_List[index] is IXmlQuest)
{
IXmlQuest o = m_List[index] as IXmlQuest;
if(o != null && !o.Deleted){
m_From.SendGump( new XMLQuestLogGump( m_From, m_Page, null ) );
m_From.CloseGump( typeof( XmlQuestStatusGump ) );
m_From.SendGump( new XmlQuestStatusGump(o, o.TitleString, 320, 0, true) );
}
}
}
break;
}
}
}
public XMLQuestLogGump( Mobile from, int page, List<object> list ) : base( 12, 24 )
{
if(from == null) return;
from.CloseGump( typeof( XMLQuestLogGump ) );
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(from, typeof(XmlQuestPoints));
m_From = from;
m_Page = page;
if ( list == null )
{
// make a new list based on the number of items in the book
int nquests = 0;
list = new List<object>( );
// find all quest items in the players pack
if(from.Backpack != null)
{
Item [] packquestitems = from.Backpack.FindItemsByType(typeof(IXmlQuest));
if (packquestitems != null)
{
nquests += packquestitems.Length;
for ( int i = 0; i < packquestitems.Length; ++i )
{
if(packquestitems[i] != null && !packquestitems[i].Deleted && !(packquestitems[i].Parent is XmlQuestBook))
list.Add( packquestitems[i] );
}
}
// find any questbooks they might have
Item [] questbookitems = from.Backpack.FindItemsByType(typeof(XmlQuestBook));
if(questbookitems != null)
{
for ( int j = 0; j < questbookitems.Length; ++j )
{
Item [] questitems = ((XmlQuestBook)questbookitems[j]).FindItemsByType(typeof(IXmlQuest));
if(questitems != null)
{
nquests += questitems.Length;
for ( int i = 0; i < questitems.Length; ++i )
{
list.Add( questitems[i] );
}
}
}
}
// find any completed quests on the XmlQuestPoints attachment
if(p != null && p.QuestList != null)
{
// add all completed quests
foreach(XmlQuestPoints.QuestEntry q in p.QuestList)
{
list.Add(q);
}
}
}
}
m_List = list;
int index = GetIndexForPage( page );
int count = GetCountForIndex( index );
int tableIndex = 0;
int width = 600;
width = 766;
X = (824 - width) / 2;
int xoffset = 20;
AddPage( 0 );
AddBackground( 10, 10, width, 439, 5054 );
AddImageTiled( 18, 20, width - 17, 420, 2624 );
AddImageTiled( 58 - xoffset, 64, 36, 352, 200 ); // open
AddImageTiled( 96 - xoffset, 64, 163, 352, 1416 ); // name
AddImageTiled( 261 - xoffset, 64, 55, 352, 200 ); // type
AddImageTiled( 308 - xoffset, 64, 85, 352, 1416 ); // status
AddImageTiled( 395 - xoffset, 64, 116, 352, 200 ); // expires
AddImageTiled( 511 - xoffset, 64, 42, 352, 1416 ); // points
AddImageTiled( 555 - xoffset, 64, 175, 352, 200 ); // completed
AddImageTiled( 734 - xoffset, 64, 42, 352, 1416 ); // repeated
for ( int i = index; i < (index + count) && i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
AddImageTiled( 24, 94 + (tableIndex * 32), 489, 2, 2624 );
++tableIndex;
}
AddAlphaRegion( 18, 20, width - 17, 420 );
AddImage( 5, 5, 10460 );
AddImage( width - 15, 5, 10460 );
AddImage( 5, 424, 10460 );
AddImage( width - 15, 424, 10460 );
AddHtmlLocalized( 375, 25, 200, 30, 1046026, LabelColor, false, false ); // Quest Log
AddHtmlLocalized( 63 - xoffset, 45, 200, 32, 1072837, LabelColor, false, false ); // Current Points:
AddHtml( 243 - xoffset, 45, 200, 32, XmlSimpleGump.Color("Available Credits:","FFFFFF"), false, false ); // Your Reward Points:
AddHtml( 453 - xoffset, 45, 200, 32, XmlSimpleGump.Color("Rank:","FFFFFF"), false, false ); // Rank
AddHtml( 600 - xoffset, 45, 200, 32, XmlSimpleGump.Color("Quests Completed:","FFFFFF"), false, false ); // Quests completed
if(p != null)
{
int pcolor = 53;
AddLabel(170 - xoffset, 45, pcolor, p.Points.ToString());
AddLabel(350 - xoffset, 45, pcolor, p.Credits.ToString());
AddLabel(500 - xoffset, 45, pcolor, p.Rank.ToString());
AddLabel(720 - xoffset, 45, pcolor, p.QuestsCompleted.ToString());
}
AddHtmlLocalized( 63 - xoffset, 64, 200, 32, 3000362, LabelColor, false, false ); // Open
AddHtmlLocalized( 147 - xoffset, 64, 200, 32, 3005104, LabelColor, false, false ); // Name
AddHtmlLocalized( 270 - xoffset, 64, 200, 32, 1062213, LabelColor, false, false ); // Type
AddHtmlLocalized( 326 - xoffset, 64, 200, 32, 3000132, LabelColor, false, false ); // Status
AddHtmlLocalized( 429 - xoffset, 64, 200, 32, 1062465, LabelColor, false, false ); // Expires
AddHtml( 514 - xoffset, 64, 200, 32, XmlSimpleGump.Color("Points","FFFFFF"), false, false ); // Points
AddHtml( 610 - xoffset, 64, 200, 32, XmlSimpleGump.Color("Next Available","FFFFFF"), false, false ); // Next Available
//AddHtmlLocalized( 610 - xoffset, 64, 200, 32, 1046033, LabelColor, false, false ); // Completed
AddHtmlLocalized( 738 - xoffset, 64, 200, 32, 3005020, LabelColor, false, false ); // Repeat
AddButton( 675 - xoffset, 416, 4017, 4018, 0, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 710 - xoffset, 416, 120, 20, 1011441, LabelColor, false, false ); // EXIT
AddButton( 113 - xoffset, 416, 0xFA8, 0xFAA, 10, GumpButtonType.Reply, 0 );
AddHtml( 150 - xoffset, 416, 200, 32, XmlSimpleGump.Color("Top Players","FFFFFF"), false, false ); // Top players gump
tableIndex = 0;
if ( page > 0 )
{
AddButton( 225, 416, 4014, 4016, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 260, 416, 150, 20, 1011067, LabelColor, false, false ); // Previous page
}
if ( GetIndexForPage( page + 1 ) < list.Count )
{
AddButton( 375, 416, 4005, 4007, 3, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 410, 416, 150, 20, 1011066, LabelColor, false, false ); // Next page
}
for ( int i = index; i < (index + count) && i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
if ( obj is IXmlQuest )
{
IXmlQuest e = (IXmlQuest)obj;
int y = 96 + (tableIndex++ * 32);
AddButton( 60 - xoffset, y + 2, 0xFAB, 0xFAD, 2000 + i, GumpButtonType.Reply, 0 ); // open gump
int color;
if(!e.IsValid)
{
color = 33;
}
else
if(e.IsCompleted)
{
color = 67;
}
else
{
color = 5;
}
AddLabel( 100 - xoffset, y, color, (string)e.Name );
//AddHtmlLocalized( 315, y, 200, 32, e.IsCompleted ? 1049071 : 1049072, htmlcolor, false, false ); // Completed/Incomplete
AddLabel( 315 - xoffset, y, color, e.IsCompleted ? "Completed" : "In Progress" );
// indicate the expiration time
if(e.IsValid)
{
// do a little parsing of the expiration string to fit it in the space
string substring = e.ExpirationString;
if(e.ExpirationString.IndexOf("Expires in") >= 0)
{
substring = e.ExpirationString.Substring(11);
}
AddLabel( 400 - xoffset, y, color, (string)substring );
}
else
{
AddLabel( 400 - xoffset, y, color, "No longer valid" );
}
if(e.PartyEnabled)
{
AddLabel( 270 - xoffset, y, color, "Party" );
//AddHtmlLocalized( 250, y, 200, 32, 3000332, htmlcolor, false, false ); // Party
}
else
{
AddLabel( 270 - xoffset, y, color, "Solo" );
}
AddLabel( 515 - xoffset, y, color, e.Difficulty.ToString() );
}
else
if(obj is XmlQuestPoints.QuestEntry)
{
XmlQuestPoints.QuestEntry e = (XmlQuestPoints.QuestEntry)obj;
int y = 96 + (tableIndex++ * 32);
int color = 67;
AddLabel( 100 - xoffset, y, color, (string)e.Name );
AddLabel( 315 - xoffset, y, color, "Completed" );
if(e.PartyEnabled)
{
AddLabel( 270 - xoffset, y, color, "Party" );
//AddHtmlLocalized( 250, y, 200, 32, 3000332, htmlcolor, false, false ); // Party
}
else
{
AddLabel( 270 - xoffset, y, color, "Solo" );
}
AddLabel( 515 - xoffset, y, color, e.Difficulty.ToString() );
//AddLabel( 560 - xoffset, y, color, e.WhenCompleted.ToString() );
// determine when the quest can be done again by looking for an xmlquestattachment with the same name
XmlQuestAttachment qa = (XmlQuestAttachment)XmlAttach.FindAttachment(from, typeof(XmlQuestAttachment), e.Name);
if(qa != null)
{
if(qa.Expiration == TimeSpan.Zero)
{
AddLabel( 560 - xoffset, y, color, "Not Repeatable" );
}
else
{
DateTime nexttime = DateTime.UtcNow + qa.Expiration;
AddLabel( 560 - xoffset, y, color, nexttime.ToString() );
}
}
else
{
// didnt find one so it can be done again
AddLabel( 560 - xoffset, y, color, "Available Now" );
}
AddLabel( 741 - xoffset, y, color, e.TimesCompleted.ToString() );
}
}
}
}
}

View File

@@ -0,0 +1,229 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Engines.XmlSpawner2;
/*
** QuestRewardGump
** ArteGordon
** updated 9/18/05
**
** Gives out rewards based on the XmlQuestReward reward list entries and the players Credits that are accumulated through quests with the XmlQuestPoints attachment.
** The Gump supports Item, Mobile, and Attachment type rewards.
*/
namespace Server.Gumps
{
public class QuestRewardGump : Gump
{
private List<XmlQuestPointsRewards> Rewards;
private int y_inc = 35;
private int x_creditoffset = 350;
private int x_pointsoffset = 480;
private int maxItemsPerPage = 9;
private int viewpage;
public QuestRewardGump( Mobile from, int page ) : base( 20, 30 )
{
from.CloseGump(typeof(QuestRewardGump));
// determine the gump size based on the number of rewards
Rewards = XmlQuestPointsRewards.RewardsList;
viewpage = page;
int height = maxItemsPerPage*y_inc + 120;
int width = x_pointsoffset+110;
/*
if(Rewards != null && Rewards.Count > 0)
{
height = Rewards.Count*y_inc + 120;
}
*/
AddBackground( 0, 0, width, height, 0xDAC );
AddHtml( 40, 20, 350, 50, "Rewards Available for Purchase with QuestPoints Credits", false, false );
int qcredits = XmlQuestPoints.GetCredits(from);
AddLabel( 400, 20, 0, String.Format("Available Credits: {0}", qcredits ));
int qpoints = XmlQuestPoints.GetPoints(from);
//AddButton( 30, height - 35, 0xFB7, 0xFB9, 0, GumpButtonType.Reply, 0 );
//AddLabel( 70, height - 35, 0, "Close" );
// put the page buttons in the lower right corner
if(Rewards != null && Rewards.Count > 0)
{
AddLabel( width - 165, height - 35, 0, String.Format("Page: {0}/{1}", viewpage+1, (int)(Rewards.Count/maxItemsPerPage)+1));
// page up and down buttons
AddButton( width - 55, height - 35, 0x15E0, 0x15E4, 13, GumpButtonType.Reply, 0 );
AddButton( width - 35, height - 35, 0x15E2, 0x15E6, 12, GumpButtonType.Reply, 0 );
}
AddLabel( 70, 50, 40, "Reward" );
AddLabel( x_creditoffset, 50, 40, "Credits" );
AddLabel( x_pointsoffset, 50, 40, "Min Points" );
// display the items with their selection buttons
if(Rewards != null)
{
int y = 50;
for(int i = 0; i < Rewards.Count; i++)
{
if((int)(i/maxItemsPerPage) != viewpage) continue;
XmlQuestPointsRewards r = Rewards[i];
if(r == null) continue;
y += y_inc;
int texthue = 0;
// display the item
if(r.MinPoints > qpoints || r.Cost > qcredits)
{
texthue = 33;
}
else
{
// add the selection button
AddButton( 30, y, 0xFA5, 0xFA7, 1000+i, GumpButtonType.Reply, 0 );
}
// display the name
AddLabel( 70, y+3, texthue, r.Name);
// display the cost
AddLabel( x_creditoffset, y+3, texthue, r.Cost.ToString() );
// display the item
if(r.ItemID > 0)
AddItem(x_creditoffset+60, y+r.yOffset, r.ItemID, r.ItemHue);
// display the min points requirement
AddLabel( x_pointsoffset, y+3, texthue, r.MinPoints.ToString() );
}
}
}
public override void OnResponse( NetState state, RelayInfo info )
{
if(info == null || state == null || state.Mobile == null || Rewards == null) return;
Mobile from = state.Mobile;
switch ( info.ButtonID )
{
case 12:
// page up
int nitems = 0;
if(Rewards != null)
nitems = Rewards.Count;
int page = viewpage+1;
if(page > (int)(nitems/maxItemsPerPage))
{
page = (int)(nitems/maxItemsPerPage);
}
state.Mobile.SendGump( new QuestRewardGump( state.Mobile, page));
break;
case 13:
// page down
page = viewpage-1;
if(page < 0)
{
page = 0;
}
state.Mobile.SendGump( new QuestRewardGump( state.Mobile, page));
break;
default:
{
if(info.ButtonID >= 1000)
{
int selection = info.ButtonID - 1000;
if(selection < Rewards.Count)
{
XmlQuestPointsRewards r = Rewards[selection];
// check the price
if(XmlQuestPoints.HasCredits(from, r.Cost, r.MinPoints))
{
// create an instance of the reward type
object o = null;
try
{
o = Activator.CreateInstance( r.RewardType , r.RewardArgs);
}
catch {}
bool received = true;
if(o is Item)
{
// and give them the item
from.AddToBackpack((Item)o);
}
else if(o is Mobile)
{
// if it is controllable then set the buyer as master. Note this does not check for control slot limits.
if(o is BaseCreature)
{
BaseCreature b = o as BaseCreature;
b.Controlled = true;
b.ControlMaster = from;
}
((Mobile)o).MoveToWorld(from.Location, from.Map);
}
else if(o is XmlAttachment)
{
XmlAttachment a = o as XmlAttachment;
XmlAttach.AttachTo(from, a);
}
else
{
from.SendMessage(33, "unable to create {0}.", r.RewardType.Name);
received = false;
}
// complete the transaction
if(received)
{
// charge them
if(XmlQuestPoints.TakeCredits(from, r.Cost))
{
from.SendMessage("You have purchased {0} for {1} credits.", r.Name, r.Cost);
}
else
{
if(o is Item)
((Item)o).Delete();
else if(o is Mobile)
((Mobile)o).Delete();
else if(o is XmlAttachment)
((XmlAttachment)o).Delete();
}
}
}
else
{
from.SendMessage("Insufficient Credits for {0}.", r.Name);
}
from.SendGump(new QuestRewardGump(from, viewpage));
}
}
break;
}
}
}
}
}

View File

@@ -0,0 +1,61 @@
using System;
using Server.Gumps;
/*
** QuestRewardStone
** used to open the QuestPointsRewardGump that allows players to purchase rewards with their XmlQuestPoints Credits.
*/
namespace Server.Items
{
public class QuestRewardStone : Item
{
[Constructable]
public QuestRewardStone() : base( 0xED4 )
{
Movable = false;
Name = "a Quest Points Reward Stone";
}
public QuestRewardStone( Serial serial ) : base( serial )
{
}
public override bool HandlesOnMovement{ get{ return true; } }
public override void OnMovement( Mobile m, Point3D oldLocation )
{
if ( m.Player )
{
if ( !m.InRange( this.Location, 2 ) )
m.CloseGump( typeof( QuestRewardGump ) );
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override void OnDoubleClick( Mobile from )
{
if ( from.InRange( GetWorldLocation(), 2 ) )
{
from.SendGump( new QuestRewardGump( from, 0 ) );
}
else
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
}
}
}
}

View File

@@ -0,0 +1,341 @@
using System;
using Server;
using Server.Network;
using Server.Items;
using Server.Mobiles;
using Server.Prompts;
using Server.Targeting;
using Server.Engines.XmlSpawner2;
//
// XmlPlayerQuestGump
//
namespace Server.Gumps
{
public class XmlPlayerQuestGump : Gump
{
private PlayerMobile m_From;
private IXmlQuest m_QuestItem;
public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
{
if(info == null || sender == null || sender.Mobile == null) return;
// read the text entries for the search criteria
TextRelay tr = info.GetTextEntry( 100 ); // quest name
if(tr != null)
m_QuestItem.Name = tr.Text.Trim();
tr = info.GetTextEntry( 102 ); // title
if(tr != null)
m_QuestItem.TitleString = tr.Text.Trim();
tr = info.GetTextEntry( 103 ); // notestring
if(tr != null)
m_QuestItem.NoteString = tr.Text;
tr = info.GetTextEntry( 200 ); // objectives
if(tr != null)
m_QuestItem.Objective1 = tr.Text.Trim();
tr = info.GetTextEntry( 201 );
if(tr != null)
m_QuestItem.Objective2 = tr.Text.Trim();
tr = info.GetTextEntry( 202 );
if(tr != null)
m_QuestItem.Objective3 = tr.Text.Trim();
tr = info.GetTextEntry( 203 );
if (tr != null)
m_QuestItem.Objective4 = tr.Text.Trim();
tr = info.GetTextEntry( 204 );
if(tr != null)
m_QuestItem.Objective5 = tr.Text.Trim();
tr = info.GetTextEntry( 205 );
if(tr != null && tr.Text != null && tr.Text.Length > 0) // descriptions
m_QuestItem.Description1 = tr.Text.Trim();
else
m_QuestItem.Description1 = null;
tr = info.GetTextEntry( 206 );
if(tr != null && tr.Text != null && tr.Text.Length > 0)
m_QuestItem.Description2 = tr.Text.Trim();
else
m_QuestItem.Description2 = null;
tr = info.GetTextEntry( 207 );
if(tr != null && tr.Text != null && tr.Text.Length > 0)
m_QuestItem.Description3 = tr.Text.Trim();
else
m_QuestItem.Description3 = null;
tr = info.GetTextEntry( 208 );
if(tr != null && tr.Text != null && tr.Text.Length > 0)
m_QuestItem.Description4 = tr.Text.Trim();
else
m_QuestItem.Description4 = null;
tr = info.GetTextEntry( 209 );
if(tr != null && tr.Text != null && tr.Text.Length > 0)
m_QuestItem.Description5 = tr.Text.Trim();
else
m_QuestItem.Description5 = null;
tr = info.GetTextEntry( 210 ); // expiration
if(tr != null && tr.Text != null && tr.Text.Length > 0){
try{m_QuestItem.Expiration = double.Parse(tr.Text.Trim());} catch{}
}
// check all of the check boxes
m_QuestItem.PartyEnabled = info.IsSwitched(300);
m_QuestItem.CanSeeReward = info.IsSwitched(301);
// refresh the time created
m_QuestItem.TimeCreated = DateTime.UtcNow;
switch ( info.ButtonID )
{
case 0: // Okay
{
break;
}
case 1: // Select Reward
{
sender.Mobile.Target = new RewardTarget(m_QuestItem);
break;
}
case 2: // Select Reward Return
{
sender.Mobile.Target = new ReturnTarget(m_QuestItem);
break;
}
}
}
public XmlPlayerQuestGump( PlayerMobile from, IXmlQuest questitem ) : base( 12, 140 )
{
from.CloseGump( typeof( XmlPlayerQuestGump ) );
if(from == null || from.Deleted || questitem == null || questitem.Deleted) return;
m_From = from;
m_QuestItem = questitem;
int width = 600;
//width = 516;
X = (624 - width) / 2;
AddPage( 0 );
AddBackground( 10, 10, width, 439, 5054 );
AddImageTiled( 18, 20, width - 17, 420, 2624 );
AddAlphaRegion( 18, 20, width - 17, 420 );
AddImage( 5, 5, 10460 );
AddImage( width - 15, 5, 10460 );
AddImage( 5, 424, 10460 );
AddImage( width - 15, 424, 10460 );
// add the Quest Title
AddLabel( width/2 - 50, 15, 0x384, "Player Quest Maker" );
int y = 35;
// add the Quest Name
AddLabel( 28, y, 0x384, "Quest Name" );
string name = questitem.Name;
if(name != null)
{
name = name.Substring(4);
}
AddImageTiled( 26, y + 20, 232, 20, 0xBBC );
AddTextEntry( 26, y + 20, 250, 20, 0, 100, name );
// add the Quest Title
AddLabel( 328, y, 0x384, "Quest Title" );
AddImageTiled( 306, y + 20, 232, 20, 0xBBC );
AddTextEntry( 306, y + 20, 230, 20, 0, 102, questitem.TitleString );
y += 50;
// add the Quest Text
AddLabel( 28, y, 0x384, "Quest Text" );
AddImageTiled( 26, y + 20, 532, 80, 0xBBC );
AddTextEntry( 26, y + 20, 530, 80, 0, 103, questitem.NoteString );
y += 110;
// add the Quest Expiration
AddLabel( 28, y, 0x384, "Expiration" );
AddLabel( 98, y + 20, 0x384, "Hours" );
AddImageTiled( 26, y + 20, 52, 20, 0xBBC );
AddTextEntry( 26, y + 20, 50, 20, 0, 210, questitem.Expiration.ToString() );
y += 50;
// add the Quest Objectives
AddLabel( 28, y, 0x384, "Quest Objectives" );
AddImageTiled( 26, y + 20, 252, 19, 0xBBC );
AddTextEntry( 26, y + 20, 250, 19, 0, 200, questitem.Objective1 );
AddImageTiled( 26, y + 40, 252, 19, 0xBBC );
AddTextEntry( 26, y + 40, 250, 19, 0, 201, questitem.Objective2 );
AddImageTiled( 26, y + 60, 252, 19, 0xBBC );
AddTextEntry( 26, y + 60, 250, 19, 0, 202, questitem.Objective3 );
AddImageTiled( 26, y + 80, 252, 19, 0xBBC );
AddTextEntry( 26, y + 80, 250, 19, 0, 203, questitem.Objective4 );
AddImageTiled( 26, y + 100, 252, 19, 0xBBC );
AddTextEntry( 26, y + 100, 250, 19, 0, 204, questitem.Objective5 );
// add the Quest Objectives
AddLabel( 328, y, 0x384, "Objective Descriptions" );
AddImageTiled( 306, y + 20, 252, 19, 0xBBC );
AddTextEntry( 306, y + 20, 250, 19, 0, 205, questitem.Description1 );
AddImageTiled( 306, y + 40, 252, 19, 0xBBC );
AddTextEntry( 306, y + 40, 250, 19, 0, 206, questitem.Description2 );
AddImageTiled( 306, y + 60, 252, 19, 0xBBC );
AddTextEntry( 306, y + 60, 250, 19, 0, 207, questitem.Description3 );
AddImageTiled( 306, y + 80, 252, 19, 0xBBC );
AddTextEntry( 306, y + 80, 250, 19, 0, 208, questitem.Description4 );
AddImageTiled( 306, y + 100, 252, 19, 0xBBC );
AddTextEntry( 306, y + 100, 250, 19, 0, 209, questitem.Description5 );
y += 130;
// party enable toggle
AddCheck( 25, y, 0xD2, 0xD3, questitem.PartyEnabled, 300);
AddLabel( 48, y, 0x384, "PartyEnabled" );
y += 20;
// can see toggle
AddCheck( 25, y, 0xD2, 0xD3, questitem.CanSeeReward, 301);
AddLabel( 48, y, 0x384, "CanSeeReward" );
// select reward button
AddButton( 225, y+3, 2103, 2103, 1, GumpButtonType.Reply, 0 );
AddLabel( 245, y, 0x384, "Select Reward" );
// select reward button
AddButton( 375, y+3, 2103, 2103, 2, GumpButtonType.Reply, 0 );
AddLabel( 395, y, 0x384, "Select Return Container" );
AddButton( 45, 416, 2130, 2129, 0, GumpButtonType.Reply, 0 ); // Okay button
//AddButton( 375 - xoffset, 416, 4017, 4018, 0, GumpButtonType.Reply, 0 );
//AddHtmlLocalized( 410 - xoffset, 416, 120, 20, 1011441, LabelColor, false, false ); // EXIT
}
private class RewardTarget : Target
{
IXmlQuest m_QuestItem;
public RewardTarget(IXmlQuest questitem) : base ( 30, true, TargetFlags.None )
{
m_QuestItem = questitem;
}
protected override void OnTarget( Mobile from, object targeted )
{
if(m_QuestItem == null || m_QuestItem.Deleted) return;
// first check to see if you are too far from the return container. This is to avoid exploits involving targeting a container
// then using the return reward feature as a free transport of items back to that container
if(m_QuestItem.ReturnContainer != null && !m_QuestItem.ReturnContainer.Deleted)
{
Point3D returnloc;
if(m_QuestItem.ReturnContainer.Parent == null)
{
returnloc = m_QuestItem.ReturnContainer.Location;
} else
if(m_QuestItem.ReturnContainer.RootParent != null)
{
returnloc = ((IEntity)m_QuestItem.ReturnContainer.RootParent).Location;
} else
{
from.SendMessage("Invalid container location");
return;
}
if(!Utility.InRange( returnloc, from.Location, 10))
{
// out of range
from.SendMessage("Too far away from the reward return container");
return;
}
}
// try to add the item as the reward item
if(m_QuestItem.PlayerMade && (from != null) && !from.Deleted && (from is PlayerMobile) &&
(from == m_QuestItem.Creator) && (from == m_QuestItem.Owner) && (targeted is Item) &&
!(targeted is IXmlQuest))
{
Item i = targeted as Item;
// make sure the target item is in the oweners backpack
if(i != null && !i.Deleted && i.RootParent == m_QuestItem.Owner)
{
m_QuestItem.RewardItem = i;
m_QuestItem.AutoReward = true;
} else
{
from.SendMessage("Targeted item must be in the owners pack");
}
}
}
}
private class ReturnTarget : Target
{
IXmlQuest m_QuestItem;
public ReturnTarget(IXmlQuest questitem) : base ( 30, true, TargetFlags.None )
{
m_QuestItem = questitem;
}
protected override void OnTarget( Mobile from, object targeted )
{
if(m_QuestItem == null || m_QuestItem.Deleted) return;
// try to add the item as the reward item
if(m_QuestItem.PlayerMade && (from != null) && !from.Deleted && (from is PlayerMobile) &&
(from == m_QuestItem.Creator) && (from == m_QuestItem.Owner) && targeted is Container)
{
Container i = targeted as Container;
// make sure the target item is in the oweners backpack
if(i != null && !i.Deleted )
{
m_QuestItem.ReturnContainer = i;
from.SendMessage("Reward return container set");
} else
{
from.SendMessage("Targeted item must be a valid container");
}
}
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,85 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Server.Mobiles;
using System.IO;
namespace Server.Engines.XmlSpawner2
{
public class XmlQuestAttachment : XmlAttachment
{
private DateTime m_DataValue;
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 XmlQuestAttachment(ASerial serial)
: base(serial)
{
}
[Attachable]
public XmlQuestAttachment(string name)
{
Name = name;
Date = DateTime.UtcNow;
}
[Attachable]
public XmlQuestAttachment(string name, double expiresin)
{
Name = name;
Date = DateTime.UtcNow;
Expiration = TimeSpan.FromMinutes(expiresin);
}
[Attachable]
public XmlQuestAttachment(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.AccessLevel == AccessLevel.Player) return null;
if (Expiration > TimeSpan.Zero)
{
return String.Format("Quest '{2}' Completed {0} expires in {1} mins", Date, Expiration.TotalMinutes, Name);
}
else
{
return String.Format("Quest '{1}' Completed {0}", Date, Name);
}
}
}
}

View File

@@ -0,0 +1,279 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Mobiles;
using System.IO;
using System.Collections.Generic;
using Server.Targeting;
using Server.Engines.PartySystem;
using System.Data;
using System.Xml;
/*
** XmlQuestBook class
**
*/
namespace Server.Items
{
[Flipable( 0x1E5E, 0x1E5F )]
public class PlayerQuestBoard : XmlQuestBook
{
public override bool IsDecoContainer
{
get { return false; }
}
public PlayerQuestBoard( Serial serial ) : base( serial )
{
}
[Constructable]
public PlayerQuestBoard() : base( 0x1e5e )
{
Movable = false;
Name = "Player Quest Board";
LiftOverride = true; // allow players to store books in it
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class XmlQuestBook : Container
{
private PlayerMobile m_Owner;
private bool m_Locked;
[CommandProperty( AccessLevel.GameMaster )]
public PlayerMobile Owner
{ get{ return m_Owner; }
set { m_Owner = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Locked
{ get{ return m_Locked; }
set { m_Locked = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool IsCompleted
{ get{
Item [] questitems = this.FindItemsByType(typeof(IXmlQuest));
if(questitems == null || questitems.Length <= 0)
return false;
for ( int i = 0; i < questitems.Length; ++i )
{
IXmlQuest q = questitems[i] as IXmlQuest;
// check completion and validity status of all quests held in the book
if(q == null || q.Deleted || !q.IsValid || !q.IsCompleted) return false;
}
return true;
}
}
public XmlQuestBook( Serial serial ) : base( serial )
{
}
[Constructable]
public XmlQuestBook(int itemid) : this( )
{
ItemID = itemid;
}
[Constructable]
public XmlQuestBook() : base( 0x2259 )
{
//LootType = LootType.Blessed;
Name = "QuestBook";
Hue = 100;
}
public override void OnDoubleClick( Mobile from )
{
if(!(from is PlayerMobile)) return;
if(from.AccessLevel >= AccessLevel.GameMaster)
{
base.OnDoubleClick(from);
}
from.SendGump( new XmlQuestBookGump( (PlayerMobile)from, this ) );
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
if(dropped is IXmlQuest && !Locked)
{
return base.OnDragDrop(from,dropped);
} else
{
return false;
}
}
private void CheckOwnerFlag()
{
if(Owner != null && !Owner.Deleted)
{
// need to check to see if any other questtoken items are owned
// search the Owners top level pack for an xmlquest
List<Item> list = XmlQuest.FindXmlQuest(Owner);
if(list == null || list.Count == 0)
{
// if none remain then flag the ower as having none
Owner.SetFlag(XmlQuest.CarriedXmlQuestFlag,false);
}
}
}
public virtual void Invalidate()
{
if(Owner != null)
{
Owner.SendMessage(String.Format("{0} Quests invalidated - '{1}' removed", TotalItems,Name));
}
this.Delete();
}
public override void OnItemLifted(Mobile from, Item item)
{
base.OnItemLifted(from,item);
if(from is PlayerMobile && Owner == null)
{
Owner = from as PlayerMobile;
LootType = LootType.Blessed;
// flag the owner as carrying a questtoken assuming the book contains quests and then confirm it with CheckOwnerFlag
Owner.SetFlag(XmlQuest.CarriedXmlQuestFlag,true);
CheckOwnerFlag();
}
}
#if(NEWPARENT)
public override void OnAdded(IEntity parent)
#else
public override void OnAdded(object parent)
#endif
{
base.OnAdded(parent);
if(parent != null && parent is Container)
{
// find the parent of the container
// note, the only valid additions are to the player pack. Anything else is invalid. This is to avoid exploits involving storage or transfer of questtokens
object from = ((Container)parent).Parent;
// check to see if it can be added
if(from != null && from is PlayerMobile)
{
// if it was not owned then allow it to go anywhere
if(Owner == null)
{
Owner = from as PlayerMobile;
LootType = LootType.Blessed;
// could also bless all of the quests inside as well but not actually necessary since blessed containers retain their
// contents whether blessed or not, and when dropped the questtokens will be blessed
// flag the owner as carrying a questtoken
Owner.SetFlag(XmlQuest.CarriedXmlQuestFlag,true);
CheckOwnerFlag();
} else
if(from as PlayerMobile != Owner || parent is BankBox)
{
// tried to give it to another player or placed it in the players bankbox. try to return it to the owners pack
Owner.AddToBackpack(this);
}
} else
{
if(Owner != null)
{
// try to return it to the owners pack
Owner.AddToBackpack(this);
}
// allow placement into npcs or drop on their corpses when owner is null
else
if(!(from is Mobile) && !(parent is Corpse))
{
// in principle this should never be reached
// invalidate the token
CheckOwnerFlag();
Invalidate();
}
}
}
}
public override void OnDelete()
{
base.OnDelete();
CheckOwnerFlag();
}
public override bool OnDroppedToWorld(Mobile from,Point3D point)
{
bool returnvalue = base.OnDroppedToWorld(from,point);
from.SendGump( new XmlConfirmDeleteGump(from,this));
//CheckOwnerFlag();
//Invalidate();
return false;
//return returnvalue;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( m_Owner);
writer.Write( m_Locked);
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
this.m_Owner = reader.ReadMobile() as PlayerMobile;
this.m_Locked = reader.ReadBool();
}
}
}

View File

@@ -0,0 +1,308 @@
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Items;
using Server.Mobiles;
using Server.Prompts;
using Server.Engines.XmlSpawner2;
//
// XmlQuestBookGump
// modified from RC0 BOBGump.cs
//
namespace Server.Gumps
{
public class XmlQuestBookGump : Gump
{
private PlayerMobile m_From;
private XmlQuestBook m_Book;
private ArrayList m_List;
private int m_Page;
private const int LabelColor = 0x7FFF;
public int GetIndexForPage( int page )
{
int index = 0;
while ( page-- > 0 )
index += GetCountForIndex( index );
return index;
}
public int GetCountForIndex( int index )
{
int slots = 0;
int count = 0;
ArrayList list = m_List;
for ( int i = index; i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
int add;
add = 1;
if ( (slots + add) > 10 )
break;
slots += add;
++count;
}
return count;
}
public XmlQuestBookGump( PlayerMobile from, XmlQuestBook book ) : this( from, book, 0, null )
{
}
public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
{
if(info == null || m_From == null) return;
switch ( info.ButtonID )
{
case 0: // EXIT
{
break;
}
case 2: // Previous page
{
if ( m_Page > 0 )
m_From.SendGump( new XmlQuestBookGump( m_From, m_Book, m_Page - 1, m_List ) );
return;
}
case 3: // Next page
{
if ( GetIndexForPage( m_Page + 1 ) < m_List.Count )
m_From.SendGump( new XmlQuestBookGump( m_From, m_Book, m_Page + 1, m_List ) );
break;
}
default:
{
if ( info.ButtonID >= 2000 )
{
int index = info.ButtonID - 2000;
if ( index < 0 || index >= m_List.Count )
break;
if(m_List[index] is IXmlQuest)
{
IXmlQuest o = m_List[index] as IXmlQuest;
if(o != null && !o.Deleted){
m_From.SendGump( new XmlQuestBookGump( m_From, m_Book, m_Page, null ) );
m_From.CloseGump( typeof( XmlQuestStatusGump ) );
m_From.SendGump( new XmlQuestStatusGump(o, o.TitleString, 320, 0, true) );
}
}
} else
if ( info.ButtonID >= 1000 )
{
int index = info.ButtonID - 1000;
if ( index < 0 || index >= m_List.Count )
break;
// allow quests to be dropped from books that are either in the world or in the players backpack
if ( m_Book.IsChildOf( m_From.Backpack ) || (m_Book.Parent == null))
{
// move the item from the book to the players backpack
Item item = m_List[index] as Item;
if ( item != null && !item.Deleted)
{
m_From.AddToBackpack( item );
m_From.SendGump( new XmlQuestBookGump( m_From, m_Book, m_Page, null ) );
}
else
{
m_From.SendMessage( "Internal error. The quest could not be retrieved." );
}
}
}
break;
}
}
}
public XmlQuestBookGump( PlayerMobile from, XmlQuestBook book, int page, ArrayList list ) : base( 12, 24 )
{
from.CloseGump( typeof( XmlQuestBookGump ) );
m_From = from;
m_Book = book;
m_Page = page;
if ( list == null )
{
// make a new list based on the number of items in the book
int nquests = 0;
Item [] questitems = book.FindItemsByType(typeof(IXmlQuest));
if(questitems != null)
nquests = questitems.Length;
list = new ArrayList( nquests );
for ( int i = 0; i < nquests; ++i )
{
list.Add( questitems[i] );
}
}
m_List = list;
int index = GetIndexForPage( page );
int count = GetCountForIndex( index );
int tableIndex = 0;
int width = 600;
width = 516;
X = (624 - width) / 2;
int xoffset = 0;
if(m_Book.Locked)
xoffset = 20;
AddPage( 0 );
AddBackground( 10, 10, width, 439, 5054 );
AddImageTiled( 18, 20, width - 17, 420, 2624 );
AddImageTiled( 58 - xoffset, 64, 36, 352, 200 ); // open
AddImageTiled( 96 - xoffset, 64, 163, 352, 1416 ); // name
AddImageTiled( 261 - xoffset, 64, 55, 352, 200 ); // type
AddImageTiled( 308 - xoffset, 64, 85, 352, 1416 ); // status
AddImageTiled( 395 - xoffset, 64, 116, 352, 200 ); // expires
for ( int i = index; i < (index + count) && i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
AddImageTiled( 24, 94 + (tableIndex * 32), 489, 2, 2624 );
++tableIndex;
}
AddAlphaRegion( 18, 20, width - 17, 420 );
AddImage( 5, 5, 10460 );
AddImage( width - 15, 5, 10460 );
AddImage( 5, 424, 10460 );
AddImage( width - 15, 424, 10460 );
AddHtmlLocalized( 224, 32, 200, 32, 1046026, LabelColor, false, false ); // Quest Log
AddHtmlLocalized( 63 - xoffset, 64, 200, 32, 3000362, LabelColor, false, false ); // Open
AddHtmlLocalized( 147 - xoffset, 64, 200, 32, 3005104, LabelColor, false, false ); // Name
AddHtmlLocalized( 270 - xoffset, 64, 200, 32, 1062213, LabelColor, false, false ); // Type
AddHtmlLocalized( 326 - xoffset, 64, 200, 32, 3000132, LabelColor, false, false ); // Status
AddHtmlLocalized( 429 - xoffset, 64, 200, 32, 1062465, LabelColor, false, false ); // Expires
AddButton( 375 - xoffset, 416, 4017, 4018, 0, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 410 - xoffset, 416, 120, 20, 1011441, LabelColor, false, false ); // EXIT
if(!m_Book.Locked)
AddHtmlLocalized( 26, 64, 50, 32, 1062212, LabelColor, false, false ); // Drop
tableIndex = 0;
if ( page > 0 )
{
AddButton( 75, 416, 4014, 4016, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 110, 416, 150, 20, 1011067, LabelColor, false, false ); // Previous page
}
if ( GetIndexForPage( page + 1 ) < list.Count )
{
AddButton( 225, 416, 4005, 4007, 3, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 260, 416, 150, 20, 1011066, LabelColor, false, false ); // Next page
}
for ( int i = index; i < (index + count) && i >= 0 && i < list.Count; ++i )
{
object obj = list[i];
if ( obj is IXmlQuest )
{
IXmlQuest e = (IXmlQuest)obj;
int y = 96 + (tableIndex++ * 32);
if(!m_Book.Locked)
AddButton( 35, y + 2, 5602, 5606, 1000 + i, GumpButtonType.Reply, 0 ); // drop
AddButton( 60 - xoffset, y + 2, 0xFAB, 0xFAD, 2000 + i, GumpButtonType.Reply, 0 ); // open gump
int color;
if(!e.IsValid)
{
color = 33;
} else
if(e.IsCompleted)
{
color = 67;
} else
{
color = 5;
}
AddLabel( 100 - xoffset, y, color, (string)e.Name );
//AddHtmlLocalized( 315, y, 200, 32, e.IsCompleted ? 1049071 : 1049072, htmlcolor, false, false ); // Completed/Incomplete
AddLabel( 315 - xoffset, y, color, e.IsCompleted ? "Completed" : "In Progress" );
// indicate the expiration time
if(e.IsValid){
// do a little parsing of the expiration string to fit it in the space
string substring = e.ExpirationString;
if(e.ExpirationString.IndexOf("Expires in") >= 0)
{
substring = e.ExpirationString.Substring(11);
}
AddLabel( 400 - xoffset, y, color, (string)substring );
} else
{
AddLabel( 400 - xoffset, y, color, "No longer valid" );
}
if(e.PartyEnabled){
AddLabel( 270 - xoffset, y, color, "Party" );
//AddHtmlLocalized( 250, y, 200, 32, 3000332, htmlcolor, false, false ); // Party
} else {
AddLabel( 270 - xoffset, y, color, "Solo" );
}
}
}
}
}
}

View File

@@ -0,0 +1,702 @@
using System;
using System.Data;
using System.IO;
using System.Collections.Generic;
using System.Globalization;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Gumps;
using Server.Targeting;
using Server.Engines.XmlSpawner2;
/*
** Changelog
**
** 3/25/04
** added party status information
** 3/23/04
** changed bottom border location in the quest status gump for 3dclient compatibility
*/
namespace Server.Gumps
{
public class XmlConfirmDeleteGump : Gump
{
Item m_Item;
Mobile m_From;
public XmlConfirmDeleteGump(Mobile from, Item item) : base ( 0, 0 )
{
m_Item = item;
m_From = from;
Closable = false;
Dragable = true;
AddPage( 0 );
AddBackground( 10, 185, 200, 130, 5054 );
if(item is XmlQuestBook)
{
AddLabel( 20, 190, 33, String.Format("Delete this questbook?") );
AddLabel( 20, 210, 33, String.Format("{0} quest(s) will be lost.", item.TotalItems) );
AddLabel( 20, 230, 53, item.Name );
}
else if(item is IXmlQuest)
{
AddLabel( 20, 210, 33, String.Format("Delete this quest?") );
AddLabel( 20, 230, 53, item.Name );
}
else
{
AddLabel( 20, 210, 33, String.Format("Delete this item?") );
AddLabel( 20, 230, 53, item.Name );
}
AddRadio( 35, 255, 9721, 9724, false, 1 ); // accept/yes radio
AddRadio( 135, 255, 9721, 9724, true, 2 ); // decline/no radio
AddHtmlLocalized(72, 255, 200, 30, 1049016, 0x7fff , false , false ); // Yes
AddHtmlLocalized(172, 255, 200, 30, 1049017, 0x7fff , false , false ); // No
AddButton( 80, 289, 2130, 2129, 3, GumpButtonType.Reply, 0 ); // Okay button
}
public override void OnResponse( NetState state, RelayInfo info )
{
if(info == null || state == null || state.Mobile == null) return;
int radiostate = -1;
if(info.Switches.Length > 0)
{
radiostate = info.Switches[0];
}
switch(info.ButtonID)
{
default:
{
if(radiostate == 1 && m_Item != null )
{ // accept
if(m_Item is IXmlQuest)
{
((IXmlQuest)m_Item).Invalidate();
}
else
if(m_Item is XmlQuestBook)
{
((XmlQuestBook)m_Item).Invalidate();
}
else
{
m_Item.Delete();
}
}
else
if(m_From != null && m_Item != null && !m_Item.Deleted)
{
m_From.AddToBackpack(m_Item);
}
break;
}
}
}
}
public class XmlSimpleGump : Gump
{
public static string Color( string text, string color )
{
return String.Format( "<BASEFONT COLOR=#{0}>{1}</BASEFONT>", color, text );
}
private int m_gumptype;
private object m_invoker;
private BaseXmlSpawner.KeywordTag m_keywordtag;
private XmlGumpCallback m_gumpcallback;
private List<GumpSelection> gumpSelections = new List<GumpSelection>();
private class GumpSelection
{
public string Selection;
public string Response;
public int GumpItemType; // 1=textentry
public GumpSelection(string s, string r)
{
Selection = s;
Response = r;
}
}
void LocalAddHtml(string text, int x, int y, int width, int height, int color, bool background, bool scrollbar)
{
if (text == null) return;
// check for cliloc specification
if (text.StartsWith("#"))
{
int cliloc = 0;
if(int.TryParse(text.Substring(1, text.Length - 1), out cliloc))
AddHtmlLocalized(x, y, width, height, cliloc, color, background, scrollbar);
}
else
{
try
{
string colorstring = String.Format("{0:X}",color);
AddHtml(x, y, width, height, XmlSimpleGump.Color(text, colorstring), background, scrollbar);
}
catch { }
}
}
private string ParseGumpText(string text)
{
string maintext = text;
// format for multiple selection specifications is
// maintext ; selection0 ; response0 ; selection1 ; response1 ....
string [] args = text.Split(';');
// the first arg is the maintext
if(args.Length > 0)
{
maintext = args[0];
// fill the selection and responses with the remaining args
for(int i = 1;i<args.Length;i += 2)
{
GumpSelection s = new GumpSelection("","");
if(i < args.Length) s.Selection = args[i].Trim();
if(i+1 < args.Length) s.Response = args[i+1].Trim();
gumpSelections.Add(s);
}
}
return maintext;
}
public XmlSimpleGump( object invoker, string gumptext, string gumptitle, int gumptype, BaseXmlSpawner.KeywordTag tag, Mobile from) : this( invoker, gumptext, gumptitle, gumptype, tag, from, null)
{
}
public XmlSimpleGump( object invoker, string gumptext, string gumptitle, int gumptype, BaseXmlSpawner.KeywordTag tag, Mobile from, XmlGumpCallback gumpcallback) : base( 0, 0 )
{
string maintext = gumptext;
int nselections = 0;
int height = 400;
int width = 369;
Closable = false;
Dragable = true;
m_gumptype = gumptype;
m_invoker = invoker;
m_keywordtag = tag;
m_gumpcallback = gumpcallback;
AddPage( 0 );
// for the multiple selection gump, parse the gumptext for selections and responses
if(gumptype == 4)
{
maintext = ParseGumpText(gumptext);
nselections = gumpSelections.Count;
height = height + nselections*40;
}
if(gumptype == 5)
{
maintext = ParseGumpText(gumptext);
nselections = gumpSelections.Count;
// the maintext in this case is a width,height specifier so parse it
string [] args = maintext.Split(',');
if(args != null && args.Length>1)
{
int.TryParse(args[0].Trim(), out width);
int.TryParse(args[1].Trim(), out height);
}
}
AddImageTiled( 54, 33, width, height, 2624 );
AddAlphaRegion( 54, 33, width, height );
AddImageTiled( width + 47, 39, 44, height-11, 203 );
AddImageTiled( 58, 39, 29, height - 10, 10460 ); // left hand border
AddImageTiled( width + 43, 37, 31, height - 11, 10460 ); // right hand border
AddImageTiled( 40, 38, 17, height - 9, 9263 ); // leftmost border
//AddImageTiled( 94, 25, width - 27, 15, 10304 ); // top border
AddImageTiled( 40, 25, width + 48, 15, 10304 ); // top border
AddImageTiled( 40, height + 27, width + 46, 16, 10304 ); // bottom border
if(gumptype != 5)
{
AddImage( width + 61, 9, 10441); // dragon borders
AddImage( 6, 25, 10421 );
AddImage( 34, 12, 10420 );
AddImage( -10, height - 86, 10402 );
AddImage( 56, 150, 10411 );
AddImage( 136, 84, 96 ); // divider
AddImage( width + 3, 57, 1417); // quest icons
AddImage( width + 12, 66, 5576);
AddButton( width - 31, height - 8, 2130, 2129, 3, GumpButtonType.Reply, 0 ); // Okay button
}
else
{
AddButton( width + 70, 25, 0x138b, 0x138b, 0, GumpButtonType.Reply, 0 ); // closegump button
}
if(gumptitle != null && gumptitle.Length > 0 && gumptype != 5)
{ // display the title if it is there
AddImage( 156, 126, 2103 ); // bullet
LocalAddHtml(gumptitle, 174, 121, 200, 40, 0x00FF42, false, false);
}
if(gumptype == 0)
{ // simple message gump
LocalAddHtml(maintext, 105, 159, 299, 182, 0xEFEF5A, false, true);
} else
if(gumptype == 1)
{ // Yes/no type gump
AddRadio( 101, height - 45, 9721, 9724, true, 1 ); // accept/yes radio
AddRadio( 101, height - 11, 9721, 9724, false, 2 ); // decline/no radio
AddHtmlLocalized(137, height - 41, 200, 30, 1049016, 0x7fff , false , false ); // Yes
AddHtmlLocalized(137, height - 7, 200, 30, 1049017, 0x7fff , false , false ); // No
LocalAddHtml(maintext, 105, 159, 299, 182, 0xEFEF5A, false, true);
}
else
if(gumptype == 2)
{ // reply type gump
AddImageTiled( 134, height - 7, 159, 23, 0x52 );
AddImageTiled( 135, height - 6, 157, 21, 0xBBC );
AddHtmlLocalized(105, height - 7, 200, 30, 3002006, 0x7fff , false , false ); // Say:
AddTextEntry( 135, height - 7, 150, 21, 0, 99, null );
LocalAddHtml(maintext, 105, 159, 299, 182, 0xEFEF5A, false, true);
}
else
if(gumptype == 3)
{ // Quest type gump
AddImage( 97, 49, 9005 ); // quest ribbon
AddRadio( 101, height - 45, 9721, 9724, true, 1 ); // accept/yes radio
AddRadio( 101, height - 11, 9721, 9724, false, 2 ); // decline/no radio
AddHtmlLocalized( 139, 59, 200, 30, 1046013, 0x7fff, false , false ); // Quest Offer
AddHtmlLocalized(137, height - 41, 200, 30, 1049011, 0x7fff , false , false ); // I accept!
AddHtmlLocalized(137, height - 7, 200, 30, 1049012, 0x7fff , false , false ); // No thanks, I decline.
LocalAddHtml(maintext, 105, 159, 299, 182, 0xEFEF5A, false, true);
}
else
if(gumptype == 4)
{ // multiple selection type gump
// parse the gump text to get the selections and responses
for(int i=0;i < gumpSelections.Count; i++)
{
int y = 360 + i*40;
AddRadio( 101, y, 9721, 9724, i==0 ? true: false, i ); // accept/yes radio
AddHtml( 137, y+4, 250, 40, XmlSimpleGump.Color( gumpSelections[i].Selection, "FFFFFF" ), false, false );
}
LocalAddHtml(maintext, 105, 159, 299, 182, 0xEFEF5A, false, true);
}
else
if(gumptype == 5)
{
// parse the gump text to get the selections and responses
for(int i=0;i < gumpSelections.Count; i++)
{
string selection = gumpSelections[i].Selection;
string response = gumpSelections[i].Response;
int gx = 0;
int gy = 0;
int gwidth = 0;
int gheight = 0;
string label = null;
string [] args = null;
int gumpid = 0;
int color = 0;
if(selection != null)
{
args = selection.Split(',');
}
// process the gumpitem specifications
if(args.Length > 1)
{
for(int j=0;j<args.Length;j++)
{
args[j] = args[j].Trim();
}
if(args[0].ToLower() == "button")
{
// syntax is button,gumpid,x,y
if(args.Length > 3)
{
if(args[1].StartsWith("0x"))
{
int.TryParse(args[1].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out gumpid);
}
else
{
int.TryParse(args[1], out gumpid);
}
int.TryParse(args[2], out gx);
int.TryParse(args[3], out gy);
int buttonid = 1000 + i;
// add the button
AddButton( gx, gy, gumpid, gumpid, buttonid, GumpButtonType.Reply, 0 );
}
}
else
if(args[0].ToLower() == "label")
{
// syntax is label,x,y,label[,color]
if(args.Length > 3)
{
int.TryParse(args[1], out gx);
int.TryParse(args[2], out gy);
label = args[3];
}
// set the default label color
color = 0x384;
if(args.Length > 4)
{
int.TryParse(args[4], out color);
}
// add the label
AddLabel( gx, gy, color, label );
}
else
if(args[0].ToLower() == "html")
{
// reparse the specification to allow for the possibility of commas in the html text
args = selection.Split(new char[] {','},6);
color = 0xEFEF5A;
// syntax is html,x,y,width,height,text[,hue] * hue has to be in HEX format, ex: 0xFF00AA (lenght of 8 mandatory!)
if(args.Length > 5)
{
int.TryParse(args[1].Trim(), out gx);
int.TryParse(args[2].Trim(), out gy);
int.TryParse(args[3].Trim(), out gwidth);
int.TryParse(args[4].Trim(), out gheight);
if(args.Length>6 && args[5].StartsWith("0x") && args[5].Trim().Length==8)
{
if(!int.TryParse(args[5].Trim().Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out color))
color=0xEFEF5A;
label = args[6];
}
else
label = args[5];
}
// add the html area
//AddHtml( gx, gy, gwidth, gheight, label, false, true );
LocalAddHtml(label, gx, gy, gwidth, gheight, color, false, true);
}
else
if(args[0].ToLower() == "textentry")
{
gumpSelections[i].GumpItemType = 1;
// syntax is textentry,x,y,width,height[,textcolor][,text]
if(args.Length > 4)
{
int.TryParse(args[1].Trim(), out gx);
int.TryParse(args[2].Trim(), out gy);
int.TryParse(args[3].Trim(), out gwidth);
int.TryParse(args[4].Trim(), out gheight);
}
if(args.Length > 5)
{
label = args[5];
}
// set the default textentry color
color = 0x384;
if(args.Length > 6)
{
int.TryParse(args[6], out color);
}
AddTextEntry( gx, gy, gwidth, gheight, color, i, label );
}
else
if(args[0].ToLower() == "radio")
{
int gumpid1 = 0;
int gumpid2 = 0;
// syntax is radio,gumpid1,gumpid2,x,y[,initialstate]
if(args.Length > 4)
{
int.TryParse(args[1].Trim(), out gumpid1);
int.TryParse(args[2].Trim(), out gumpid2);
int.TryParse(args[3].Trim(), out gx);
int.TryParse(args[4].Trim(), out gy);
}
bool initial = false;
if(args.Length > 5)
{
bool.TryParse(args[5], out initial);
}
AddRadio( gx, gy, gumpid1, gumpid2, initial, i);
}
else
if(args[0].ToLower() == "image")
{
// syntax is image,gumpid,x,y[,hue]
if(args.Length > 3)
{
if(args[1].StartsWith("0x"))
{
int.TryParse(args[1].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out gumpid);
}
else
{
int.TryParse(args[1], out gumpid);
}
int.TryParse(args[2], out gx);
int.TryParse(args[3], out gy);
if(args.Length > 4)
{
int.TryParse(args[4], out color);
}
// add the image
AddImage( gx, gy, gumpid, color );
}
}
else
if(args[0].ToLower() == "imagetiled")
{
// syntax is imagetiled,gumpid,x,y,width,height
if(args.Length > 5)
{
if(args[1].StartsWith("0x"))
{
int.TryParse(args[1].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out gumpid);
}
else
{
int.TryParse(args[1], out gumpid);
}
int.TryParse(args[2], out gx);
int.TryParse(args[3], out gy);
int.TryParse(args[4], out gwidth);
int.TryParse(args[5], out gheight);
// add the image
AddImageTiled( gx, gy, gwidth, gheight, gumpid );
}
}
else
if(args[0].ToLower() == "item")
{
// syntax is item,itemid,x,y[,hue]
if(args.Length > 3)
{
if(args[1].StartsWith("0x"))
{
int.TryParse(args[1].Substring(2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out gumpid);
}
else
{
int.TryParse(args[1], out gumpid);
}
int.TryParse(args[2], out gx);
int.TryParse(args[3], out gy);
if(args.Length > 4)
{
int.TryParse(args[4], out color);
}
// add the image
AddItem( gx, gy, gumpid, color );
}
}
}
}
}
}
public override void OnResponse( Server.Network.NetState state, RelayInfo info )
{
if(info == null || state == null || state.Mobile == null) return;
Mobile from = state.Mobile;
if(m_gumpcallback != null)
{
if(info.ButtonID == 0)
{
m_gumpcallback( from, m_invoker, String.Empty);
}
else
{
switch (m_gumptype)
{
case 0: // simple acknowledgement gump
m_gumpcallback(from, m_invoker, "done");
break;
case 1: // yes/no gump
if (info.Switches != null && info.Switches.Length > 0)
{
if (info.Switches[0] == 1)
{
m_gumpcallback(from, m_invoker, "yes");
}
else
{
m_gumpcallback(from, m_invoker, "no");
}
}
break;
case 2: // text entry gump
TextRelay entry = info.GetTextEntry(99);
if (entry != null && entry.Text.Length > 0)
{
// return the response string
m_gumpcallback(from, m_invoker, entry.Text);
}
break;
case 3: // accept/decline gump
if (info.Switches != null && info.Switches.Length > 0)
{
if (info.Switches[0] == 1)
{
from.SendLocalizedMessage(1049019); // You have accepted the Quest.
m_gumpcallback(from, m_invoker, "accept");
}
else
{
from.SendLocalizedMessage(1049018); // You have declined the Quest.
m_gumpcallback(from, m_invoker, "decline");
}
}
break;
case 4: // multiple option gump
if (info.Switches != null && info.Switches.Length > 0)
{
int select = info.Switches[0];
if (select >= 0 && select < gumpSelections.Count)
{
// return the response string for that selection
m_gumpcallback(from, m_invoker, gumpSelections[select].Response);
}
}
break;
case 5:
string buttonresponse = String.Empty;
string radioresponse = String.Empty;
string textresponse = String.Empty;
if (info.ButtonID >= 1000)
{
int select = info.ButtonID - 1000;
// get the gump response associated with the button
if (select >= 0 && select < gumpSelections.Count)
{
// return the response string for that selection
buttonresponse = gumpSelections[select].Response;
}
}
if (info.Switches != null && info.Switches.Length > 0)
{
int radiostate = info.Switches[0];
if (radiostate >= 0 && radiostate < gumpSelections.Count)
{
radioresponse = gumpSelections[radiostate].Response;
}
}
// check for any textentries
for (int j = 0; j < gumpSelections.Count; j++)
{
if (gumpSelections[j].GumpItemType == 1)
{
try
{
TextRelay te = info.GetTextEntry(j);
if (te != null && te.Text.Length > 0)
{
textresponse += te.Text + " ";
}
}
catch { }
}
}
// build the composite reponse string
string responsestring = null;
if (buttonresponse != null && buttonresponse.Length > 0)
{
responsestring = buttonresponse;
}
if (radioresponse != null && radioresponse.Length > 0)
{
responsestring += " " + radioresponse;
}
if (textresponse != null && textresponse.Length > 0)
{
responsestring += " " + textresponse;
}
m_gumpcallback(from, m_invoker, responsestring);
break;
}
}
}
// get rid of any temporary gump keyword tokens
if(m_invoker is XmlSpawner)
((XmlSpawner)m_invoker).DeleteTag(m_keywordtag);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,690 @@
using System;
using System.Collections.Generic;
using Server;
using Server.Items;
using Server.Network;
using Server.Mobiles;
using Server.Prompts;
using Server.Targeting;
using Server.Engines.XmlSpawner2;
namespace Server.Gumps
{
public class XmlQuestStatusGump : Gump
{
public static string Color(string text, string color)
{
return String.Format("<BASEFONT COLOR=#{0}>{1}</BASEFONT>", color, text);
}
public void DisplayQuestStatus(int x, int y, string objectivestr, string statestr, bool status, string descriptionstr)
{
if (objectivestr != null && objectivestr.Length > 0)
{
// look for special keywords
string[] arglist = BaseXmlSpawner.ParseString(objectivestr, 5, ",");
int targetcount = 1;
bool foundkill = false;
bool foundcollect = false;
bool foundgive = false;
bool foundescort = false;
string name = null;
string mobname = null;
string type = null;
string status_str;
string text = null;
string typestr;
bool checkprop;
if (arglist.Length > 0)
switch (arglist[0])
{
case "GIVE":
// format for the objective string will be GIVE,mobname,itemtype[,count][,proptest]
if (arglist.Length > 2)
{
mobname = arglist[1];
//name = arglist[2];
type = arglist[2];
}
XmlQuest.CheckArgList(arglist, 3, null, out typestr, out targetcount, out checkprop, out status_str);
foundgive = true;
break;
case "GIVENAMED":
// format for the objective string will be GIVENAMED,mobname,itemname[,type][,count][,proptest]
if (arglist.Length > 2)
{
mobname = arglist[1];
name = arglist[2];
}
XmlQuest.CheckArgList(arglist, 3, null, out typestr, out targetcount, out checkprop, out status_str);
if (typestr != null) type = typestr;
foundgive = true;
break;
case "KILL":
// format for the objective string will be KILL,mobtype[,count][,proptest]
if (arglist.Length > 1)
{
//name = arglist[1];
type = arglist[1];
}
XmlQuest.CheckArgList(arglist, 2, null, out typestr, out targetcount, out checkprop, out status_str);
foundkill = true;
break;
case "KILLNAMED":
// format for the objective string KILLNAMED,mobname[,type][,count][,proptest]
if (arglist.Length > 1)
{
name = arglist[1];
}
XmlQuest.CheckArgList(arglist, 2, null, out typestr, out targetcount, out checkprop, out status_str);
if (typestr != null) type = typestr;
foundkill = true;
break;
case "COLLECT":
// format for the objective string will be COLLECT,itemtype[,count][,proptest]
if (arglist.Length > 1)
{
//name = arglist[1];
type = arglist[1];
}
XmlQuest.CheckArgList(arglist, 2, null, out typestr, out targetcount, out checkprop, out status_str);
foundcollect = true;
break;
case "COLLECTNAMED":
// format for the objective string will be COLLECTNAMED,itemname[,itemtype][,count][,proptest]
if (arglist.Length > 1)
{
name = arglist[1];
}
XmlQuest.CheckArgList(arglist, 2, null, out typestr, out targetcount, out checkprop, out status_str);
if (typestr != null) type = typestr;
foundcollect = true;
break;
case "ESCORT":
// format for the objective string will be ESCORT,mobname[,proptest]
if (arglist.Length > 1)
{
name = arglist[1];
}
foundescort = true;
break;
}
if (foundkill)
{
// get the current kill status
int killed = 0;
try
{
killed = int.Parse(statestr);
}
catch { }
int remaining = targetcount - killed;
if (remaining < 0) remaining = 0;
// report the kill task objective status
if (descriptionstr != null)
text = String.Format("{0} ({1} left)", descriptionstr, remaining);
else
{
if (name != null)
{
if (type == null) type = "mob";
text = String.Format("Kill {0} {1}(s) named {2} ({3} left)", targetcount, type, name, remaining);
}
else
text = String.Format("Kill {0} {1}(s) ({2} left)", targetcount, type, remaining);
}
}
else
if (foundescort)
{
// get the current escort status
int escorted = 0;
try
{
escorted = int.Parse(statestr);
}
catch { }
int remaining = targetcount - escorted;
if (remaining < 0) remaining = 0;
// report the escort task objective status
if (descriptionstr != null)
text = descriptionstr;
else
text = String.Format("Escort {0}", name);
}
else
if (foundcollect)
{
// get the current collection status
int collected = 0;
try
{
collected = int.Parse(statestr);
}
catch { }
int remaining = targetcount - collected;
if (remaining < 0) remaining = 0;
// report the collect task objective status
if (descriptionstr != null)
text = String.Format("{0} ({1} left)", descriptionstr, remaining);
else
{
if (name != null)
{
if (type == null) type = "mob";
text = String.Format("Collect {0} {1}(s) named {2} ({3} left)", targetcount, type, name, remaining);
}
else
text = String.Format("Collect {0} {1}(s) ({2} left)", targetcount, type, remaining);
}
}
else
if (foundgive)
{
// get the current give status
int collected = 0;
try
{
collected = int.Parse(statestr);
}
catch { }
int remaining = targetcount - collected;
if (remaining < 0) remaining = 0;
// report the collect task objective status
if (descriptionstr != null)
text = String.Format("{0} ({1} left)", descriptionstr, remaining);
else
{
if (name != null)
{
if (type == null) type = "item";
text = String.Format("Give {0} {1}(s) named {2} to {3} ({4} left)", targetcount, type, name, mobname, remaining);
}
else
text = String.Format("Give {0} {1}(s) to {2} ({3} left)", targetcount, type, mobname, remaining);
}
}
else
{
// just report the objectivestring
text = objectivestr;
}
AddHtml(x, y, 223, 35, XmlSimpleGump.Color(text, "EFEF5A"), false, false);
if (status)
{
AddImage(x - 20, y + 3, 0x939); // bullet
AddHtmlLocalized(x + 222, y, 225, 37, 1046033, 0xff42, false, false); // Complete
}
else
{
AddImage(x - 20, y + 3, 0x938); // bullet
AddHtmlLocalized(x + 222, y, 225, 37, 1046034, 0x7fff, false, false); // Incomplete
}
}
}
private IXmlQuest m_questitem;
private string m_gumptitle;
private int m_X;
private int m_Y;
private bool m_solid;
private int m_screen;
public XmlQuestStatusGump(IXmlQuest questitem, string gumptitle)
: this(questitem, gumptitle, 0, 0, false, 0)
{
}
public XmlQuestStatusGump(IXmlQuest questitem, string gumptitle, int X, int Y, bool solid)
: this(questitem, gumptitle, X, Y, solid, 0)
{
}
public XmlQuestStatusGump(IXmlQuest questitem, string gumptitle, int X, int Y, bool solid, int screen)
: base(X, Y)
{
Closable = true;
Dragable = true;
m_X = X;
m_Y = Y;
m_solid = solid;
m_questitem = questitem;
m_gumptitle = gumptitle;
m_screen = screen;
AddPage(0);
if (!solid)
{
AddImageTiled(54, 33, 369, 400, 2624);
AddAlphaRegion(54, 33, 369, 400);
}
else
{
AddBackground(54, 33, 369, 400, 5054);
}
AddImageTiled(416, 39, 44, 389, 203);
// AddButton( 338, 392, 2130, 2129, 3, GumpButtonType.Reply, 0 ); // Okay button
AddHtmlLocalized(139, 59, 200, 30, 1046026, 0x7fff, false, false); // Quest Log
AddImage(97, 49, 9005); // quest ribbon
AddImageTiled(58, 39, 29, 390, 10460); // left hand border
AddImageTiled(412, 37, 31, 389, 10460); // right hand border
AddImage(430, 9, 10441);
AddImageTiled(40, 38, 17, 391, 9263);
AddImage(6, 25, 10421);
AddImage(34, 12, 10420);
AddImageTiled(94, 25, 342, 15, 10304); // top border
AddImageTiled(40, 414, 415, 16, 10304); // bottom border
AddImage(-10, 314, 10402);
AddImage(56, 150, 10411);
AddImage(136, 84, 96);
AddImage(372, 57, 1417);
AddImage(381, 66, 5576);
// add the status and journal tabs
AddImageTiled(90, 34, 322, 5, 0x145E); // top border
int tab1 = 0x138F;
int tab2 = 0x138E;
if (screen == 1)
{
tab1 = 0x138E;
tab2 = 0x138F;
}
AddButton(100, 18, tab1, tab2, 900, GumpButtonType.Reply, 0);
AddLabel(115, 17, 0, "Status");
AddButton(189, 18, tab2, tab1, 901, GumpButtonType.Reply, 0);
AddLabel(205, 17, 0, "Journal");
if (screen == 1)
{
// display the journal
if (questitem.Journal != null && questitem.Journal.Count > 0)
{
string journaltext = null;
for (int i = 0; i < questitem.Journal.Count; i++)
{
journaltext += "<u>";
journaltext += questitem.Journal[i].EntryID;
journaltext += ":</u><br>";
journaltext += questitem.Journal[i].EntryText;
journaltext += "<br><br>";
}
AddHtml(100, 90, 270, 300, journaltext, true, true);
}
// add the add journal entry button
AddButton(300, 49, 0x99C, 0x99D, 952, GumpButtonType.Reply, 0);
//AddButton(300, 49, 0x159E, 0x159D, 952, GumpButtonType.Reply, 0);
}
else
{
if (gumptitle != null && gumptitle.Length > 0)
{ // display the title if it is there
AddImage(146, 91, 2103); // bullet
AddHtml(164, 86, 200, 30, XmlSimpleGump.Color(gumptitle, "00FF42"), false, false);
}
if (questitem.NoteString != null && questitem.NoteString.Length > 0)
{ // display the note string if it is there
AddHtml(100, 106, 270, 80, questitem.NoteString, true, true);
}
DisplayQuestStatus(130, 192, questitem.Objective1, questitem.State1, questitem.Completed1, questitem.Description1);
DisplayQuestStatus(130, 224, questitem.Objective2, questitem.State2, questitem.Completed2, questitem.Description2);
DisplayQuestStatus(130, 256, questitem.Objective3, questitem.State3, questitem.Completed3, questitem.Description3);
DisplayQuestStatus(130, 288, questitem.Objective4, questitem.State4, questitem.Completed4, questitem.Description4);
DisplayQuestStatus(130, 320, questitem.Objective5, questitem.State5, questitem.Completed5, questitem.Description5);
//if(questitem.HasCollect){
AddButton(100, 350, 0x2A4E, 0x2A3A, 700, GumpButtonType.Reply, 0);
AddLabel(135, 356, 0x384, "Collect");
//}
if ((questitem.RewardItem != null && !questitem.RewardItem.Deleted))
{
m_questitem.CheckRewardItem();
if (questitem.RewardItem.Amount > 1)
{
AddLabel(230, 356, 55, String.Format("Reward: {0} ({1})", questitem.RewardItem.GetType().Name,
questitem.RewardItem.Amount));
AddLabel(230, 373, 55, String.Format("Weight: {0}", questitem.RewardItem.Weight * questitem.RewardItem.Amount));
}
else
if (questitem.RewardItem is Container)
{
AddLabel(230, 356, 55, String.Format("Reward: {0} ({1} items)", questitem.RewardItem.GetType().Name,
questitem.RewardItem.TotalItems));
AddLabel(230, 373, 55, String.Format("Weight: {0}", questitem.RewardItem.TotalWeight + questitem.RewardItem.Weight));
}
else
{
AddLabel(230, 356, 55, String.Format("Reward: {0}", questitem.RewardItem.GetType().Name));
AddLabel(230, 373, 55, String.Format("Weight: {0}", questitem.RewardItem.Weight));
}
AddImageTiled(330, 373, 81, 40, 200);
AddItem(340, 376, questitem.RewardItem.ItemID);
}
if (questitem.RewardAttachment != null && !questitem.RewardAttachment.Deleted)
{
AddLabel(230, 339, 55, String.Format("Bonus: {0}", questitem.RewardAttachment.GetType().Name));
}
if ((questitem.RewardItem != null && !questitem.RewardItem.Deleted) || (questitem.RewardAttachment != null && !questitem.RewardAttachment.Deleted))
{
if (questitem.CanSeeReward)
{
AddButton(400, 380, 2103, 2103, 800, GumpButtonType.Reply, 0);
}
}
// indicate any status info
XmlQuest.VerifyObjectives(questitem);
if (questitem.Status != null)
{
AddLabel(100, 392, 33, questitem.Status);
}
else
// indicate the expiration time
if (questitem.IsValid)
{
//AddHtmlLocalized(150, 400, 50, 37, 1046033, 0xf0000 , false , false ); // Expires
AddHtml(130, 392, 200, 37, XmlSimpleGump.Color(questitem.ExpirationString, "00FF42"), false, false);
}
else
if (questitem.AlreadyDone)
{
if (!questitem.Repeatable)
{
AddLabel(100, 392, 33, "Already done - cannot be repeated");
}
else
{
List<XmlAttachment> a = XmlAttach.FindAttachments(questitem.Owner, typeof(XmlQuestAttachment), questitem.Name);
if (a != null && a.Count > 0)
{
AddLabel(100, 392, 33, String.Format("Repeatable in {0}", a[0].Expiration));
}
else
{
AddLabel(150, 392, 33, "Already done - ???");
}
}
}
else
{
//AddHtml( 150, 384, 200, 37, XmlSimpleGump.Color( "No longer valid", "00FF42" ), false, false );
AddLabel(150, 392, 33, "No longer valid");
}
if (XmlQuest.QuestPointsEnabled)
{
AddHtml(250, 40, 200, 30, XmlSimpleGump.Color(String.Format("Difficulty Level {0}", questitem.Difficulty), "00FF42"), false, false);
}
if (questitem.PartyEnabled)
{
AddHtml(250, 55, 200, 30, XmlSimpleGump.Color("Party Quest", "00FF42"), false, false);
if (questitem.PartyRange >= 0)
{
AddHtml(250, 70, 200, 30, XmlSimpleGump.Color(String.Format("Party Range {0}", questitem.PartyRange), "00FF42"), false, false);
}
else
{
AddHtml(250, 70, 200, 30, XmlSimpleGump.Color("No Range Limit", "00FF42"), false, false);
}
}
else
{
AddHtml(250, 55, 200, 30, XmlSimpleGump.Color("Solo Quest", "00FF42"), false, false);
}
}
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (info == null || state == null || state.Mobile == null || state.Mobile.Deleted || m_questitem == null || m_questitem.Deleted)
return;
switch (info.ButtonID)
{
case 700:
state.Mobile.Target = new XmlQuest.GetCollectTarget(m_questitem);
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, m_screen));
break;
case 800:
if(!m_questitem.CanSeeReward) return;
if (m_questitem.RewardItem != null || m_questitem.RewardAttachment != null)
{
// open a new status gump
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, m_screen));
}
// display the reward item
if (m_questitem.RewardItem != null)
{
// show the contents of the xmlquest pack
if (m_questitem.Pack != null)
m_questitem.Pack.DisplayTo(state.Mobile);
}
// identify the reward attachment
if (m_questitem.RewardAttachment != null)
{
//state.Mobile.SendMessage("{0}",m_questitem.RewardAttachment.OnIdentify(state.Mobile));
state.Mobile.CloseGump(typeof(DisplayAttachmentGump));
state.Mobile.SendGump(new DisplayAttachmentGump(state.Mobile, m_questitem.RewardAttachment.OnIdentify(state.Mobile)));
}
break;
case 900:
// open a new status gump with status display
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, 0));
break;
case 901:
// open a new status gump with journal display
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, 1));
break;
case 952:
// open a new status gump with journal display
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, 1));
// and open the journal entry editing gump
// only allow this to be used if the questholder is theirs
if (m_questitem.Owner == state.Mobile)
{
state.Mobile.SendGump(new JournalEntryGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid));
}
break;
}
}
public class JournalEntryGump : Gump
{
private IXmlQuest m_questitem;
private string m_gumptitle;
private int m_X, m_Y;
private bool m_solid;
public JournalEntryGump(IXmlQuest questitem, string gumptitle, int X, int Y, bool solid)
: base(X, Y)
{
if (questitem == null || questitem.Deleted)
return;
m_questitem = questitem;
m_gumptitle = gumptitle;
m_X = X;
m_Y = Y;
m_solid = solid;
AddPage(0);
//AddBackground(0, 0, 260, 354, 5054);
//AddAlphaRegion(20, 0, 220, 354);
AddImage(0, 0, 0x24AE); // left top scroll
AddImage(114, 0, 0x24AF); // middle top scroll
AddImage(170, 0, 0x24B0); // right top scroll
AddImageTiled(0, 140, 114, 100, 0x24B1); // left middle scroll
AddImageTiled(114, 140, 114, 100, 0x24B2); // middle middle scroll
AddImageTiled(170, 140, 114, 100, 0x24B3); // right middle scroll
AddImage(0, 210, 0x24B4); // left bottom scroll
AddImage(114, 210, 0x24B5); // middle bottom scroll
AddImage(170, 210, 0x24B6); // right bottom scroll
//AddImageTiled(23, 40, 214, 290, 0x52);
//AddImageTiled(24, 41, 213, 281, 0xBBC);
// OK button
AddButton(25, 327, 0xFB7, 0xFB9, 1, GumpButtonType.Reply, 0);
// Close button
AddButton(230, 327, 0xFB1, 0xFB3, 0, GumpButtonType.Reply, 0);
// Edit button
//AddButton(100, 325, 0xEF, 0xEE, 2, GumpButtonType.Reply, 0);
string str = null;
int entrynumber = 0;
if (questitem.Journal != null && questitem.Journal.Count > 0)
{
entrynumber = questitem.Journal.Count;
}
string m_entryid = "Personal entry #" + entrynumber;
// entryid text entry area
//AddImageTiled(23, 0, 214, 23, 0x52);
//AddImageTiled(24, 1, 213, 21, 0xBBC);
AddTextEntry(35, 5, 200, 21, 0, 1, m_entryid);
// main text entry area
AddTextEntry(35, 40, 200, 271, 0, 0, str);
// editing text entry areas
// background for text entry area
/*
AddImageTiled(23, 275, 214, 23, 0x52);
AddImageTiled(24, 276, 213, 21, 0xBBC);
AddImageTiled(23, 300, 214, 23, 0x52);
AddImageTiled(24, 301, 213, 21, 0xBBC);
AddTextEntry(35, 275, 200, 21, 0, 1, null);
AddTextEntry(35, 300, 200, 21, 0, 2, null);
*/
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (info == null || state == null || state.Mobile == null) return;
if (m_questitem == null || m_questitem.Deleted)
return;
bool update_entry = false;
//bool edit_entry = false;
switch (info.ButtonID)
{
case 0: // Close
{
update_entry = false;
break;
}
case 1: // Okay
{
update_entry = true;
break;
}
case 2: // Edit
{
//edit_entry = true;
break;
}
default:
update_entry = true;
break;
}
if (update_entry)
{
string entrytext = null;
string entryid = null;
TextRelay entry = info.GetTextEntry(0);
if (entry != null)
{
entrytext = entry.Text;
}
entry = info.GetTextEntry(1);
if (entry != null)
{
entryid = entry.Text;
}
m_questitem.AddJournalEntry = entryid + ":" + entrytext;
}
// open a new journal gump
state.Mobile.CloseGump(typeof(XmlQuestStatusGump));
state.Mobile.SendGump(new XmlQuestStatusGump(m_questitem, m_gumptitle, m_X, m_Y, m_solid, 1));
}
}
private class DisplayAttachmentGump : Gump
{
public DisplayAttachmentGump(Mobile from, string text)
: base(0, 0)
{
// prepare the page
AddPage(0);
AddBackground(0, 0, 400, 150, 5054);
AddAlphaRegion(0, 0, 400, 150);
AddLabel(20, 2, 55, "Quest Attachment Description");
AddHtml(20, 20, 360, 110, text, true, true);
}
}
}
}

View File

@@ -0,0 +1,749 @@
#define FACTIONS
using System;
using System.IO;
using System.Xml;
using Server;
using Server.Items;
using Server.Network;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Targeting;
using Server.Gumps;
using System.Text;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Engines.XmlSpawner2
{
public class XmlQuestLeaders
{
private static TimeSpan m_QuestLeaderboardSaveInterval = TimeSpan.FromMinutes(15); // default time interval between quest leaderboard saves
private static string m_QuestLeaderboardSaveDirectory = "Leaderboard"; // default directory for saving quest leaderboard xml information
private static int m_QuestLeaderboardSaveRanks = 20; // number of ranked players to save to the quest leaderboard. 0 means save all players.
private static QuestLeaderboardTimer m_QuestLeaderboardTimer;
private static string m_QuestLeaderboardFile;
private static List<XmlQuestLeaders.QuestRankEntry> QuestRankList = new List<XmlQuestLeaders.QuestRankEntry>();
private static bool needsupdate = true;
public class QuestRankEntry : IComparable<XmlQuestLeaders.QuestRankEntry>
{
public Mobile Quester;
public int Rank;
public XmlQuestPoints QuestPointsAttachment;
public QuestRankEntry(Mobile m, XmlQuestPoints attachment)
{
Quester = m;
QuestPointsAttachment = attachment;
}
public int CompareTo( QuestRankEntry p )
{
if(p.QuestPointsAttachment == null || QuestPointsAttachment == null) return 0;
// break points ties with quests completed (more quests means higher rank)
if(p.QuestPointsAttachment.Points - QuestPointsAttachment.Points == 0)
{
// if kills are the same then compare previous rank
if(p.QuestPointsAttachment.QuestsCompleted - QuestPointsAttachment.QuestsCompleted == 0)
{
return p.QuestPointsAttachment.Rank - QuestPointsAttachment.Rank;
}
return p.QuestPointsAttachment.QuestsCompleted - QuestPointsAttachment.QuestsCompleted;
}
return p.QuestPointsAttachment.Points - QuestPointsAttachment.Points;
}
}
private static void RefreshQuestRankList()
{
if(needsupdate && QuestRankList != null)
{
QuestRankList.Sort();
int rank = 0;
//int prevpoints = 0;
for(int i= 0; i<QuestRankList.Count;i++)
{
QuestRankEntry p = QuestRankList[i];
// bump the rank for every change in point level
// this means that people with the same points score will have the same rank
/*
if(p.QuestPointsAttachment.Points != prevpoints)
{
rank++;
}
prevpoints = p.QuestPointsAttachment.Points;
*/
// bump the rank for every successive player in the list. Players with the same points total will be
// ordered by quests completed
rank++;
p.Rank = rank;
}
needsupdate = false;
}
}
public static int GetQuestRanking(Mobile m)
{
if(QuestRankList == null || m == null) return 0;
RefreshQuestRankList();
// go through the sorted list and calculate rank
for(int i= 0; i<QuestRankList.Count;i++)
{
QuestRankEntry p = QuestRankList[i];
// found the person?
if(p.Quester == m)
{
return p.Rank;
}
}
// rank 0 means unranked
return 0;
}
public static void UpdateQuestRanking(Mobile m, XmlQuestPoints attachment)
{
if(QuestRankList == null) QuestRankList = new List<XmlQuestLeaders.QuestRankEntry>();
// flag the rank list for updating on the next attempt to retrieve a rank
needsupdate = true;
bool found = false;
// rank the entries
for(int i= 0; i<QuestRankList.Count;i++)
{
QuestRankEntry p = QuestRankList[i];
// found a match
if(p != null && p.Quester == m)
{
// update the entry with the new points value
p.QuestPointsAttachment = attachment;
found = true;
break;
}
}
// a new entry so add it
if(!found)
{
QuestRankList.Add(new QuestRankEntry(m, attachment));
}
}
public static void Initialize()
{
CommandSystem.Register( "QuestLeaderboardSave", AccessLevel.Administrator, new CommandEventHandler( QuestLeaderboardSave_OnCommand ) );
CommandSystem.Register( "QuestRanking", AccessLevel.Player, new CommandEventHandler( QuestRanking_OnCommand ) );
}
[Usage( "QuestRanking" )]
[Description( "Displays the top players in quest points" )]
public static void QuestRanking_OnCommand( CommandEventArgs e )
{
if(e == null || e.Mobile == null) return;
// if this player has an XmlQuestPoints attachment, find it
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(e.Mobile,typeof(XmlQuestPoints));
e.Mobile.CloseGump(typeof(TopQuestPlayersGump));
e.Mobile.SendGump(new TopQuestPlayersGump(p));
}
public static void WriteQuestLeaderboardXml(string filename, int nranks)
{
string dirname = Path.Combine( m_QuestLeaderboardSaveDirectory, filename );
StreamWriter sw = new StreamWriter( dirname );
XmlTextWriter xf = new XmlTextWriter( sw );
if(xf == null)
{
Console.WriteLine("Error: unable to save XML quest leaderboard to {0}", dirname);
return;
}
xf.Formatting = Formatting.Indented;
xf.WriteStartDocument( true );
xf.WriteStartElement( "QuestLeaderboard" );
if(nranks > 0)
xf.WriteAttributeString( "nentries", nranks.ToString() );
else
xf.WriteAttributeString( "nentries", QuestRankList.Count.ToString() );
// go through the sorted list and display the top ranked players
for(int i= 0; i<QuestRankList.Count;i++)
{
if(nranks > 0 && i >= nranks) break;
QuestRankEntry r = QuestRankList[i];
XmlQuestPoints a = r.QuestPointsAttachment;
if(r.Quester != null && !r.Quester.Deleted && r.Rank > 0 && a != null && !a.Deleted)
{
string guildname = null;
if(r.Quester.Guild != null)
guildname = r.Quester.Guild.Abbreviation;
#if(FACTIONS)
string factionname = null;
if(r.Quester is PlayerMobile && ((PlayerMobile)r.Quester).FactionPlayerState != null)
factionname = ((PlayerMobile)r.Quester).FactionPlayerState.Faction.ToString();
#endif
// check for any ranking change and update rank date
if(r.Rank != a.Rank)
{
a.WhenRanked = DateTime.UtcNow;
if(a.Rank > 0)
a.DeltaRank = a.Rank - r.Rank;
a.Rank = r.Rank;
}
TimeSpan timeranked = DateTime.UtcNow - a.WhenRanked;
// write out the entry information
xf.WriteStartElement( "Entry" );
xf.WriteAttributeString( "number", i.ToString() );
xf.WriteStartElement( "Player" );
xf.WriteString( r.Quester.Name );
xf.WriteEndElement();
xf.WriteStartElement( "Guild" );
xf.WriteString( guildname );
xf.WriteEndElement();
#if(FACTIONS)
xf.WriteStartElement( "Faction" );
xf.WriteString( factionname );
xf.WriteEndElement();
#endif
xf.WriteStartElement( "Points" );
xf.WriteString( a.Points.ToString() );
xf.WriteEndElement();
string quests = "???";
try
{
quests = a.QuestsCompleted.ToString();
}
catch{}
xf.WriteStartElement( "Quests" );
xf.WriteString( quests );
xf.WriteEndElement();
xf.WriteStartElement( "Rank" );
xf.WriteString( a.Rank.ToString() );
xf.WriteEndElement();
xf.WriteStartElement( "Change" );
xf.WriteString( a.DeltaRank.ToString() );
xf.WriteEndElement();
xf.WriteStartElement( "Duration" );
xf.WriteString( timeranked.ToString() );
xf.WriteEndElement();
// end the entry
xf.WriteEndElement();
}
}
xf.WriteEndElement();
xf.Close();
}
public static void WriteQuestLeaderboardHtml(string filename, int nranks)
{
string dirname = Path.Combine( m_QuestLeaderboardSaveDirectory, filename );
StreamWriter sw = new StreamWriter( dirname );
if(sw == null)
{
Console.WriteLine("Error: unable to save HTML quest leaderboard to {0}", dirname);
return;
}
sw.WriteLine("<TABLE border=\"1\" summary=\"This table gives quest leaderboard stats\"> ");
sw.WriteLine( "<CAPTION><B>Quest Leaderboard</B></CAPTION>");
#if(FACTIONS)
sw.WriteLine( "<TR><TH><TH>Player Name<TH>Guild<TH>Faction<TH>Points<TH>Quests<TH>Rank<TH>Change<TH>Time at current rank");
#else
sw.WriteLine( "<TR><TH><TH>Player Name<TH>Guild<TH>Points<TH>Quests<TH>Rank<TH>Change<TH>Time at current rank");
#endif
// go through the sorted list and display the top ranked players
for(int i= 0; i<QuestRankList.Count;i++)
{
if(nranks > 0 && i >= nranks) break;
QuestRankEntry r = QuestRankList[i];
XmlQuestPoints a = r.QuestPointsAttachment;
if(r.Quester != null && !r.Quester.Deleted && r.Rank > 0 && a != null && !a.Deleted)
{
string guildname = null;
if(r.Quester.Guild != null)
guildname = r.Quester.Guild.Abbreviation;
#if(FACTIONS)
string factionname = null;
if(r.Quester is PlayerMobile && ((PlayerMobile)r.Quester).FactionPlayerState != null)
factionname = ((PlayerMobile)r.Quester).FactionPlayerState.Faction.ToString();
#endif
// check for any ranking change and update rank date
if(r.Rank != a.Rank)
{
a.WhenRanked = DateTime.UtcNow;
if(a.Rank > 0)
a.DeltaRank = a.Rank - r.Rank;
a.Rank = r.Rank;
}
TimeSpan timeranked = DateTime.UtcNow - a.WhenRanked;
string quests = "???";
try
{
quests = a.QuestsCompleted.ToString();
}
catch{}
#if(FACTIONS)
// write out the entry information
sw.WriteLine( "<TR><TH><TD>{0}<TD>{1}<TD>{2}<TD>{3}<TD>{4}<TD>{5}<TD>{6}<TD>{7}",
r.Quester.Name,
guildname,
factionname,
a.Points,
quests,
a.Rank,
a.DeltaRank,
timeranked
);
#else
// write out the entry information
sw.WriteLine( "<TR><TH><TD>{0}<TD>{1}<TD>{2}<TD>{3}<TD>{4}<TD>{5}<TD>{6}",
r.Quester.Name,
guildname,
a.Points,
quests,
a.Rank,
a.DeltaRank,
timeranked
);
#endif
}
}
sw.WriteLine( "</TABLE>");
sw.Close();
}
public static void WriteQuestLeaderboard(string filename, int nranks)
{
if(QuestRankList == null) return;
// force an update of the quest leaderboard rankings
needsupdate = true;
RefreshQuestRankList();
if ( !Directory.Exists( m_QuestLeaderboardSaveDirectory ) )
Directory.CreateDirectory( m_QuestLeaderboardSaveDirectory );
WriteQuestLeaderboardXml(filename + ".xml", nranks);
WriteQuestLeaderboardHtml(filename + ".html", nranks);
}
[Usage( "QuestLeaderboardSave [filename [minutes[nentries]]][off]" )]
[Description( "Periodically save .xml quest leaderboard information to the specified file" )]
public static void QuestLeaderboardSave_OnCommand( CommandEventArgs e )
{
if(e.Arguments.Length > 0)
{
if(m_QuestLeaderboardTimer != null) m_QuestLeaderboardTimer.Stop();
if(e.Arguments[0].ToLower() != "off")
{
m_QuestLeaderboardFile = e.Arguments[0];
if(e.Arguments.Length > 1)
{
try
{
m_QuestLeaderboardSaveInterval = TimeSpan.FromMinutes(double.Parse(e.Arguments[1]));
}
catch{}
}
if(e.Arguments.Length > 2)
{
try
{
m_QuestLeaderboardSaveRanks = int.Parse(e.Arguments[2]);
}
catch{}
}
m_QuestLeaderboardTimer = new QuestLeaderboardTimer(m_QuestLeaderboardFile, m_QuestLeaderboardSaveInterval, m_QuestLeaderboardSaveRanks);
m_QuestLeaderboardTimer.Start();
}
}
if(m_QuestLeaderboardTimer != null && m_QuestLeaderboardTimer.Running)
{
e.Mobile.SendMessage("Quest Leaderboard is saving to {0} every {1} minutes. Nranks = {2}",
m_QuestLeaderboardFile, m_QuestLeaderboardSaveInterval.TotalMinutes, m_QuestLeaderboardSaveRanks);
}
else
{
e.Mobile.SendMessage("Quest Leaderboard saving is off.");
}
}
public static void QuestLBSSerialize( GenericWriter writer )
{
// version
writer.Write( (int) 0 );
// version 0
if(m_QuestLeaderboardTimer != null && m_QuestLeaderboardTimer.Running)
{
writer.Write((bool)true);
}
else
writer.Write((bool)false);
writer.Write(m_QuestLeaderboardSaveInterval);
writer.Write(m_QuestLeaderboardSaveRanks);
writer.Write(m_QuestLeaderboardFile);
}
public static void QuestLBSDeserialize(GenericReader reader)
{
int version = reader.ReadInt();
switch(version)
{
case 0:
bool running = reader.ReadBool();
m_QuestLeaderboardSaveInterval = reader.ReadTimeSpan();
m_QuestLeaderboardSaveRanks = reader.ReadInt();
m_QuestLeaderboardFile = reader.ReadString();
if(running)
{
if(m_QuestLeaderboardTimer != null) m_QuestLeaderboardTimer.Stop();
m_QuestLeaderboardTimer = new QuestLeaderboardTimer(m_QuestLeaderboardFile, m_QuestLeaderboardSaveInterval, m_QuestLeaderboardSaveRanks);
m_QuestLeaderboardTimer.Start();
}
break;
}
}
// added the duration timer that begins on spawning
private class QuestLeaderboardTimer : Timer
{
private string m_filename;
private int m_nranks;
public QuestLeaderboardTimer( string filename, TimeSpan delay, int nranks ) : base( delay, delay )
{
m_filename = filename;
m_nranks = nranks;
Priority = TimerPriority.FiveSeconds;
}
protected override void OnTick()
{
WriteQuestLeaderboard(m_filename, m_nranks);
}
}
public class TopQuestPlayersGump : Gump
{
private XmlQuestPoints m_attachment;
public TopQuestPlayersGump(XmlQuestPoints attachment) : base( 0,0)
{
if(QuestRankList == null) return;
m_attachment = attachment;
int numberToDisplay = 20;
int height = numberToDisplay*20 + 65;
// prepare the page
AddPage( 0 );
int width = 740;
#if(FACTIONS)
width = 790;
#endif
AddBackground( 0, 0, width, height, 5054 );
AddAlphaRegion( 0, 0, width, height );
AddImageTiled( 20, 20, width - 40, height - 45, 0xBBC );
AddLabel( 20, 2, 55, "Top Quest Player Rankings" );
// guild filter
AddLabel( 40, height - 20, 55, "Filter by Guild" );
string filter = null;
if(m_attachment != null)
filter = m_attachment.guildFilter;
AddImageTiled( 140, height - 20, 160, 19, 0xBBC );
AddTextEntry( 140, height - 20, 160, 19, 0, 200, filter );
AddButton( 20, height - 20, 0x15E1, 0x15E5, 200, GumpButtonType.Reply, 0 );
// name filter
AddLabel( 340, height - 20, 55, "Filter by Name" ); //
string nfilter = null;
if(m_attachment != null)
nfilter = m_attachment.nameFilter;
AddImageTiled( 440, height - 20, 160, 19, 0xBBC );
AddTextEntry( 440, height - 20, 160, 19, 0, 100, nfilter );
AddButton( 320, height - 20, 0x15E1, 0x15E5, 100, GumpButtonType.Reply, 0 );
RefreshQuestRankList();
int xloc = 23;
AddLabel( xloc, 20, 0, "Name" );
xloc += 177;
AddLabel( xloc, 20, 0, "Guild" );
#if(FACTIONS)
xloc += 35;
AddLabel( xloc, 20, 0, "Faction" );
xloc += 15;
#endif
xloc += 50;
AddLabel( xloc, 20, 0, "Points" );
xloc += 50;
AddLabel( xloc, 20, 0, "Quests" );
xloc += 50;
//AddLabel( xloc, 20, 0, "" );
xloc += 70;
AddLabel( xloc, 20, 0, "Rank" );
xloc += 45;
AddLabel( xloc, 20, 0, "Change" );
xloc += 45;
AddLabel( xloc, 20, 0, "Time at Rank" );
// go through the sorted list and display the top ranked players
int y = 40;
int count = 0;
for(int i= 0; i<QuestRankList.Count;i++)
{
if(count >= numberToDisplay) break;
QuestRankEntry r = QuestRankList[i];
if(r == null) continue;
XmlQuestPoints a = r.QuestPointsAttachment;
if(a == null) continue;
if(r.Quester != null && !r.Quester.Deleted && r.Rank > 0 && a != null && !a.Deleted)
{
string guildname = null;
if(r.Quester.Guild != null) guildname = r.Quester.Guild.Abbreviation;
#if(FACTIONS)
string factionname = null;
if(r.Quester is PlayerMobile && ((PlayerMobile)r.Quester).FactionPlayerState != null)
factionname = ((PlayerMobile)r.Quester).FactionPlayerState.Faction.ToString();
#endif
// check for any ranking change and update rank date
if(r.Rank != a.Rank)
{
a.WhenRanked = DateTime.UtcNow;
if(a.Rank > 0)
a.DeltaRank = a.Rank - r.Rank;
a.Rank = r.Rank;
}
// check for guild filter
if(m_attachment != null && m_attachment.guildFilter != null && m_attachment.guildFilter.Length > 0)
{
// parse the comma separated list
string [] args = m_attachment.guildFilter.Split(',');
if(args != null)
{
bool found = false;
foreach(string arg in args)
{
if(arg != null && guildname == arg.Trim())
{
found = true;
break;
}
}
if(!found) continue;
}
}
// check for name filter
if(m_attachment != null && m_attachment.nameFilter != null && m_attachment.nameFilter.Length > 0)
{
// parse the comma separated list
string [] args = m_attachment.nameFilter.Split(',');
if(args != null)
{
bool found = false;
foreach(string arg in args)
{
if(arg != null && r.Quester.Name != null && (r.Quester.Name.ToLower().IndexOf(arg.Trim().ToLower()) >= 0))
{
found = true;
break;
}
}
if(!found) continue;
}
}
count++;
TimeSpan timeranked = DateTime.UtcNow - a.WhenRanked;
int days = (int)timeranked.TotalDays;
int hours = (int)(timeranked.TotalHours - days*24);
int mins = (int)(timeranked.TotalMinutes - ((int)timeranked.TotalHours)*60);
string quests = "???";
try
{
quests = a.QuestsCompleted.ToString();
}
catch{}
xloc = 23;
AddLabel( xloc, y, 0, r.Quester.Name ?? String.Empty );
xloc += 177;
AddLabel( xloc, y, 0, guildname ?? String.Empty );
#if(FACTIONS)
xloc += 35;
AddLabelCropped( xloc, y, 60, 21, 0, factionname ?? String.Empty );
xloc += 15;
#endif
xloc += 50;
AddLabel( xloc, y, 0, a.Points.ToString() );
xloc += 50;
AddLabel( xloc, y, 0, quests ?? String.Empty );
xloc += 50;
//AddLabel( xloc, y, 0, "" );
xloc += 70;
AddLabel( xloc, y, 0, a.Rank.ToString() );
string label=null;
if(days > 0)
label += String.Format("{0} days ",days);
if(hours > 0)
label += String.Format("{0} hours ",hours);
if(mins > 0)
label += String.Format("{0} mins",mins);
if(label == null)
{
label = "just changed";
}
string deltalabel = a.DeltaRank.ToString();
int deltahue = 0;
if(a.DeltaRank > 0)
{
deltalabel = String.Format("+{0}",a.DeltaRank);
deltahue = 68;
}
else if(a.DeltaRank < 0)
{
deltahue = 33;
}
xloc += 50;
AddLabel( xloc, y, deltahue, deltalabel );
xloc += 40;
AddLabel( xloc, y, 0, label);
y += 20;
}
}
}
public override void OnResponse( NetState state, RelayInfo info )
{
if(state == null || state.Mobile == null || info == null) return;
// Get the current name
if(m_attachment != null)
{
TextRelay entry = info.GetTextEntry( 200 );
if(entry != null)
m_attachment.guildFilter = entry.Text;
entry = info.GetTextEntry( 100 );
if(entry != null)
m_attachment.nameFilter = entry.Text;
}
switch(info.ButtonID)
{
case 100:
case 200:
{
// redisplay the gump
state.Mobile.SendGump(new TopQuestPlayersGump(m_attachment));
break;
}
}
}
}
}
}

View File

@@ -0,0 +1,380 @@
using System;
using Server;
using Server.Items;
using Server.Network;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Gumps;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Engines.XmlSpawner2
{
public class XmlQuestPoints : XmlAttachment
{
private int m_Points;
private int m_Completed;
private int m_Credits;
private List<XmlQuestPoints.QuestEntry> m_QuestList = new List<XmlQuestPoints.QuestEntry>();
private DateTime m_WhenRanked;
private int m_Rank;
private int m_DeltaRank;
public string guildFilter;
public string nameFilter;
public List<XmlQuestPoints.QuestEntry> QuestList { get{ return m_QuestList; } set { m_QuestList = value; }}
[CommandProperty( AccessLevel.GameMaster )]
public int Rank { get{ return m_Rank; } set { m_Rank = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int DeltaRank { get{ return m_DeltaRank; } set { m_DeltaRank = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public DateTime WhenRanked { get{ return m_WhenRanked; } set { m_WhenRanked = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int Points { get{ return m_Points; } set { m_Points = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int Credits { get{ return m_Credits; } set { m_Credits = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int QuestsCompleted { get{ return m_Completed; } set { m_Completed = value; } }
public class QuestEntry
{
public Mobile Quester;
public string Name;
public DateTime WhenCompleted;
public DateTime WhenStarted;
public int Difficulty;
public bool PartyEnabled;
public int TimesCompleted = 1;
public QuestEntry()
{
}
public QuestEntry(Mobile m, IXmlQuest quest)
{
Quester = m;
if(quest != null)
{
WhenStarted = quest.TimeCreated;
WhenCompleted = DateTime.UtcNow;
Difficulty = quest.Difficulty;
Name = quest.Name;
}
}
public virtual void Serialize( GenericWriter writer )
{
writer.Write( (int) 0 ); // version
writer.Write(Quester);
writer.Write(Name);
writer.Write(WhenCompleted);
writer.Write(WhenStarted);
writer.Write(Difficulty);
writer.Write(TimesCompleted);
writer.Write(PartyEnabled);
}
public virtual void Deserialize( GenericReader reader )
{
int version = reader.ReadInt();
switch(version)
{
case 0:
Quester = reader.ReadMobile();
Name = reader.ReadString();
WhenCompleted = reader.ReadDateTime();
WhenStarted = reader.ReadDateTime();
Difficulty = reader.ReadInt();
TimesCompleted = reader.ReadInt();
PartyEnabled = reader.ReadBool();
break;
}
}
public static void AddQuestEntry(Mobile m, IXmlQuest quest)
{
if(m == null || quest == null) return;
// get the XmlQuestPoints attachment from the mobile
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m, typeof(XmlQuestPoints));
if(p == null) return;
// look through the list of quests and see if it is one that has already been done
if(p.QuestList == null) p.QuestList = new List<XmlQuestPoints.QuestEntry>();
bool found = false;
foreach(QuestEntry e in p.QuestList)
{
if(e.Name == quest.Name)
{
// found a match, so just change the number and dates
e.TimesCompleted++;
e.WhenStarted = quest.TimeCreated;
e.WhenCompleted = DateTime.UtcNow;
// and update the difficulty and party status
e.Difficulty = quest.Difficulty;
e.PartyEnabled = quest.PartyEnabled;
found = true;
break;
}
}
if(!found)
{
// add a new entry
p.QuestList.Add(new QuestEntry(m, quest));
}
}
}
public XmlQuestPoints(ASerial serial) : base(serial)
{
}
[Attachable]
public XmlQuestPoints()
{
}
public static new void Initialize()
{
CommandSystem.Register( "QuestPoints", AccessLevel.Player, new CommandEventHandler( CheckQuestPoints_OnCommand ) );
CommandSystem.Register( "QuestLog", AccessLevel.Player, new CommandEventHandler( QuestLog_OnCommand ) );
}
[Usage( "QuestPoints" )]
[Description( "Displays the players quest points and ranking" )]
public static void CheckQuestPoints_OnCommand( CommandEventArgs e )
{
if(e == null || e.Mobile == null) return;
string msg = null;
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(e.Mobile, typeof(XmlQuestPoints));
if(p != null)
{
msg = p.OnIdentify(e.Mobile);
}
if(msg != null)
e.Mobile.SendMessage(msg);
}
[Usage( "QuestLog" )]
[Description( "Displays players quest history" )]
public static void QuestLog_OnCommand( CommandEventArgs e )
{
if(e == null || e.Mobile == null) return;
e.Mobile.CloseGump(typeof(XMLQuestLogGump));
e.Mobile.SendGump(new XMLQuestLogGump(e.Mobile));
}
public static void GiveQuestPoints(Mobile from, IXmlQuest quest)
{
if(from == null || quest == null) return;
// find the XmlQuestPoints attachment
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(from, typeof(XmlQuestPoints));
// if doesnt have one yet, then add it
if(p == null)
{
p = new XmlQuestPoints();
XmlAttach.AttachTo(from, p);
}
// if you wanted to scale the points given based on party size, karma, fame, etc.
// this would be the place to do it
int points = quest.Difficulty;
// update the questpoints attachment information
p.Points += points;
p.Credits += points;
p.QuestsCompleted++;
if(from != null)
{
from.SendMessage("You have received {0} quest points!",points);
}
// add the completed quest to the quest list
QuestEntry.AddQuestEntry(from, quest);
// update the overall ranking list
XmlQuestLeaders.UpdateQuestRanking(from, p);
}
public static int GetCredits(Mobile m)
{
int val = 0;
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m, typeof(XmlQuestPoints));
if(p != null)
{
val = p.Credits;
}
return val;
}
public static int GetPoints(Mobile m)
{
int val = 0;
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m, typeof(XmlQuestPoints));
if(p != null)
{
val = p.Points;
}
return val;
}
public static bool HasCredits(Mobile m, int credits, int minpoints)
{
if(m == null || m.Deleted) return false;
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m, typeof(XmlQuestPoints));
if(p != null)
{
if(p.Credits >= credits && p.Points >= minpoints)
{
return true;
}
}
return false;
}
public static bool TakeCredits(Mobile m, int credits)
{
if(m == null || m.Deleted) return false;
XmlQuestPoints p = (XmlQuestPoints)XmlAttach.FindAttachment(m, typeof(XmlQuestPoints));
if(p != null)
{
if(p.Credits >= credits)
{
p.Credits -= credits;
return true;
}
}
return false;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize(writer);
writer.Write( (int) 0 );
// version 0
writer.Write(m_Points);
writer.Write(m_Credits);
writer.Write(m_Completed);
writer.Write(m_Rank);
writer.Write(m_DeltaRank);
writer.Write(m_WhenRanked);
// save the quest history
if(QuestList != null)
{
writer.Write((int)QuestList.Count);
foreach(QuestEntry e in QuestList)
{
e.Serialize(writer);
}
}
else
{
writer.Write((int)0);
}
// need this in order to rebuild the rankings on deser
if(AttachedTo is Mobile)
writer.Write(AttachedTo as Mobile);
else
writer.Write((Mobile)null);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch(version)
{
case 0:
m_Points = reader.ReadInt();
m_Credits = reader.ReadInt();
m_Completed = reader.ReadInt();
m_Rank = reader.ReadInt();
m_DeltaRank = reader.ReadInt();
m_WhenRanked = reader.ReadDateTime();
int nquests = reader.ReadInt();
if(nquests > 0)
{
QuestList = new List<XmlQuestPoints.QuestEntry>(nquests);
for(int i = 0; i< nquests;i++)
{
QuestEntry e = new QuestEntry();
e.Deserialize(reader);
QuestList.Add(e);
}
}
// get the owner of this in order to rebuild the rankings
Mobile quester = reader.ReadMobile();
// rebuild the ranking list
// if they have never made a kill, then dont rank
if(quester != null && QuestsCompleted > 0)
{
XmlQuestLeaders.UpdateQuestRanking(quester, this);
}
break;
}
}
public override string OnIdentify(Mobile from)
{
return String.Format("Quest Points Status:\nTotal Quest Points = {0}\nTotal Quests Completed = {1}\nQuest Credits Available = {2}",Points, QuestsCompleted, Credits);
}
}
}

View File

@@ -0,0 +1,64 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
/*
** XmlQuestPointsRewards
** ArteGordon
** updated 9/18/05
**
** this class lets you specify rewards that can be purchased for XmlQuestPoints quest Credits.
** The items will be displayed in the QuestPointsRewardGump that is opened by the QuestPointsRewardStone
*/
namespace Server.Engines.XmlSpawner2
{
public class XmlQuestPointsRewards
{
public int Cost; // cost of the reward in credits
public Type RewardType; // this will be used to create an instance of the reward
public string Name; // used to describe the reward in the gump
public int ItemID; // used for display purposes
public int ItemHue;
public int yOffset;
public object [] RewardArgs; // arguments passed to the reward constructor
public int MinPoints; // the minimum points requirement for the reward
private static List<XmlQuestPointsRewards> PointsRewardList = new List<XmlQuestPointsRewards>();
public static List<XmlQuestPointsRewards> RewardsList { get { return PointsRewardList; } }
public XmlQuestPointsRewards(int minpoints, Type reward, string name, int cost, int id, int hue, int yoffset, object[] args)
{
RewardType = reward;
Cost = cost;
ItemID = id;
ItemHue = hue;
Name = name;
RewardArgs = args;
MinPoints = minpoints;
yOffset = yoffset;
}
public static void Initialize()
{
// these are items as rewards. Note that the args list must match a constructor for the reward type specified.
PointsRewardList.Add( new XmlQuestPointsRewards( 1000, typeof(PowerScroll), "105 Smithing powerscroll", 1000, 0x14F0, 0, 5, new object[] { SkillName.Blacksmith, 105 }));
PointsRewardList.Add( new XmlQuestPointsRewards( 2000, typeof(PowerScroll), "110 Smithing powerscroll", 2000, 0x14F0, 0x22, 5, new object[] { SkillName.Blacksmith, 110 }));
PointsRewardList.Add( new XmlQuestPointsRewards( 4000, typeof(PowerScroll), "115 Smithing powerscroll", 4000, 0x14F0, 0x44, 5, new object[] { SkillName.Blacksmith, 115 }));
PointsRewardList.Add( new XmlQuestPointsRewards( 500, typeof(AncientSmithyHammer), "+20 Ancient Smithy Hammer, 50 uses", 500, 0x13E4, 0, 5, new object[] { 20, 50 }));
PointsRewardList.Add( new XmlQuestPointsRewards( 200, typeof(ColoredAnvil), "Colored Anvil", 400, 0xFAF, 0, 5, null ));
PointsRewardList.Add( new XmlQuestPointsRewards( 100, typeof(PowderOfTemperament), "Powder Of Temperament, 10 uses", 300, 4102, 0, 5, new object[] { 10 }));
PointsRewardList.Add( new XmlQuestPointsRewards( 100, typeof(LeatherGlovesOfMining), "+20 Leather Gloves Of Mining", 200, 0x13c6, 0, 5, new object[] { 20 }));
// this is an example of adding a mobile as a reward
PointsRewardList.Add( new XmlQuestPointsRewards( 0, typeof(RidableLlama),"Ridable Llama", 1, 0x20f6, 0, -15, null));
// this is an example of adding an attachment as a reward
//PointsRewardList.Add( new XmlQuestPointsRewards( 0, typeof(XmlEnemyMastery), "+200% Balron Mastery for 1 day", 2, 0, 0, 0, new object[] { "Balron", 50, 200, 1440.0 }));
//PointsRewardList.Add( new XmlQuestPointsRewards( 0, typeof(XmlStr), "+20 Strength for 1 day", 10, 0, new object[] { 20, 86400.0 }));
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,283 @@
using System;
using System.Data;
using System.IO;
using System.Collections;
using Server;
using Server.Items;
using Server.Network;
using Server.Gumps;
using Server.Targeting;
using System.Reflection;
using Server.Commands;
using CPA = Server.CommandPropertyAttribute;
using System.Xml;
using Server.Spells;
using System.Text;
using Server.Accounting;
using System.Diagnostics;
using Server.Misc;
using Server.Engines.XmlSpawner2;
namespace Server.Mobiles
{
public class XmlSpawnerSkillCheck
{
// alternate skillcheck hooks to replace those in SkillCheck.cs
public static bool Mobile_SkillCheckLocation( Mobile from, SkillName skillName, double minSkill, double maxSkill )
{
Skill skill = from.Skills[skillName];
if ( skill == null )
return false;
// call the default skillcheck handler
bool success = SkillCheck.Mobile_SkillCheckLocation( from, skillName, minSkill, maxSkill );
// call the xmlspawner skillcheck handler
CheckSkillUse(from, skill, success);
return success;
}
public static bool Mobile_SkillCheckDirectLocation( Mobile from, SkillName skillName, double chance )
{
Skill skill = from.Skills[skillName];
if ( skill == null )
return false;
// call the default skillcheck handler
bool success = SkillCheck.Mobile_SkillCheckDirectLocation( from, skillName, chance );
// call the xmlspawner skillcheck handler
CheckSkillUse(from, skill, success);
return success;
}
public static bool Mobile_SkillCheckTarget( Mobile from, SkillName skillName, object target, double minSkill, double maxSkill )
{
Skill skill = from.Skills[skillName];
if ( skill == null )
return false;
// call the default skillcheck handler
bool success = SkillCheck.Mobile_SkillCheckTarget( from, skillName, target, minSkill, maxSkill );
// call the xmlspawner skillcheck handler
CheckSkillUse(from, skill, success);
return success;
}
public static bool Mobile_SkillCheckDirectTarget( Mobile from, SkillName skillName, object target, double chance )
{
Skill skill = from.Skills[skillName];
if ( skill == null )
return false;
// call the default skillcheck handler
bool success = SkillCheck.Mobile_SkillCheckDirectTarget( from, skillName, target, chance );
// call the xmlspawner skillcheck handler
CheckSkillUse(from, skill, success);
return success;
}
public class RegisteredSkill
{
public const int MaxSkills = 52;
public const SkillName Invalid = (SkillName)(-1);
public object target;
public SkillName sid;
// note the extra skill MaxSkills +1 is used for any unknown skill that falls outside of the known 52
private static ArrayList[] m_FeluccaSkillList = new ArrayList[MaxSkills+1];
private static ArrayList[] m_TrammelSkillList = new ArrayList[MaxSkills+1];
private static ArrayList[] m_MalasSkillList = new ArrayList[MaxSkills+1];
private static ArrayList[] m_IlshenarSkillList = new ArrayList[MaxSkills+1];
private static ArrayList[] m_TokunoSkillList = new ArrayList[MaxSkills+1];
// primary function that returns the list of objects (spawners) that are associated with a given skillname by map
public static ArrayList TriggerList(SkillName index, Map map)
{
if(map == null || map == Map.Internal) return null;
ArrayList[] maplist;
// get the list for the specified map
if(map == Map.Felucca)
maplist = m_FeluccaSkillList;
else
if(map == Map.Ilshenar)
maplist = m_IlshenarSkillList;
else
if(map == Map.Malas)
maplist = m_MalasSkillList;
else
if(map == Map.Trammel)
maplist = m_TrammelSkillList;
else
if(map == Map.Tokuno)
maplist = m_TokunoSkillList;
else
return null;
// is it one of the standard 52 skills
if((int)index >= 0 && (int)index < MaxSkills)
{
if(maplist[(int)index] == null)
maplist[(int)index] = new ArrayList();
return maplist[(int)index];
}
else
// otherwise pull it out of the final slot for unknown skills. I dont know of a condition that would lead to
// additional skills being registered but it will support them if they are
{
if(maplist[MaxSkills] == null)
maplist[MaxSkills] = new ArrayList();
return maplist[MaxSkills];
}
}
}
public static void RegisterSkillTrigger( object o, SkillName s, Map map)
{
if(o == null || s == RegisteredSkill.Invalid) return;
// go through the list and if the spawner is not on it yet, then add it
bool found = false;
ArrayList skilllist = RegisteredSkill.TriggerList(s, map);
if(skilllist == null) return;
foreach(RegisteredSkill rs in skilllist)
{
if(rs.target == o && rs.sid == s)
{
found = true;
// dont register a skill if it is already on the list for this spawner
break;
}
}
// if it hasnt already been added to the list, then add it
if(!found)
{
RegisteredSkill newrs = new RegisteredSkill();
newrs.target = o;
newrs.sid = s;
skilllist.Add(newrs);
}
}
public static void UnRegisterSkillTrigger( object o, SkillName s, Map map, bool all)
{
if(o == null || s == RegisteredSkill.Invalid) return;
// go through the list and if the spawner is on it regardless of the skill registered, then remove it
if(all)
{
for(int i = 0;i<RegisteredSkill.MaxSkills+1;i++)
{
ArrayList skilllist = RegisteredSkill.TriggerList((SkillName)i, map);
if(skilllist == null) return;
foreach(RegisteredSkill rs in skilllist)
{
if(rs.target == o)
{
skilllist.Remove(rs);
break;
}
}
}
} else
{
ArrayList skilllist = RegisteredSkill.TriggerList(s, map);
if(skilllist == null) return;
// if the all flag is not set then just remove the spawner from the list for the specified skill
foreach(RegisteredSkill rs in skilllist)
{
if((rs.target == o) && (rs.sid == s))
{
skilllist.Remove(rs);
break;
}
}
}
}
// determines whether XmlSpawner, XmlAttachment, or XmlQuest OnSkillUse methods should be invoked.
public static void CheckSkillUse( Mobile m, Skill skill, bool success)
{
if(!(m is PlayerMobile) || skill == null) return;
/*
// first check for any attachments that might support OnSkillUse
ArrayList list = XmlAttach.FindAttachments(m);
if(list != null && list.Count > 0)
{
foreach(XmlAttachment a in list)
{
if(a != null && !a.Deleted && a.HandlesOnSkillUse)
{
a.OnSkillUse(m, skill, success);
}
}
}
*/
// then check for registered skills
ArrayList skilllist = RegisteredSkill.TriggerList(skill.SkillName, m.Map);
if(skilllist == null) return;
// determine whether there are any registered objects for this skill
foreach(RegisteredSkill rs in skilllist)
{
if(rs.sid == skill.SkillName)
{
// if so then invoke their skill handlers
if(rs.target is XmlSpawner)
{
XmlSpawner spawner = (XmlSpawner)rs.target;
if ( spawner.HandlesOnSkillUse )
{
// call the spawner handler
spawner.OnSkillUse(m, skill, success);
}
} else
if(rs.target is IXmlQuest)
{
IXmlQuest quest = (IXmlQuest)rs.target;
if ( quest.HandlesOnSkillUse )
{
// call the xmlquest handler
quest.OnSkillUse(m, skill, success);
}
}
}
}
}
}
}

View File

@@ -0,0 +1,372 @@
#define BOOKTEXTENTRY
using System;
using System.IO;
using System.Text;
using Server;
using Server.Network;
using Server.Mobiles;
using Server.Gumps;
namespace Server.Items
{
public delegate void XmlTextEntryBookCallback( Mobile from, object [] args, string response );
public class XmlTextEntryBook : BaseEntryBook
{
public XmlTextEntryBookCallback m_bookcallback;
public object [] m_args;
public XmlTextEntryBook( int itemID, string title, string author, int pageCount, bool writable,
XmlTextEntryBookCallback callback, object [] args) : base( itemID, title, author, pageCount, writable )
{
m_args = args;
m_bookcallback = callback;
}
public XmlTextEntryBook( Serial serial ) : base( serial )
{
}
public void FillTextEntryBook(string text)
{
int pagenum = 0;
BookPageInfo [] pages = Pages;
int current = 0;
// break up the text into single line length pieces
while(text != null && current < text.Length)
{
int lineCount = 8;
string[] lines = new string[lineCount];
// place the line on the page
for(int i=0;i<lineCount;i++)
{
if(current < text.Length)
{
// make each line 25 chars long
int length = text.Length - current;
if(length > 20) length = 20;
lines[i] = text.Substring(current,length);
current += length;
}
else
{
// fill up the remaining lines
lines[i] = String.Empty;
}
}
if ( pagenum >= PagesCount )
return;
Pages[pagenum].Lines = lines;
pagenum++;
}
// empty the remaining contents
for(int j=pagenum;j < PagesCount; j++)
{
if(Pages[j].Lines.Length > 0)
for(int i=0;i<Pages[j].Lines.Length;i++)
{
Pages[j].Lines[i] = String.Empty;
}
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
Delete();
}
}
// -------------------------------------------------------------
// modifed from Beta-36 distribution version of BaseBook from basebook.cs
// adds a hook to allow processing of book text on content change
// -------------------------------------------------------------
public class BaseEntryBook : Item
{
private string m_Title;
private string m_Author;
private BookPageInfo[] m_Pages;
private bool m_Writable;
[CommandProperty( AccessLevel.GameMaster )]
public string Title
{
get { return m_Title; }
set { m_Title = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public string Author
{
get { return m_Author; }
set { m_Author = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Writable
{
get { return m_Writable; }
set { m_Writable = value; }
}
[CommandProperty(AccessLevel.GameMaster)]
public int PagesCount
{
get { return m_Pages.Length; }
}
public BookPageInfo[] Pages
{
get { return m_Pages; }
}
[Constructable]
public BaseEntryBook( int itemID, string title, string author, int pageCount, bool writable) : base( itemID )
{
m_Title = title;
m_Author = author;
m_Pages = new BookPageInfo[pageCount];
m_Writable = writable;
for ( int i = 0; i < m_Pages.Length; ++i )
m_Pages[i] = new BookPageInfo();
}
public BaseEntryBook( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
#if(BOOKTEXTENTRY)
public override void OnDoubleClick ( Mobile from )
{
from.Send( new EntryBookHeader( from, this ) );
from.Send( new EntryBookPageDetails( this ) );
}
public static void Initialize()
{
// This will hijack the default packet handler for basebooks content change. The header change handlers are left alone and basebook will still handle them.
// This means that BaseEntryBooks will not support header changes (they are not intended to)
//PacketHandlers.Register( 0x66, 0, true, new OnPacketReceive( ContentChange ) );
}
public static void ContentChange( NetState state, PacketReader pvSrc )
{
// need to deal with actual books
string entryText = String.Empty;
Mobile from = state.Mobile;
int serial = pvSrc.ReadInt32();
Item bookitem = World.FindItem(serial);
// first try it as a normal basebook
if (bookitem is BaseBook)
{
// do the base book content change
BaseContentChange(bookitem as BaseBook, state, pvSrc);
return;
}
// then try it as a text entry book
BaseEntryBook book = bookitem as BaseEntryBook;
if (book == null) return;
// get the number of available pages in the book
int pageCount = pvSrc.ReadUInt16();
if ( pageCount > book.PagesCount )
return;
for ( int i = 0; i < pageCount; ++i )
{
// get the current page number being read
int index = pvSrc.ReadUInt16();
if ( index >= 1 && index <= book.PagesCount )
{
--index;
int lineCount = pvSrc.ReadUInt16();
if ( lineCount <= 8 )
{
string[] lines = new string[lineCount];
for ( int j = 0; j < lineCount; ++j )
{
if ( (lines[j] = pvSrc.ReadUTF8StringSafe()).Length >= 80 )
return;
}
book.Pages[index].Lines = lines;
}
else
{
return;
}
}
else
{
return;
}
}
System.Text.StringBuilder sb = new System.Text.StringBuilder();
// add the book lines to the entry string
for ( int i = 0; i < book.PagesCount; ++i )
{
for(int j=0;j<book.Pages[i].Lines.Length;j++)
{
sb.Append(book.Pages[i].Lines[j]);
}
}
// send the book text off to be processed by invoking the callback if it is a textentry book
XmlTextEntryBook tebook = book as XmlTextEntryBook;
if(tebook != null && tebook.m_bookcallback != null)
{
tebook.m_bookcallback(state.Mobile, tebook.m_args, sb.ToString());
}
}
public static void BaseContentChange(BaseBook book, NetState state, PacketReader pvSrc)
{
Mobile from = state.Mobile;
if (book == null)
return;
int pageCount = pvSrc.ReadUInt16();
if (state.IsEnhancedClient && pageCount == 1)
{
book.ContentChangeEC(state, pvSrc);
return;
}
else if (book.Writable && from.InRange(book.GetWorldLocation(), 1))
{
if (pageCount > book.PagesCount)
return;
for (int i = 0; i < pageCount; ++i)
{
int index = pvSrc.ReadUInt16();
if (index >= 1 && index <= book.PagesCount)
{
--index;
int lineCount = pvSrc.ReadUInt16();
if (lineCount <= 8)
{
string[] lines = new string[lineCount];
for (int j = 0; j < lineCount; ++j)
if ((lines[j] = pvSrc.ReadUTF8StringSafe()).Length >= 80)
return;
book.Pages[index].Lines = lines;
}
else
{
return;
}
}
else
{
return;
}
}
}
}
#endif
}
#if(BOOKTEXTENTRY)
public sealed class EntryBookPageDetails : Packet
{
public EntryBookPageDetails( BaseEntryBook book ) : base( 0x66 )
{
EnsureCapacity( 256 );
m_Stream.Write( (int) book.Serial );
m_Stream.Write( (ushort) book.PagesCount );
for ( int i = 0; i < book.PagesCount; ++i )
{
BookPageInfo page = book.Pages[i];
m_Stream.Write( (ushort) (i + 1) );
m_Stream.Write( (ushort) page.Lines.Length );
for ( int j = 0; j < page.Lines.Length; ++j )
{
byte[] buffer = Utility.UTF8.GetBytes( page.Lines[j] );
m_Stream.Write( buffer, 0, buffer.Length );
m_Stream.Write( (byte) 0 );
}
}
}
}
public sealed class EntryBookHeader : Packet
{
public EntryBookHeader( Mobile from, BaseEntryBook book ) : base ( 0xD4 )
{
string title = book.Title == null ? "" : book.Title;
string author = book.Author == null ? "" : book.Author;
byte[] titleBuffer = Utility.UTF8.GetBytes( title );
byte[] authorBuffer = Utility.UTF8.GetBytes( author );
EnsureCapacity( 15 + titleBuffer.Length + authorBuffer.Length );
m_Stream.Write( (int) book.Serial );
m_Stream.Write( (bool) true );
m_Stream.Write( (bool) book.Writable && from.InRange( book.GetWorldLocation(), 1 ) );
m_Stream.Write( (ushort) book.PagesCount );
m_Stream.Write( (ushort) (titleBuffer.Length + 1) );
m_Stream.Write( titleBuffer, 0, titleBuffer.Length );
m_Stream.Write( (byte) 0 ); // terminate
m_Stream.Write( (ushort) (authorBuffer.Length + 1) );
m_Stream.Write( authorBuffer, 0, authorBuffer.Length );
m_Stream.Write( (byte) 0 ); // terminate
}
}
#endif
}

View File

@@ -0,0 +1,69 @@
using System;
using System.Text;
using Server;
using Server.Items;
using Server.Targeting;
using Server.Mobiles;
namespace Server.Commands
{
public class WhatIsIt
{
public static void Initialize()
{
CommandSystem.Register("WhatIsIt", AccessLevel.Player, new CommandEventHandler(GenericCommand_OnCommand));
}
public class WhatIsItTarget : Target
{
public WhatIsItTarget()
: base(30, true, TargetFlags.None)
{
CheckLOS = false;
}
protected override void OnTarget( Mobile from, object targeted )
{
if(from == null || targeted == null) return;
string name = String.Empty;
string typename = targeted.GetType().Name;
string article = "a";
if (typename != null && typename.Length > 0)
{
if ("aeiouy".IndexOf(typename.ToLower()[0]) >= 0)
{
article = "an";
}
}
if(targeted is Item)
{
name = ((Item)targeted).Name;
} else
if(targeted is Mobile)
{
name = ((Mobile)targeted).Name;
}
if (name != String.Empty && name != null)
{
from.SendMessage("That is {0} {1} named '{2}'", article, typename, name);
}
else
{
from.SendMessage("That is {0} {1} with no name", article, typename);
}
}
}
[Usage( "WhatIsIt" )]
public static void GenericCommand_OnCommand( CommandEventArgs e )
{
if(e == null || e.Mobile == null) return;
e.Mobile.Target = new WhatIsItTarget();
}
}
}

View File

@@ -0,0 +1,466 @@
using System;
using Server;
using System.IO;
using System.Collections;
using Server.Multis;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using System.Runtime.Serialization;
using Server.Targeting;
using Server.Commands;
using Server.Commands.Generic;
namespace Server.Engines.XmlSpawner2
{
public class WriteMulti
{
private class TileEntry
{
public int ID;
public int X;
public int Y;
public int Z;
public TileEntry(int id, int x, int y, int z)
{
ID = id;
X = x;
Y = y;
Z = z;
}
}
public static void Initialize()
{
CommandSystem.Register("WriteMulti", XmlSpawner.DiskAccessLevel, new CommandEventHandler(WriteMulti_OnCommand));
}
[Usage("WriteMulti <MultiFile> [zmin zmax][-noitems][-nostatics][-nomultis][-noaddons][-invisible]")]
[Description("Creates a multi text file from the objects within the targeted area. The min/max z range can also be specified.")]
public static void WriteMulti_OnCommand(CommandEventArgs e)
{
if (e == null || e.Mobile == null) return;
if (e.Mobile.AccessLevel < XmlSpawner.DiskAccessLevel)
{
e.Mobile.SendMessage("You do not have rights to perform this command.");
return;
}
if (e.Arguments != null && e.Arguments.Length < 1)
{
e.Mobile.SendMessage("Usage: {0} <MultiFile> [zmin zmax][-noitems][-nostatics][-nomultis][-noaddons][-invisible]", e.Command);
return;
}
string filename = e.Arguments[0].ToString();
int zmin = int.MinValue;
int zmax = int.MinValue;
bool includeitems = true;
bool includestatics = true;
bool includemultis = true;
bool includeaddons = true;
bool includeinvisible = false;
if (e.Arguments.Length > 1)
{
int index = 1;
while (index < e.Arguments.Length)
{
if (e.Arguments[index] == "-noitems")
{
includeitems = false;
index++;
}
else if (e.Arguments[index] == "-nostatics")
{
includestatics = false;
index++;
}
else if (e.Arguments[index] == "-nomultis")
{
includemultis = false;
index++;
}
else if (e.Arguments[index] == "-noaddons")
{
includeaddons = false;
index++;
}
else if (e.Arguments[index] == "-invisible")
{
includeinvisible = true;
index++;
}
else
{
try
{
zmin = int.Parse(e.Arguments[index++]);
zmax = int.Parse(e.Arguments[index++]);
}
catch
{
e.Mobile.SendMessage("{0} : Invalid zmin zmax arguments", e.Command);
return;
}
}
}
}
string dirname;
if (System.IO.Directory.Exists(XmlSpawner.XmlSpawnDir) && filename != null && !filename.StartsWith("/") && !filename.StartsWith("\\"))
{
// put it in the defaults directory if it exists
dirname = String.Format("{0}/{1}", XmlSpawner.XmlSpawnDir, filename);
}
else
{
// otherwise just put it in the main installation dir
dirname = filename;
}
// check to see if the file already exists and can be written to by the owner
if (System.IO.File.Exists(dirname))
{
// check the file
try
{
StreamReader op = new StreamReader(dirname, false);
if (op == null)
{
e.Mobile.SendMessage("Cannot access file {0}", dirname);
return;
}
string line = op.ReadLine();
op.Close();
// check the first line
if (line != null && line.Length > 0)
{
string[] args = line.Split(" ".ToCharArray(), 3);
if (args == null || args.Length < 3)
{
e.Mobile.SendMessage("Cannot overwrite file {0} : not owner", dirname);
return;
}
if (args[2] != e.Mobile.Name)
{
e.Mobile.SendMessage("Cannot overwrite file {0} : not owner", dirname);
return;
}
}
else
{
e.Mobile.SendMessage("Cannot overwrite file {0} : not owner", dirname);
return;
}
}
catch
{
e.Mobile.SendMessage("Cannot overwrite file {0}", dirname);
return;
}
}
DefineMultiArea(e.Mobile, dirname, zmin, zmax, includeitems, includestatics, includemultis, includeinvisible, includeaddons);
}
public static void DefineMultiArea(Mobile m, string dirname, int zmin, int zmax, bool includeitems, bool includestatics,
bool includemultis, bool includeinvisible, bool includeaddons)
{
object[] multiargs = new object[8];
multiargs[0] = dirname;
multiargs[1] = zmin;
multiargs[2] = zmax;
multiargs[3] = includeitems;
multiargs[4] = includestatics;
multiargs[5] = includemultis;
multiargs[6] = includeinvisible;
multiargs[7] = includeaddons;
BoundingBoxPicker.Begin(m, new BoundingBoxCallback(DefineMultiArea_Callback), multiargs);
}
private static void DefineMultiArea_Callback(Mobile from, Map map, Point3D start, Point3D end, object state)
{
object[] multiargs = (object[])state;
if (from != null && multiargs != null && map != null)
{
string dirname = (string)multiargs[0];
int zmin = (int)multiargs[1];
int zmax = (int)multiargs[2];
bool includeitems = (bool)multiargs[3];
bool includestatics = (bool)multiargs[4];
bool includemultis = (bool)multiargs[5];
bool includeinvisible = (bool)multiargs[6];
bool includeaddons = (bool)multiargs[7];
ArrayList itemlist = new ArrayList();
ArrayList staticlist = new ArrayList();
ArrayList tilelist = new ArrayList();
int sx = (start.X > end.X) ? end.X : start.X;
int sy = (start.Y > end.Y) ? end.Y : start.Y;
int ex = (start.X < end.X) ? end.X : start.X;
int ey = (start.Y < end.Y) ? end.Y : start.Y;
// find all of the world-placed items within the specified area
if (includeitems)
{
// make the first pass for items only
IPooledEnumerable eable = map.GetItemsInBounds(new Rectangle2D(sx, sy, ex - sx + 1, ey - sy + 1));
foreach (Item item in eable)
{
// is it within the bounding area
if (item.Parent == null && (zmin == int.MinValue || (item.Location.Z >= zmin && item.Location.Z <= zmax)))
{
// add the item
if ((includeinvisible || item.Visible) && (item.ItemID <= 16383))
{
itemlist.Add(item);
}
}
}
eable.Free();
int searchrange = 100;
// make the second expanded pass to pick up addon components and multi components
eable = map.GetItemsInBounds(new Rectangle2D(sx - searchrange, sy - searchrange, ex - sy + searchrange * 2 + 1,
ey - sy + searchrange * 2 + 1));
foreach (Item item in eable)
{
// is it within the bounding area
if (item.Parent == null)
{
if (item is BaseAddon && includeaddons)
{
// go through all of the addon components
foreach (AddonComponent c in ((BaseAddon)item).Components)
{
int x = c.X;
int y = c.Y;
int z = c.Z;
if ((includeinvisible || item.Visible) && (item.ItemID <= 16383 || includemultis) &&
(x >= sx && x <= ex && y >= sy && y <= ey && (zmin == int.MinValue || (z >= zmin && z <= zmax))))
{
itemlist.Add(c);
}
}
}
if (item is BaseMulti && includemultis)
{
// go through all of the multi components
MultiComponentList mcl = ((BaseMulti)item).Components;
if (mcl != null && mcl.List != null)
{
for (int i = 0; i < mcl.List.Length; i++)
{
MultiTileEntry t = mcl.List[i];
int x = t.m_OffsetX + item.X;
int y = t.m_OffsetY + item.Y;
int z = t.m_OffsetZ + item.Z;
int itemID = t.m_ItemID & 0x3FFF;
if (x >= sx && x <= ex && y >= sy && y <= ey && (zmin == int.MinValue || (z >= zmin && z <= zmax)))
{
tilelist.Add(new TileEntry(itemID, x, y, z));
}
}
}
}
}
}
eable.Free();
}
// find all of the static tiles within the specified area
if (includestatics)
{
// count the statics
for (int x = sx; x < ex; x++)
{
for (int y = sy; y < ey; y++)
{
StaticTile[] statics = map.Tiles.GetStaticTiles(x, y, false);
for (int j = 0; j < statics.Length; j++)
{
if ((zmin == int.MinValue || (statics[j].Z >= zmin && statics[j].Z <= zmax)))
{
staticlist.Add(new TileEntry(statics[j].ID & 0x3FFF, x, y, statics[j].Z));
}
}
}
}
}
int nstatics = staticlist.Count;
int nitems = itemlist.Count;
int ntiles = tilelist.Count;
int ntotal = nitems + nstatics + ntiles;
int ninvisible = 0;
int nmultis = ntiles;
int naddons = 0;
foreach (Item item in itemlist)
{
int x = item.X - from.X;
int y = item.Y - from.Y;
int z = item.Z - from.Z;
if (item.ItemID > 16383)
{
nmultis++;
}
if (!item.Visible)
{
ninvisible++;
}
if (item is BaseAddon || item is AddonComponent)
{
naddons++;
}
}
try
{
// open the file, overwrite any previous contents
StreamWriter op = new StreamWriter(dirname, false);
if (op != null)
{
// write the header
op.WriteLine("1 version {0}", from.Name);
op.WriteLine("{0} num components", ntotal);
// write out the items
foreach (Item item in itemlist)
{
int x = item.X - from.X;
int y = item.Y - from.Y;
int z = item.Z - from.Z;
if (item.Hue > 0)
{
// format is x y z visible hue
op.WriteLine("{0} {1} {2} {3} {4} {5}", item.ItemID, x, y, z, item.Visible ? 1 : 0, item.Hue);
}
else
{
// format is x y z visible
op.WriteLine("{0} {1} {2} {3} {4}", item.ItemID, x, y, z, item.Visible ? 1 : 0);
}
}
if (includestatics)
{
foreach (TileEntry s in staticlist)
{
int x = s.X - from.X;
int y = s.Y - from.Y;
int z = s.Z - from.Z;
int ID = s.ID;
op.WriteLine("{0} {1} {2} {3} {4}", ID, x, y, z, 1);
}
}
if (includemultis)
{
foreach (TileEntry s in tilelist)
{
int x = s.X - from.X;
int y = s.Y - from.Y;
int z = s.Z - from.Z;
int ID = s.ID;
op.WriteLine("{0} {1} {2} {3} {4}", ID, x, y, z, 1);
}
}
}
op.Close();
}
catch
{
from.SendMessage("Error writing multi file {0}", dirname);
return;
}
from.SendMessage(66, "WriteMulti results:");
if (includeitems)
{
from.SendMessage(66, "Included {0} items", nitems);
if (includemultis)
{
from.SendMessage("{0} multis", nmultis);
}
else
{
from.SendMessage(33, "Ignored multis");
}
if (includeinvisible)
{
from.SendMessage("{0} invisible", ninvisible);
}
else
{
from.SendMessage(33, "Ignored invisible");
}
if (includeaddons)
{
from.SendMessage("{0} addons", naddons);
}
else
{
from.SendMessage(33, "Ignored addons");
}
}
else
{
from.SendMessage(33, "Ignored items");
}
if (includestatics)
{
from.SendMessage(66, "Included {0} statics", nstatics);
}
else
{
from.SendMessage(33, "Ignored statics");
}
from.SendMessage(66, "Saved {0} components to {1}", ntotal, dirname);
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,476 @@
using System;
using System.IO;
using System.Xml;
using System.Collections;
using Server.Network;
using Server.Mobiles;
/*
** Modified from RunUO 1.0.0 CategorizedAddGump.cs
** by ArteGordon
** 2/5/05
*/
namespace Server.Gumps
{
public abstract class XmlAddCAGNode
{
public abstract string Caption{ get; }
public abstract void OnClick( Mobile from, int page, int index, Gump gump );
}
public class XmlAddCAGObject : XmlAddCAGNode
{
private Type m_Type;
private int m_ItemID;
private int m_Hue;
private XmlAddCAGCategory m_Parent;
public Type Type{ get{ return m_Type; } }
public int ItemID{ get{ return m_ItemID; } }
public int Hue{ get{ return m_Hue; } }
public XmlAddCAGCategory Parent{ get{ return m_Parent; } }
public override string Caption{ get{ return ( m_Type == null ? "bad type" : m_Type.Name ); } }
public override void OnClick( Mobile from, int page, int index, Gump gump )
{
if ( m_Type == null )
{
from.SendMessage( "That is an invalid type name." );
}
else
{
if(gump is XmlAddGump)
{
XmlAddGump xmladdgump = (XmlAddGump)gump;
//Commands.Handle( from, String.Format( "{0}Add {1}", Commands.CommandPrefix, m_Type.Name ) );
if(xmladdgump != null && xmladdgump.defs != null && xmladdgump.defs.NameList != null &&
index >= 0 && index < xmladdgump.defs.NameList.Length)
{
xmladdgump.defs.NameList[index] = m_Type.Name;
XmlAddGump.Refresh(from, true);
}
from.SendGump( new XmlCategorizedAddGump( from, m_Parent, page, index, xmladdgump ) );
}
else
if(gump is XmlSpawnerGump)
{
XmlSpawner m_Spawner = ((XmlSpawnerGump)gump).m_Spawner;
if(m_Spawner != null)
{
XmlSpawnerGump xg = m_Spawner.SpawnerGump;
if(xg != null)
{
xg.Rentry = new XmlSpawnerGump.ReplacementEntry();
xg.Rentry.Typename = m_Type.Name;
xg.Rentry.Index = index;
xg.Rentry.Color = 0x1436;
Timer.DelayCall( TimeSpan.Zero, new TimerStateCallback( XmlSpawnerGump.Refresh_Callback ), new object[]{ from } );
//from.CloseGump(typeof(XmlSpawnerGump));
//from.SendGump( new XmlSpawnerGump(xg.m_Spawner, xg.X, xg.Y, xg.m_ShowGump, xg.xoffset, xg.page, xg.Rentry) );
}
}
}
}
}
public XmlAddCAGObject( XmlAddCAGCategory parent, XmlTextReader xml )
{
m_Parent = parent;
if ( xml.MoveToAttribute( "type" ) )
m_Type = ScriptCompiler.FindTypeByFullName( xml.Value, false );
if ( xml.MoveToAttribute( "gfx" ) )
m_ItemID = XmlConvert.ToInt32( xml.Value );
if ( xml.MoveToAttribute( "hue" ) )
m_Hue = XmlConvert.ToInt32( xml.Value );
}
}
public class XmlAddCAGCategory : XmlAddCAGNode
{
private string m_Title;
private XmlAddCAGNode[] m_Nodes;
private XmlAddCAGCategory m_Parent;
public string Title{ get{ return m_Title; } }
public XmlAddCAGNode[] Nodes{ get{ return m_Nodes; } }
public XmlAddCAGCategory Parent{ get{ return m_Parent; } }
public override string Caption{ get{ return m_Title; } }
public override void OnClick( Mobile from, int page, int index, Gump gump )
{
from.SendGump( new XmlCategorizedAddGump( from, this, 0, index, gump ) );
}
private XmlAddCAGCategory()
{
m_Title = "no data";
m_Nodes = new XmlAddCAGNode[0];
}
public XmlAddCAGCategory( XmlAddCAGCategory parent, XmlTextReader xml )
{
m_Parent = parent;
if ( xml.MoveToAttribute( "title" ) )
{
if(xml.Value == "Add Menu")
m_Title = "XmlAdd Menu";
else
m_Title = xml.Value;
}
else
m_Title = "empty";
if ( m_Title == "Docked" )
m_Title = "Docked 2";
if ( xml.IsEmptyElement )
{
m_Nodes = new XmlAddCAGNode[0];
}
else
{
ArrayList nodes = new ArrayList();
try{
while ( xml.Read() && xml.NodeType != XmlNodeType.EndElement )
{
if ( xml.NodeType == XmlNodeType.Element && xml.Name == "object" )
nodes.Add( new XmlAddCAGObject( this, xml ) );
else if (xml.NodeType == XmlNodeType.Element && xml.Name == "category")
{
if (!xml.IsEmptyElement)
{
nodes.Add(new XmlAddCAGCategory(this, xml));
}
}
else
xml.Skip();
}
} catch (Exception ex){
Console.WriteLine("XmlCategorizedAddGump: Corrupted Data/objects.xml file detected. Not all XmlCAG objects loaded. {0}", ex);
}
m_Nodes = (XmlAddCAGNode[])nodes.ToArray( typeof( XmlAddCAGNode ) );
}
}
private static XmlAddCAGCategory m_Root;
public static XmlAddCAGCategory Root
{
get
{
if ( m_Root == null )
m_Root = Load( "Data/objects.xml" );
return m_Root;
}
}
public static XmlAddCAGCategory Load( string path )
{
if ( File.Exists( path ) )
{
XmlTextReader xml = new XmlTextReader( path );
xml.WhitespaceHandling = WhitespaceHandling.None;
while ( xml.Read() )
{
if ( xml.Name == "category" && xml.NodeType == XmlNodeType.Element )
{
XmlAddCAGCategory cat = new XmlAddCAGCategory( null, xml );
xml.Close();
return cat;
}
}
}
return new XmlAddCAGCategory();
}
}
public class XmlCategorizedAddGump : Gump
{
public static bool OldStyle = PropsConfig.OldStyle;
public static readonly int GumpOffsetX = PropsConfig.GumpOffsetX;
public static readonly int GumpOffsetY = PropsConfig.GumpOffsetY;
public static readonly int TextHue = PropsConfig.TextHue;
public static readonly int TextOffsetX = PropsConfig.TextOffsetX;
public static readonly int OffsetGumpID = PropsConfig.OffsetGumpID;
public static readonly int HeaderGumpID = PropsConfig.HeaderGumpID;
public static readonly int EntryGumpID = PropsConfig.EntryGumpID;
public static readonly int BackGumpID = PropsConfig.BackGumpID;
public static readonly int SetGumpID = PropsConfig.SetGumpID;
public static readonly int SetWidth = PropsConfig.SetWidth;
public static readonly int SetOffsetX = PropsConfig.SetOffsetX, SetOffsetY = PropsConfig.SetOffsetY /*+ (((EntryHeight - 20) / 2) / 2)*/;
public static readonly int SetButtonID1 = PropsConfig.SetButtonID1;
public static readonly int SetButtonID2 = PropsConfig.SetButtonID2;
public static readonly int PrevWidth = PropsConfig.PrevWidth;
public static readonly int PrevOffsetX = PropsConfig.PrevOffsetX, PrevOffsetY = PropsConfig.PrevOffsetY /*+ (((EntryHeight - 20) / 2) / 2)*/;
public static readonly int PrevButtonID1 = PropsConfig.PrevButtonID1;
public static readonly int PrevButtonID2 = PropsConfig.PrevButtonID2;
public static readonly int NextWidth = PropsConfig.NextWidth;
public static readonly int NextOffsetX = PropsConfig.NextOffsetX, NextOffsetY = PropsConfig.NextOffsetY /*+ (((EntryHeight - 20) / 2) / 2)*/;
public static readonly int NextButtonID1 = PropsConfig.NextButtonID1;
public static readonly int NextButtonID2 = PropsConfig.NextButtonID2;
public static readonly int OffsetSize = PropsConfig.OffsetSize;
public static readonly int EntryHeight = 24;//PropsConfig.EntryHeight;
public static readonly int BorderSize = PropsConfig.BorderSize;
private static bool PrevLabel = false, NextLabel = false;
private static readonly int PrevLabelOffsetX = PrevWidth + 1;
private static readonly int PrevLabelOffsetY = 0;
private static readonly int NextLabelOffsetX = -29;
private static readonly int NextLabelOffsetY = 0;
private static readonly int EntryWidth = 180;
private static readonly int EntryCount = 15;
private static readonly int TotalWidth = OffsetSize + EntryWidth + OffsetSize + SetWidth + OffsetSize;
private static readonly int TotalHeight = OffsetSize + ((EntryHeight + OffsetSize) * (EntryCount + 1));
private static readonly int BackWidth = BorderSize + TotalWidth + BorderSize;
private static readonly int BackHeight = BorderSize + TotalHeight + BorderSize;
private Mobile m_Owner;
private XmlAddCAGCategory m_Category;
private int m_Page;
private int m_Index = -1;
private Gump m_Gump;
private XmlSpawner m_Spawner;
public XmlCategorizedAddGump( Mobile owner, int index, Gump gump ) : this( owner, XmlAddCAGCategory.Root, 0, index, gump )
{
}
public XmlCategorizedAddGump( Mobile owner, XmlAddCAGCategory category, int page, int index, Gump gump ) : base( GumpOffsetX, GumpOffsetY )
{
if (category == null)
{
category = XmlAddCAGCategory.Root;
page = 0;
}
owner.CloseGump( typeof( WhoGump ) );
m_Owner = owner;
m_Category = category;
m_Index = index;
m_Gump = gump;
if(gump is XmlAddGump)
{
XmlAddGump xmladdgump = (XmlAddGump)gump;
if(xmladdgump != null && xmladdgump.defs != null)
{
xmladdgump.defs.CurrentCategory = category;
xmladdgump.defs.CurrentCategoryPage = page;
}
}
else
if(gump is XmlSpawnerGump)
{
m_Spawner = ((XmlSpawnerGump)gump).m_Spawner;
}
Initialize( page );
}
public void Initialize( int page )
{
m_Page = page;
XmlAddCAGNode[] nodes = m_Category.Nodes;
int count = nodes.Length - (page * EntryCount);
if ( count < 0 )
count = 0;
else if ( count > EntryCount )
count = EntryCount;
int totalHeight = OffsetSize + ((EntryHeight + OffsetSize) * (count + 1));
AddPage( 0 );
AddBackground( 0, 0, BackWidth, BorderSize + totalHeight + BorderSize, BackGumpID );
AddImageTiled( BorderSize, BorderSize, TotalWidth - (OldStyle ? SetWidth + OffsetSize : 0), totalHeight, OffsetGumpID );
int x = BorderSize + OffsetSize;
int y = BorderSize + OffsetSize;
if ( OldStyle )
AddImageTiled( x, y, TotalWidth - (OffsetSize * 3) - SetWidth, EntryHeight, HeaderGumpID );
else
AddImageTiled( x, y, PrevWidth, EntryHeight, HeaderGumpID );
if ( m_Category.Parent != null )
{
AddButton( x + PrevOffsetX, y + PrevOffsetY, PrevButtonID1, PrevButtonID2, 1, GumpButtonType.Reply, 0 );
if ( PrevLabel )
AddLabel( x + PrevLabelOffsetX, y + PrevLabelOffsetY, TextHue, "Previous" );
}
x += PrevWidth + OffsetSize;
int emptyWidth = TotalWidth - (PrevWidth * 2) - NextWidth - (OffsetSize * 5) - (OldStyle ? SetWidth + OffsetSize : 0);
if ( !OldStyle )
AddImageTiled( x - (OldStyle ? OffsetSize : 0), y, emptyWidth + (OldStyle ? OffsetSize * 2 : 0), EntryHeight, EntryGumpID );
AddHtml( x + TextOffsetX, y + ((EntryHeight - 20) / 2), emptyWidth - TextOffsetX, EntryHeight, String.Format( "<center>{0}</center>", m_Category.Caption ), false, false );
x += emptyWidth + OffsetSize;
if ( OldStyle )
AddImageTiled( x, y, TotalWidth - (OffsetSize * 3) - SetWidth, EntryHeight, HeaderGumpID );
else
AddImageTiled( x, y, PrevWidth, EntryHeight, HeaderGumpID );
if ( page > 0 )
{
AddButton( x + PrevOffsetX, y + PrevOffsetY, PrevButtonID1, PrevButtonID2, 2, GumpButtonType.Reply, 0 );
if ( PrevLabel )
AddLabel( x + PrevLabelOffsetX, y + PrevLabelOffsetY, TextHue, "Previous" );
}
x += PrevWidth + OffsetSize;
if ( !OldStyle )
AddImageTiled( x, y, NextWidth, EntryHeight, HeaderGumpID );
if ( (page + 1) * EntryCount < nodes.Length )
{
AddButton( x + NextOffsetX, y + NextOffsetY, NextButtonID1, NextButtonID2, 3, GumpButtonType.Reply, 1 );
if ( NextLabel )
AddLabel( x + NextLabelOffsetX, y + NextLabelOffsetY, TextHue, "Next" );
}
for ( int i = 0, index = page * EntryCount; i < EntryCount && index < nodes.Length; ++i, ++index )
{
x = BorderSize + OffsetSize;
y += EntryHeight + OffsetSize;
XmlAddCAGNode node = nodes[index];
AddImageTiled( x, y, EntryWidth, EntryHeight, EntryGumpID );
AddLabelCropped( x + TextOffsetX, y + ((EntryHeight - 20) / 2), EntryWidth - TextOffsetX, EntryHeight, TextHue, node.Caption );
x += EntryWidth + OffsetSize;
if ( SetGumpID != 0 )
AddImageTiled( x, y, SetWidth, EntryHeight, SetGumpID );
AddButton( x + SetOffsetX, y + SetOffsetY, SetButtonID1, SetButtonID2, i + 4, GumpButtonType.Reply, 0 );
if ( node is XmlAddCAGObject )
{
XmlAddCAGObject obj = (XmlAddCAGObject)node;
int itemID = obj.ItemID;
Rectangle2D bounds = ItemBounds.Table[itemID];
if ( itemID != 1 && bounds.Height < (EntryHeight * 2) )
{
if ( bounds.Height < EntryHeight )
AddItem( x - OffsetSize - 22 - ((i % 2) * 44) - (bounds.Width / 2) - bounds.X, y + (EntryHeight / 2) - (bounds.Height / 2) - bounds.Y, itemID );
else
AddItem( x - OffsetSize - 22 - ((i % 2) * 44) - (bounds.Width / 2) - bounds.X, y + EntryHeight - 1 - bounds.Height - bounds.Y, itemID );
}
}
}
}
public override void OnResponse( NetState state, RelayInfo info )
{
Mobile from = m_Owner;
switch ( info.ButtonID )
{
case 0: // Closed
{
return;
}
case 1: // Up
{
if ( m_Category.Parent != null )
{
int index = Array.IndexOf( m_Category.Parent.Nodes, m_Category ) / EntryCount;
if ( index < 0 )
index = 0;
from.SendGump( new XmlCategorizedAddGump( from, m_Category.Parent, index, m_Index, m_Gump ) );
}
break;
}
case 2: // Previous
{
if ( m_Page > 0 )
from.SendGump( new XmlCategorizedAddGump( from, m_Category, m_Page - 1, m_Index, m_Gump ) );
break;
}
case 3: // Next
{
if ( (m_Page + 1) * EntryCount < m_Category.Nodes.Length )
from.SendGump( new XmlCategorizedAddGump( from, m_Category, m_Page + 1, m_Index, m_Gump ) );
break;
}
default:
{
int index = (m_Page * EntryCount) + (info.ButtonID - 4);
if ( index >= 0 && index < m_Category.Nodes.Length )
{
m_Category.Nodes[index].OnClick( from, m_Page, m_Index, m_Gump );
}
break;
}
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,267 @@
using System;
using System.Collections;
using System.Reflection;
using Server;
using Server.Targeting;
using Server.Engines.XmlSpawner2;
using Server.Mobiles;
/*
** Modified from RunUO 1.0.0 AddGump.cs
** by ArteGordon
** 3/13/05
*/
namespace Server.Gumps
{
public class XmlPartialCategorizedAddGump : Gump
{
private string m_SearchString;
private ArrayList m_SearchResults;
private int m_Page;
private Gump m_Gump;
private int m_EntryIndex = -1;
private XmlSpawner m_Spawner;
public XmlPartialCategorizedAddGump( Mobile from, string searchString, int page, ArrayList searchResults, bool explicitSearch, int entryindex, Gump gump ) : base( 50, 50 )
{
if(gump is XmlSpawnerGump)
{
// keep track of the spawner for xmlspawnergumps
m_Spawner = ((XmlSpawnerGump)gump).m_Spawner;
}
// keep track of the gump
m_Gump = gump;
m_SearchString = searchString;
m_SearchResults = searchResults;
m_Page = page;
m_EntryIndex = entryindex;
from.CloseGump( typeof( XmlPartialCategorizedAddGump ) );
AddPage( 0 );
AddBackground( 0, 0, 420, 280, 5054 );
AddImageTiled( 10, 10, 400, 20, 2624 );
AddAlphaRegion( 10, 10, 400, 20 );
AddImageTiled( 41, 11, 184, 18, 0xBBC );
AddImageTiled( 42, 12, 182, 16, 2624 );
AddAlphaRegion( 42, 12, 182, 16 );
AddButton( 10, 9, 4011, 4013, 1, GumpButtonType.Reply, 0 );
AddTextEntry( 44, 10, 180, 20, 0x480, 0, searchString );
AddHtmlLocalized( 230, 10, 100, 20, 3010005, 0x7FFF, false, false );
AddImageTiled( 10, 40, 400, 200, 2624 );
AddAlphaRegion( 10, 40, 400, 200 );
if ( searchResults.Count > 0 )
{
for ( int i = (page * 10); i < ((page + 1) * 10) && i < searchResults.Count; ++i )
{
int index = i % 10;
SearchEntry se = (SearchEntry)searchResults[i];
string labelstr = se.EntryType.Name;
if(se.Parameters.Length > 0)
{
for(int j = 0; j < se.Parameters.Length;j++)
{
labelstr += ", " + se.Parameters[j].Name;
}
}
AddLabel( 44, 39 + (index * 20), 0x480, labelstr );
AddButton( 10, 39 + (index * 20), 4023, 4025, 4 + i, GumpButtonType.Reply, 0 );
}
}
else
{
AddLabel( 15, 44, 0x480, explicitSearch ? "Nothing matched your search terms." : "No results to display." );
}
AddImageTiled( 10, 250, 400, 20, 2624 );
AddAlphaRegion( 10, 250, 400, 20 );
if ( m_Page > 0 )
AddButton( 10, 249, 4014, 4016, 2, GumpButtonType.Reply, 0 );
else
AddImage( 10, 249, 4014 );
AddHtmlLocalized( 44, 250, 170, 20, 1061028, m_Page > 0 ? 0x7FFF : 0x5EF7, false, false ); // Previous page
if ( ((m_Page + 1) * 10) < searchResults.Count )
AddButton( 210, 249, 4005, 4007, 3, GumpButtonType.Reply, 0 );
else
AddImage( 210, 249, 4005 );
AddHtmlLocalized( 244, 250, 170, 20, 1061027, ((m_Page + 1) * 10) < searchResults.Count ? 0x7FFF : 0x5EF7, false, false ); // Next page
}
private static Type typeofItem = typeof( Item ), typeofMobile = typeof( Mobile );
private class SearchEntry
{
public Type EntryType;
public ParameterInfo [] Parameters;
public SearchEntry()
{
}
}
private static void Match( string match, Type[] types, ArrayList results )
{
if ( match.Length == 0 )
return;
match = match.ToLower();
for ( int i = 0; i < types.Length; ++i )
{
Type t = types[i];
if ( (typeofMobile.IsAssignableFrom( t ) || typeofItem.IsAssignableFrom( t )) && t.Name.ToLower().IndexOf( match ) >= 0 && !results.Contains( t ) )
{
ConstructorInfo[] ctors = t.GetConstructors();
for ( int j = 0; j < ctors.Length; ++j )
{
if ( /*ctors[j].GetParameters().Length == 0 && */ ctors[j].IsDefined( typeof( ConstructableAttribute ), false ) )
{
SearchEntry s = new SearchEntry();
s.EntryType = t;
s.Parameters = ctors[j].GetParameters();
//results.Add( t );
results.Add( s );
//break;
}
}
}
}
}
public static ArrayList Match( string match )
{
ArrayList results = new ArrayList();
Type[] types;
Assembly[] asms = ScriptCompiler.Assemblies;
for ( int i = 0; i < asms.Length; ++i )
{
types = ScriptCompiler.GetTypeCache( asms[i] ).Types;
Match( match, types, results );
}
types = ScriptCompiler.GetTypeCache( Core.Assembly ).Types;
Match( match, types, results );
results.Sort( new TypeNameComparer() );
return results;
}
private class TypeNameComparer : IComparer
{
public int Compare( object x, object y )
{
SearchEntry a = x as SearchEntry;
SearchEntry b = y as SearchEntry;
return a.EntryType.Name.CompareTo( b.EntryType.Name );
}
}
public override void OnResponse( Server.Network.NetState sender, RelayInfo info )
{
Mobile from = sender.Mobile;
switch ( info.ButtonID )
{
case 1: // Search
{
TextRelay te = info.GetTextEntry( 0 );
string match = ( te == null ? "" : te.Text.Trim() );
if ( match.Length < 3 )
{
from.SendMessage( "Invalid search string." );
from.SendGump( new XmlPartialCategorizedAddGump( from, match, m_Page, m_SearchResults, false, m_EntryIndex, m_Gump ) );
}
else
{
from.SendGump( new XmlPartialCategorizedAddGump( from, match, 0, Match( match ) , true, m_EntryIndex, m_Gump ) );
}
break;
}
case 2: // Previous page
{
if ( m_Page > 0 )
from.SendGump( new XmlPartialCategorizedAddGump( from, m_SearchString, m_Page - 1, m_SearchResults, true, m_EntryIndex, m_Gump ) );
break;
}
case 3: // Next page
{
if ( (m_Page + 1) * 10 < m_SearchResults.Count )
from.SendGump( new XmlPartialCategorizedAddGump( from, m_SearchString, m_Page + 1, m_SearchResults, true, m_EntryIndex, m_Gump ) );
break;
}
default:
{
int index = info.ButtonID - 4;
if ( index >= 0 && index < m_SearchResults.Count )
{
Type type = ((SearchEntry)m_SearchResults[index]).EntryType;
if(m_Gump is XmlAddGump && type != null)
{
XmlAddGump m_XmlAddGump = (XmlAddGump)m_Gump;
if(type != null && m_XmlAddGump.defs != null && m_XmlAddGump.defs.NameList != null &&
m_EntryIndex >= 0 && m_EntryIndex < m_XmlAddGump.defs.NameList.Length)
{
m_XmlAddGump.defs.NameList[m_EntryIndex] = type.Name;
XmlAddGump.Refresh(from, true);
}
}
else
if(m_Spawner != null && type != null)
{
XmlSpawnerGump xg = m_Spawner.SpawnerGump;
if(xg != null)
{
xg.Rentry = new XmlSpawnerGump.ReplacementEntry();
xg.Rentry.Typename = type.Name;
xg.Rentry.Index = m_EntryIndex;
xg.Rentry.Color = 0x1436;
Timer.DelayCall( TimeSpan.Zero, new TimerStateCallback( XmlSpawnerGump.Refresh_Callback ), new object[]{ from } );
//from.CloseGump(typeof(XmlSpawnerGump));
//from.SendGump( new XmlSpawnerGump(xg.m_Spawner, xg.X, xg.Y, xg.m_ShowGump, xg.xoffset, xg.page, xg.Rentry) );
}
}
}
break;
}
}
}
}
}