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