#W# Initial Commit: Avatars Conquest

This commit is contained in:
WarrentyExpired 2026-07-04 10:35:30 -04:00
commit 5df497787a
7510 changed files with 416048 additions and 0 deletions

View file

@ -0,0 +1,99 @@
using System;
using Server;
using Server.Mobiles;
using Server.Spells;
using System.Collections;
using System.Collections.Generic;
namespace Server.Items
{
public class AcidSlime : Item
{
private TimeSpan m_Duration;
private int m_MinDamage;
private int m_MaxDamage;
private DateTime m_Created;
private bool m_Drying;
private Timer m_Timer;
[Constructable]
public AcidSlime() : this( TimeSpan.FromSeconds( 10.0 ), 5, 10 )
{
}
public override string DefaultName { get { return "slime"; } }
[Constructable]
public AcidSlime( TimeSpan duration, int minDamage, int maxDamage )
: base( 0x122A )
{
Hue = 0x3F;
Movable = false;
m_MinDamage = minDamage;
m_MaxDamage = maxDamage;
m_Created = DateTime.Now;
m_Duration = duration;
m_Timer = Timer.DelayCall( TimeSpan.Zero, TimeSpan.FromSeconds( 1 ), new TimerCallback( OnTick ) );
}
public override void OnAfterDelete()
{
if( m_Timer != null )
m_Timer.Stop();
}
private void OnTick()
{
DateTime now = DateTime.Now;
TimeSpan age = now - m_Created;
if( age > m_Duration ) {
Delete();
} else {
if( !m_Drying && age > (m_Duration - age) )
{
m_Drying = true;
ItemID = 0x122B;
}
List<Mobile> toDamage = new List<Mobile>();
foreach( Mobile m in GetMobilesInRange( 0 ) )
{
BaseCreature bc = m as BaseCreature;
if( m.Alive && !m.IsDeadBondedPet && (bc == null || bc.Controlled || bc.Summoned) )
{
toDamage.Add( m );
}
}
for ( int i = 0; i < toDamage.Count; i++ )
Damage( toDamage[i] );
}
}
public override bool OnMoveOver( Mobile m )
{
Damage( m );
return true;
}
public void Damage ( Mobile m )
{
int damage = Utility.RandomMinMax( m_MinDamage, m_MaxDamage );
m.Damage( damage );
}
public AcidSlime( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
}
public override void Deserialize( GenericReader reader )
{
}
}
}

View file

@ -0,0 +1,228 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Misc;
using Server.Targeting;
namespace Server.Items
{
public class ArcaneGem : Item
{
public override string DefaultName
{
get { return "arcane gem"; }
}
[Constructable]
public ArcaneGem() : base( 0x1EA7 )
{
Stackable = false;
Weight = 1.0;
}
public ArcaneGem( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
if ( !IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
}
else
{
from.BeginTarget( 2, false, TargetFlags.None, new TargetCallback( OnTarget ) );
from.SendMessage( "What do you wish to use the gem on?" );
}
}
public int GetChargesFor( Mobile m )
{
int v = (int)(Server.Misc.SkillCheck.TradeSkill( m, Trades.Tailoring, false ) / 5);
if ( v < 16 )
return 16;
else if ( v > 24 )
return 24;
return v;
}
public const int DefaultArcaneHue = 2117;
public void OnTarget( Mobile from, object obj )
{
if ( !IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
return;
}
if ( obj is IArcaneEquip && obj is Item )
{
Item item = (Item)obj;
CraftResource resource = CraftResource.None;
if( item is BaseClothing )
resource = ((BaseClothing)item).Resource;
else if( item is BaseArmor )
resource = ((BaseArmor)item).Resource;
else if( item is BaseWeapon ) // Sanity, weapons cannot recieve gems...
resource = ((BaseWeapon)item).Resource;
IArcaneEquip eq = (IArcaneEquip)obj;
if ( !item.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
return;
}
else if ( resource != CraftResource.None && resource != CraftResource.Leathered )
{
from.SendLocalizedMessage( 1049690 ); // Arcane gems can not be used on that type of leather.
return;
}
int charges = GetChargesFor( from );
if ( eq.IsArcane )
{
if ( eq.CurArcaneCharges >= eq.MaxArcaneCharges )
{
from.SendMessage( "That item is already fully charged." );
}
else
{
if ( eq.CurArcaneCharges <= 0 )
item.Hue = DefaultArcaneHue;
if ( (eq.CurArcaneCharges + charges) > eq.MaxArcaneCharges )
eq.CurArcaneCharges = eq.MaxArcaneCharges;
else
eq.CurArcaneCharges += charges;
from.SendMessage( "You recharge the item." );
if ( Amount <= 1 )
Delete();
else Amount--;
}
}
else if ( Server.Misc.SkillCheck.TradeSkill( from, Trades.Tailoring, false ) >= 80.0 )
{
bool isExceptional = false;
if ( item is BaseClothing )
isExceptional = ( ((BaseClothing)item).Quality == ClothingQuality.Exceptional );
else if ( item is BaseArmor )
isExceptional = ( ((BaseArmor)item).Quality == ArmorQuality.Exceptional );
else if ( item is BaseWeapon )
isExceptional = ( ((BaseWeapon)item).Quality == WeaponQuality.Exceptional );
if ( isExceptional )
{
if ( item is BaseClothing )
{
((BaseClothing)item).Quality = ClothingQuality.Regular;
((BaseClothing)item).Crafter = from;
}
else if ( item is BaseArmor )
{
((BaseArmor)item).Quality = ArmorQuality.Regular;
((BaseArmor)item).Crafter = from;
}
else if ( item is BaseWeapon ) // Sanity, weapons cannot recieve gems...
{
((BaseWeapon)item).Quality = WeaponQuality.Regular;
((BaseWeapon)item).Crafter = from;
}
eq.CurArcaneCharges = eq.MaxArcaneCharges = charges;
item.Hue = DefaultArcaneHue;
from.SendMessage( "You enhance the item with your gem." );
if ( Amount <= 1 )
Delete();
else Amount--;
}
else
{
from.SendMessage( "Only exceptional items can be enhanced with the gem." );
}
}
else
{
from.SendMessage( "You do not have enough skill in tailoring to enhance the item." );
}
}
else
{
from.SendMessage( "You can only use this on exceptionally crafted robes, thigh boots, cloaks, or leather gloves." );
}
}
public static bool ConsumeCharges( Mobile from, int amount )
{
List<Item> items = from.Items;
int avail = 0;
for ( int i = 0; i < items.Count; ++i )
{
Item obj = items[i];
if ( obj is IArcaneEquip )
{
IArcaneEquip eq = (IArcaneEquip)obj;
if ( eq.IsArcane )
avail += eq.CurArcaneCharges;
}
}
if ( avail < amount )
return false;
for ( int i = 0; i < items.Count; ++i )
{
Item obj = items[i];
if ( obj is IArcaneEquip )
{
IArcaneEquip eq = (IArcaneEquip)obj;
if ( eq.IsArcane )
{
if ( eq.CurArcaneCharges > amount )
{
eq.CurArcaneCharges -= amount;
break;
}
else
{
amount -= eq.CurArcaneCharges;
eq.CurArcaneCharges = 0;
}
}
}
}
return true;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,40 @@
using System;
namespace Server.Items
{
public class Beeswax : Item
{
[Constructable]
public Beeswax() : this( 1 )
{
}
[Constructable]
public Beeswax( int amount ) : base( 0x1422 )
{
Weight = 1.0;
Stackable = true;
Amount = amount;
}
public Beeswax( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,106 @@
using System;
using Server;
using Server.Network;
namespace Server.Items
{
public class Blocker : Item
{
public override int LabelNumber{ get{ return 503057; } } // Impassable!
[Constructable]
public Blocker() : base( 0x21A4 )
{
Movable = false;
}
public Blocker( Serial serial ) : base( serial )
{
}
protected override Packet GetWorldPacketFor( NetState state ) {
Mobile mob = state.Mobile;
if ( mob != null && mob.AccessLevel >= AccessLevel.GameMaster )
return new GMItemPacket( this );
return base.GetWorldPacketFor( state );
}
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 sealed class GMItemPacket : Packet
{
public GMItemPacket( Item item ) : base( 0x1A )
{
this.EnsureCapacity( 20 );
// 14 base length
// +2 - Amount
// +2 - Hue
// +1 - Flags
uint serial = (uint)item.Serial.Value;
int itemID = 0x1183;
int amount = item.Amount;
Point3D loc = item.Location;
int x = loc.X;
int y = loc.Y;
int hue = item.Hue;
int flags = item.GetPacketFlags();
int direction = (int)item.Direction;
if ( amount != 0 )
serial |= 0x80000000;
else
serial &= 0x7FFFFFFF;
m_Stream.Write( (uint) serial );
m_Stream.Write( (short) (itemID & 0x7FFF) );
if ( amount != 0 )
m_Stream.Write( (short) amount );
x &= 0x7FFF;
if ( direction != 0 )
x |= 0x8000;
m_Stream.Write( (short) x );
y &= 0x3FFF;
if ( hue != 0 )
y |= 0x8000;
if ( flags != 0 )
y |= 0x4000;
m_Stream.Write( (short) y );
if ( direction != 0 )
m_Stream.Write( (byte) direction );
m_Stream.Write( (sbyte) loc.Z );
if ( hue != 0 )
m_Stream.Write( (ushort) hue );
if ( flags != 0 )
m_Stream.Write( (byte) flags );
}
}
}
}

View file

@ -0,0 +1,57 @@
using System;
using Server;
namespace Server.Items
{
public class Blood : Item
{
[Constructable]
public Blood() : this( Utility.RandomList( 0x1645, 0x122A, 0x122B, 0x122C, 0x122D, 0x122E, 0x122F ))
{
}
[Constructable]
public Blood( int itemID ) : base( itemID )
{
Movable = false;
new InternalTimer( this ).Start();
}
public Blood( Serial serial ) : base( serial )
{
new InternalTimer( this ).Start();
}
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();
}
private class InternalTimer : Timer
{
private Item m_Blood;
public InternalTimer( Item blood ) : base( TimeSpan.FromSeconds( 5.0 ) )
{
Priority = TimerPriority.OneSecond;
m_Blood = blood;
}
protected override void OnTick()
{
m_Blood.Delete();
}
}
}
}

View file

@ -0,0 +1,620 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Server;
using Server.Network;
namespace Server.Items
{
[Flipable( 0x1E5E, 0x1E5F )]
public class BulletinBoard : BaseBulletinBoard
{
[Constructable]
public BulletinBoard() : base( 0x1E5E )
{
}
public BulletinBoard( 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 abstract class BaseBulletinBoard : Item
{
private string m_BoardName;
[CommandProperty( AccessLevel.GameMaster )]
public string BoardName
{
get{ return m_BoardName; }
set{ m_BoardName = value; }
}
public BaseBulletinBoard( int itemID ) : base( itemID )
{
m_BoardName = "bulletin board";
Movable = false;
}
// Threads will be removed six hours after the last post was made
private static TimeSpan ThreadDeletionTime = TimeSpan.FromHours( 6.0 );
// A player may only create a thread once every two minutes
private static TimeSpan ThreadCreateTime = TimeSpan.FromMinutes( 2.0 );
// A player may only reply once every thirty seconds
private static TimeSpan ThreadReplyTime = TimeSpan.FromSeconds( 30.0 );
public static bool CheckTime( DateTime time, TimeSpan range )
{
return (time + range) < DateTime.Now;
}
public static string FormatTS( TimeSpan ts )
{
int totalSeconds = (int)ts.TotalSeconds;
int seconds = totalSeconds % 60;
int minutes = totalSeconds / 60;
if ( minutes != 0 && seconds != 0 )
return String.Format( "{0} minute{1} and {2} second{3}", minutes, minutes==1?"":"s", seconds, seconds==1?"":"s" );
else if ( minutes != 0 )
return String.Format( "{0} minute{1}", minutes, minutes==1?"":"s" );
else
return String.Format( "{0} second{1}", seconds, seconds==1?"":"s" );
}
public virtual void Cleanup()
{
List<Item> items = this.Items;
for ( int i = items.Count - 1; i >= 0; --i )
{
if ( i >= items.Count )
continue;
BulletinMessage msg = items[i] as BulletinMessage;
if ( msg == null )
continue;
if ( msg.Thread == null && CheckTime( msg.LastPostTime, ThreadDeletionTime ) )
{
msg.Delete();
RecurseDelete( msg ); // A root-level thread has expired
}
}
}
private void RecurseDelete( BulletinMessage msg )
{
List<Item> found = new List<Item>();
List<Item> items = this.Items;
for ( int i = items.Count - 1; i >= 0; --i )
{
if ( i >= items.Count )
continue;
BulletinMessage check = items[i] as BulletinMessage;
if ( check == null )
continue;
if ( check.Thread == msg )
{
check.Delete();
found.Add( check );
}
}
for ( int i = 0; i < found.Count; ++i )
RecurseDelete( (BulletinMessage)found[i] );
}
public virtual bool GetLastPostTime( Mobile poster, bool onlyCheckRoot, ref DateTime lastPostTime )
{
List<Item> items = this.Items;
bool wasSet = false;
for ( int i = 0; i < items.Count; ++i )
{
BulletinMessage msg = items[i] as BulletinMessage;
if ( msg == null || msg.Poster != poster )
continue;
if ( onlyCheckRoot && msg.Thread != null )
continue;
if ( msg.Time > lastPostTime )
{
wasSet = true;
lastPostTime = msg.Time;
}
}
return wasSet;
}
public override void OnDoubleClick( Mobile from )
{
if ( CheckRange( from ) )
{
Cleanup();
NetState state = from.NetState;
state.Send( new BBDisplayBoard( this ) );
if ( state.ContainerGridLines )
state.Send( new ContainerContent6017( from, this ) );
else
state.Send( new ContainerContent( from, this ) );
}
else
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
}
}
public virtual bool CheckRange( Mobile from )
{
if ( from.AccessLevel >= AccessLevel.GameMaster )
return true;
return ( from.Map == this.Map && from.InRange( GetWorldLocation(), 2 ) );
}
public void PostMessage( Mobile from, BulletinMessage thread, string subject, string[] lines )
{
if ( thread != null )
thread.LastPostTime = DateTime.Now;
AddItem( new BulletinMessage( from, thread, subject, lines ) );
}
public BaseBulletinBoard( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (string) m_BoardName );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_BoardName = reader.ReadString();
break;
}
}
}
public static void Initialize()
{
PacketHandlers.Register( 0x71, 0, true, new OnPacketReceive( BBClientRequest ) );
}
public static void BBClientRequest( NetState state, PacketReader pvSrc )
{
Mobile from = state.Mobile;
int packetID = pvSrc.ReadByte();
BaseBulletinBoard board = World.FindItem( pvSrc.ReadInt32() ) as BaseBulletinBoard;
if ( board == null || !board.CheckRange( from ) )
return;
switch ( packetID )
{
case 3: BBRequestContent( from, board, pvSrc ); break;
case 4: BBRequestHeader( from, board, pvSrc ); break;
case 5: BBPostMessage( from, board, pvSrc ); break;
case 6: BBRemoveMessage( from, board, pvSrc ); break;
}
}
public static void BBRequestContent( Mobile from, BaseBulletinBoard board, PacketReader pvSrc )
{
BulletinMessage msg = World.FindItem( pvSrc.ReadInt32() ) as BulletinMessage;
if ( msg == null || msg.Parent != board )
return;
from.Send( new BBMessageContent( board, msg ) );
}
public static void BBRequestHeader( Mobile from, BaseBulletinBoard board, PacketReader pvSrc )
{
BulletinMessage msg = World.FindItem( pvSrc.ReadInt32() ) as BulletinMessage;
if ( msg == null || msg.Parent != board )
return;
from.Send( new BBMessageHeader( board, msg ) );
}
public static void BBPostMessage( Mobile from, BaseBulletinBoard board, PacketReader pvSrc )
{
BulletinMessage thread = World.FindItem( pvSrc.ReadInt32() ) as BulletinMessage;
if ( thread != null && thread.Parent != board )
thread = null;
int breakout = 0;
while ( thread != null && thread.Thread != null && breakout++ < 10 )
thread = thread.Thread;
DateTime lastPostTime = DateTime.MinValue;
if ( board.GetLastPostTime( from, ( thread == null ), ref lastPostTime ) )
{
if ( !CheckTime( lastPostTime, (thread == null ? ThreadCreateTime : ThreadReplyTime) ) )
{
if ( thread == null )
from.SendMessage( "You must wait {0} before creating a new thread.", FormatTS( ThreadCreateTime ) );
else
from.SendMessage( "You must wait {0} before replying to another thread.", FormatTS( ThreadReplyTime ) );
return;
}
}
string subject = pvSrc.ReadUTF8StringSafe( pvSrc.ReadByte() );
if ( subject.Length == 0 )
return;
string[] lines = new string[pvSrc.ReadByte()];
if ( lines.Length == 0 )
return;
for ( int i = 0; i < lines.Length; ++i )
lines[i] = pvSrc.ReadUTF8StringSafe( pvSrc.ReadByte() );
board.PostMessage( from, thread, subject, lines );
}
public static void BBRemoveMessage( Mobile from, BaseBulletinBoard board, PacketReader pvSrc )
{
BulletinMessage msg = World.FindItem( pvSrc.ReadInt32() ) as BulletinMessage;
if ( msg == null || msg.Parent != board )
return;
if ( from.AccessLevel < AccessLevel.GameMaster && msg.Poster != from )
return;
msg.Delete();
}
}
public struct BulletinEquip
{
public int itemID;
public int hue;
public BulletinEquip( int itemID, int hue )
{
this.itemID = itemID;
this.hue = hue;
}
}
public class BulletinMessage : Item
{
private Mobile m_Poster;
private string m_Subject;
private DateTime m_Time, m_LastPostTime;
private BulletinMessage m_Thread;
private string m_PostedName;
private int m_PostedBody;
private int m_PostedHue;
private BulletinEquip[] m_PostedEquip;
private string[] m_Lines;
public string GetTimeAsString()
{
return m_Time.ToString( "MMM dd, yyyy" );
}
public override bool CheckTarget( Mobile from, Server.Targeting.Target targ, object targeted )
{
return false;
}
public override bool IsAccessibleTo( Mobile check )
{
return false;
}
public BulletinMessage( Mobile poster, BulletinMessage thread, string subject, string[] lines ) : base( 0xEB0 )
{
Movable = false;
m_Poster = poster;
m_Subject = subject;
m_Time = DateTime.Now;
m_LastPostTime = m_Time;
m_Thread = thread;
m_PostedName = m_Poster.Name;
m_PostedBody = m_Poster.Body;
m_PostedHue = m_Poster.Hue;
m_Lines = lines;
List<BulletinEquip> list = new List<BulletinEquip>();
for ( int i = 0; i < poster.Items.Count; ++i )
{
Item item = poster.Items[i];
if ( item.Layer >= Layer.OneHanded && item.Layer <= Layer.Mount )
list.Add( new BulletinEquip( item.ItemID, item.Hue ) );
}
m_PostedEquip = list.ToArray();
}
public Mobile Poster{ get{ return m_Poster; } }
public BulletinMessage Thread{ get{ return m_Thread; } }
public string Subject{ get{ return m_Subject; } }
public DateTime Time{ get{ return m_Time; } }
public DateTime LastPostTime{ get{ return m_LastPostTime; } set{ m_LastPostTime = value; } }
public string PostedName{ get{ return m_PostedName; } }
public int PostedBody{ get{ return m_PostedBody; } }
public int PostedHue{ get{ return m_PostedHue; } }
public BulletinEquip[] PostedEquip{ get{ return m_PostedEquip; } }
public string[] Lines{ get{ return m_Lines; } }
public BulletinMessage( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (Mobile) m_Poster );
writer.Write( (string) m_Subject );
writer.Write( (DateTime) m_Time );
writer.Write( (DateTime) m_LastPostTime );
writer.Write( (bool) (m_Thread != null) );
writer.Write( (Item) m_Thread );
writer.Write( (string) m_PostedName );
writer.Write( (int) m_PostedBody );
writer.Write( (int) m_PostedHue );
writer.Write( (int) m_PostedEquip.Length );
for ( int i = 0; i < m_PostedEquip.Length; ++i )
{
writer.Write( (int) m_PostedEquip[i].itemID );
writer.Write( (int) m_PostedEquip[i].hue );
}
writer.Write( (int) m_Lines.Length );
for ( int i = 0; i < m_Lines.Length; ++i )
writer.Write( (string) m_Lines[i] );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Poster = reader.ReadMobile();
m_Subject = reader.ReadString();
m_Time = reader.ReadDateTime();
m_LastPostTime = reader.ReadDateTime();
bool hasThread = reader.ReadBool();
m_Thread = reader.ReadItem() as BulletinMessage;
m_PostedName = reader.ReadString();
m_PostedBody = reader.ReadInt();
m_PostedHue = reader.ReadInt();
m_PostedEquip = new BulletinEquip[reader.ReadInt()];
for ( int i = 0; i < m_PostedEquip.Length; ++i )
{
m_PostedEquip[i].itemID = reader.ReadInt();
m_PostedEquip[i].hue = reader.ReadInt();
}
m_Lines = new string[reader.ReadInt()];
for ( int i = 0; i < m_Lines.Length; ++i )
m_Lines[i] = reader.ReadString();
if ( hasThread && m_Thread == null )
Delete();
break;
}
}
}
}
public class BBDisplayBoard : Packet
{
public BBDisplayBoard( BaseBulletinBoard board ) : base( 0x71 )
{
string name = board.BoardName;
if ( name == null )
name = "";
EnsureCapacity( 38 );
byte[] buffer = Utility.UTF8.GetBytes( name );
m_Stream.Write( (byte) 0x00 ); // PacketID
m_Stream.Write( (int) board.Serial ); // Bulletin board serial
// Bulletin board name
if ( buffer.Length >= 29 )
{
m_Stream.Write( buffer, 0, 29 );
m_Stream.Write( (byte) 0 );
}
else
{
m_Stream.Write( buffer, 0, buffer.Length );
m_Stream.Fill( 30 - buffer.Length );
}
}
}
public class BBMessageHeader : Packet
{
public BBMessageHeader( BaseBulletinBoard board, BulletinMessage msg ) : base( 0x71 )
{
string poster = SafeString( msg.PostedName );
string subject = SafeString( msg.Subject );
string time = SafeString( msg.GetTimeAsString() );
EnsureCapacity( 22 + poster.Length + subject.Length + time.Length );
m_Stream.Write( (byte) 0x01 ); // PacketID
m_Stream.Write( (int) board.Serial ); // Bulletin board serial
m_Stream.Write( (int) msg.Serial ); // Message serial
BulletinMessage thread = msg.Thread;
if ( thread == null )
m_Stream.Write( (int) 0 ); // Thread serial--root
else
m_Stream.Write( (int) thread.Serial ); // Thread serial--parent
WriteString( poster );
WriteString( subject );
WriteString( time );
}
public void WriteString( string v )
{
byte[] buffer = Utility.UTF8.GetBytes( v );
int len = buffer.Length + 1;
if ( len > 255 )
len = 255;
m_Stream.Write( (byte) len );
m_Stream.Write( buffer, 0, len-1 );
m_Stream.Write( (byte) 0 );
}
public string SafeString( string v )
{
if ( v == null )
return String.Empty;
return v;
}
}
public class BBMessageContent : Packet
{
public BBMessageContent( BaseBulletinBoard board, BulletinMessage msg ) : base( 0x71 )
{
string poster = SafeString( msg.PostedName );
string subject = SafeString( msg.Subject );
string time = SafeString( msg.GetTimeAsString() );
EnsureCapacity( 22 + poster.Length + subject.Length + time.Length );
m_Stream.Write( (byte) 0x02 ); // PacketID
m_Stream.Write( (int) board.Serial ); // Bulletin board serial
m_Stream.Write( (int) msg.Serial ); // Message serial
WriteString( poster );
WriteString( subject );
WriteString( time );
m_Stream.Write( (short) msg.PostedBody );
m_Stream.Write( (short) msg.PostedHue );
int len = msg.PostedEquip.Length;
if ( len > 255 )
len = 255;
m_Stream.Write( (byte) len );
for ( int i = 0; i < len; ++i )
{
BulletinEquip eq = msg.PostedEquip[i];
m_Stream.Write( (short) eq.itemID );
m_Stream.Write( (short) eq.hue );
}
len = msg.Lines.Length;
if ( len > 255 )
len = 255;
m_Stream.Write( (byte) len );
for ( int i = 0; i < len; ++i )
WriteString( msg.Lines[i] );
}
public void WriteString( string v )
{
byte[] buffer = Utility.UTF8.GetBytes( v );
int len = buffer.Length + 1;
if ( len > 255 )
len = 255;
m_Stream.Write( (byte) len );
m_Stream.Write( buffer, 0, len-1 );
m_Stream.Write( (byte) 0 );
}
public string SafeString( string v )
{
if ( v == null )
return String.Empty;
return v;
}
}
}

View file

@ -0,0 +1,904 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.ContextMenus;
using Server.Engines.PartySystem;
using Server.Guilds;
using Server.Misc;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
{
public interface IDevourer
{
bool Devour( Corpse corpse );
}
[Flags]
public enum CorpseFlag
{
None = 0x00000000,
/// <summary>
/// Has this corpse been carved?
/// </summary>
Carved = 0x00000001,
/// <summary>
/// If true, this corpse will not turn into bones
/// </summary>
NoBones = 0x00000002,
/// <summary>
/// If true, the corpse has turned into bones
/// </summary>
IsBones = 0x00000004,
/// <summary>
/// Has this corpse yet been visited by a taxidermist?
/// </summary>
VisitedByTaxidermist = 0x00000008,
/// <summary>
/// Was the owner criminal when he died?
/// </summary>
Criminal = 0x00000010,
/// <summary>
/// Has this corpse been animated?
/// </summary>
Animated = 0x00000020,
}
public class Corpse : Container, ICarvable
{
private Mobile m_Owner; // Whos corpse is this?
private Mobile m_Killer; // Who killed the owner?
private CorpseFlag m_Flags; // @see CorpseFlag
private List<Mobile> m_Looters; // Who's looted this corpse?
private List<Item> m_EquipItems; // List of items equiped when the owner died. Ingame, these items display /on/ the corpse, not just inside
private List<Mobile> m_Aggressors; // Anyone from this list will be able to loot this corpse; we attacked them, or they attacked us when we were freely attackable
private string m_CorpseName; // Value of the CorpseNameAttribute attached to the owner when he died -or- null if the owner had no CorpseNameAttribute; use "the remains of ~name~"
private IDevourer m_Devourer; // The creature that devoured this corpse
// For notoriety:
private AccessLevel m_AccessLevel; // Which AccessLevel the owner had when he died
private Guild m_Guild; // Which Guild the owner was in when he died
private int m_Kills; // How many kills the owner had when he died
private DateTime m_TimeOfDeath; // What time was this corpse created?
private HairInfo m_Hair; // This contains the hair of the owner
private FacialHairInfo m_FacialHair; // This contains the facial hair of the owner
public static readonly TimeSpan MonsterLootRightSacrifice = TimeSpan.FromMinutes( 2.0 );
public override bool IsChildVisibleTo( Mobile m, Item child )
{
if ( !m.Player || m.AccessLevel > AccessLevel.Player ) //Staff and creatures not subject to instancing.
return true;
return true;
}
public override bool IsDecoContainer
{
get{ return false; }
}
[CommandProperty( AccessLevel.GameMaster )]
public DateTime TimeOfDeath
{
get{ return m_TimeOfDeath; }
set{ m_TimeOfDeath = value; }
}
public override bool DisplayWeight { get { return false; } }
public HairInfo Hair { get { return m_Hair; } }
public FacialHairInfo FacialHair { get { return m_FacialHair; } }
[CommandProperty( AccessLevel.GameMaster )]
public bool IsBones
{
get { return GetFlag( CorpseFlag.IsBones ); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Devoured
{
get { return (m_Devourer != null); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Carved
{
get{ return GetFlag( CorpseFlag.Carved ); }
set { SetFlag( CorpseFlag.Carved, value ); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool VisitedByTaxidermist
{
get { return GetFlag( CorpseFlag.VisitedByTaxidermist ); }
set { SetFlag( CorpseFlag.VisitedByTaxidermist, value ); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Animated
{
get { return GetFlag( CorpseFlag.Animated ); }
set { SetFlag( CorpseFlag.Animated, value ); }
}
[CommandProperty( AccessLevel.GameMaster )]
public AccessLevel AccessLevel
{
get{ return m_AccessLevel; }
}
public List<Mobile> Aggressors
{
get{ return m_Aggressors; }
}
public List<Mobile> Looters
{
get{ return m_Looters; }
}
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Killer
{
get{ return m_Killer; }
}
public List<Item> EquipItems
{
get{ return m_EquipItems; }
}
public Guild Guild
{
get{ return m_Guild; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int Kills
{
get{ return m_Kills; }
set{ m_Kills = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Criminal
{
get { return GetFlag( CorpseFlag.Criminal ); }
set { SetFlag( CorpseFlag.Criminal, value ); }
}
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Owner
{
get{ return m_Owner; }
}
public void TurnToBones()
{
if ( Deleted )
return;
ProcessDelta();
SendRemovePacket();
ItemID = Utility.Random( 0xECA, 9 ); // bone graphic
Hue = 0;
ProcessDelta();
SetFlag( CorpseFlag.NoBones, true );
SetFlag( CorpseFlag.IsBones, true );
BeginDecay( m_BoneDecayTime );
}
private static TimeSpan m_DefaultDecayTime = TimeSpan.FromMinutes( 7.0 );
private static TimeSpan m_BoneDecayTime = TimeSpan.FromMinutes( 7.0 );
private Timer m_DecayTimer;
private DateTime m_DecayTime;
public void BeginDecay( TimeSpan delay )
{
if ( m_DecayTimer != null )
m_DecayTimer.Stop();
m_DecayTime = DateTime.Now + delay;
m_DecayTimer = new InternalTimer( this, delay );
m_DecayTimer.Start();
}
public override void OnAfterDelete()
{
if ( m_DecayTimer != null )
m_DecayTimer.Stop();
m_DecayTimer = null;
}
private class InternalTimer : Timer
{
private Corpse m_Corpse;
public InternalTimer( Corpse c, TimeSpan delay ) : base( delay )
{
m_Corpse = c;
Priority = TimerPriority.FiveSeconds;
}
protected override void OnTick()
{
if ( !m_Corpse.GetFlag( CorpseFlag.NoBones ) )
m_Corpse.TurnToBones();
else
m_Corpse.Delete();
}
}
public static string GetCorpseName( Mobile m )
{
Type t = m.GetType();
object[] attrs = t.GetCustomAttributes( typeof( CorpseNameAttribute ), true );
if ( attrs != null && attrs.Length > 0 )
{
CorpseNameAttribute attr = attrs[0] as CorpseNameAttribute;
if ( attr != null )
return attr.Name;
}
return null;
}
public static void Initialize()
{
Mobile.CreateCorpseHandler += new CreateCorpseHandler( Mobile_CreateCorpseHandler );
}
public static Container Mobile_CreateCorpseHandler( Mobile owner, HairInfo hair, FacialHairInfo facialhair, List<Item> initialContent, List<Item> equipItems )
{
bool shouldFillCorpse = true;
//if ( owner is BaseCreature )
// shouldFillCorpse = !((BaseCreature)owner).IsBonded;
Corpse c = new Corpse( owner, hair, facialhair, shouldFillCorpse ? equipItems : new List<Item>() );
owner.Corpse = c;
if ( shouldFillCorpse )
{
for ( int i = 0; i < initialContent.Count; ++i )
{
Item item = initialContent[i];
c.DropItem( item );
}
}
else
{
c.Carved = true; // TODO: Is it needed?
}
Point3D loc = owner.Location;
Map map = owner.Map;
if ( map == null || map == Map.Internal )
{
loc = owner.LogoutLocation;
map = owner.LogoutMap;
}
c.MoveToWorld( loc, map );
return c;
}
public override bool IsPublicContainer{ get{ return true; } }
public Corpse( Mobile owner, List<Item> equipItems ) : this( owner, null, null, equipItems )
{
}
public Corpse( Mobile owner, HairInfo hair, FacialHairInfo facialhair, List<Item> equipItems )
: base( 0x2006 )
{
// To supress console warnings, stackable must be true
Stackable = true;
Amount = owner.Body; // protocol defines that for itemid 0x2006, amount=body
Stackable = false;
Movable = false;
Hue = owner.Hue;
Direction = owner.Direction;
Name = owner.Name;
m_Owner = owner;
m_CorpseName = GetCorpseName( owner );
m_TimeOfDeath = DateTime.Now;
m_AccessLevel = owner.AccessLevel;
m_Guild = owner.Guild as Guild;
m_Kills = owner.Kills;
SetFlag( CorpseFlag.Criminal, owner.Criminal );
m_Hair = hair;
m_FacialHair = facialhair;
// This corpse does not turn to bones if: the owner is not a player
SetFlag( CorpseFlag.NoBones, !owner.Player );
m_Looters = new List<Mobile>();
m_EquipItems = equipItems;
m_Aggressors = new List<Mobile>( owner.Aggressors.Count + owner.Aggressed.Count );
//bool addToAggressors = !( owner is BaseCreature );
bool isBaseCreature = (owner is BaseCreature);
TimeSpan lastTime = TimeSpan.MaxValue;
for ( int i = 0; i < owner.Aggressors.Count; ++i )
{
AggressorInfo info = owner.Aggressors[i];
if ( (DateTime.Now - info.LastCombatTime) < lastTime )
{
m_Killer = info.Attacker;
lastTime = (DateTime.Now - info.LastCombatTime);
}
if ( !isBaseCreature && !info.CriminalAggression )
m_Aggressors.Add( info.Attacker );
}
for ( int i = 0; i < owner.Aggressed.Count; ++i )
{
AggressorInfo info = owner.Aggressed[i];
if ( (DateTime.Now - info.LastCombatTime) < lastTime )
{
m_Killer = info.Defender;
lastTime = (DateTime.Now - info.LastCombatTime);
}
if ( !isBaseCreature )
m_Aggressors.Add( info.Defender );
}
if ( isBaseCreature )
{
BaseCreature bc = (BaseCreature)owner;
Mobile master = bc.GetMaster();
if( master != null )
m_Aggressors.Add( master );
List<DamageStore> rights = BaseCreature.GetLootingRights( bc.DamageEntries, bc.HitsMax );
for ( int i = 0; i < rights.Count; ++i )
{
DamageStore ds = rights[i];
if ( ds.m_HasRight )
m_Aggressors.Add( ds.m_Mobile );
}
}
BeginDecay( m_DefaultDecayTime );
DevourCorpse();
}
public Corpse( Serial serial ) : base( serial )
{
}
protected bool GetFlag( CorpseFlag flag )
{
return ((m_Flags & flag) != 0);
}
protected void SetFlag( CorpseFlag flag, bool on )
{
m_Flags = (on ? m_Flags | flag : m_Flags & ~flag);
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 11 ); // version
writer.Write( (int)m_Flags );
writer.WriteDeltaTime( m_TimeOfDeath );
List<KeyValuePair<Item, Point3D>> list = ( m_RestoreTable == null ? null : new List<KeyValuePair<Item, Point3D>>( m_RestoreTable ) );
int count = ( list == null ? 0 : list.Count );
writer.Write( count );
for ( int i = 0; i < count; ++i )
{
KeyValuePair<Item, Point3D> kvp = list[i];
Item item = kvp.Key;
Point3D loc = kvp.Value;
writer.Write( item );
if ( item.Location == loc )
{
writer.Write( false );
}
else
{
writer.Write( true );
writer.Write( loc );
}
}
writer.Write( m_DecayTimer != null );
if ( m_DecayTimer != null )
writer.WriteDeltaTime( m_DecayTime );
writer.Write( m_Looters );
writer.Write( m_Killer );
writer.Write( m_Aggressors );
writer.Write( m_Owner );
writer.Write( (string) m_CorpseName );
writer.Write( (int) m_AccessLevel );
writer.Write( (Guild) m_Guild );
writer.Write( (int) m_Kills );
writer.Write( m_EquipItems );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 11:
{
// Version 11, we move all bools to a CorpseFlag
m_Flags = (CorpseFlag)reader.ReadInt();
m_TimeOfDeath = reader.ReadDeltaTime();
int count = reader.ReadInt();
for( int i = 0; i < count; ++i )
{
Item item = reader.ReadItem();
if( reader.ReadBool() )
SetRestoreInfo( item, reader.ReadPoint3D() );
else if( item != null )
SetRestoreInfo( item, item.Location );
}
if( reader.ReadBool() )
BeginDecay( reader.ReadDeltaTime() - DateTime.Now );
m_Looters = reader.ReadStrongMobileList();
m_Killer = reader.ReadMobile();
m_Aggressors = reader.ReadStrongMobileList();
m_Owner = reader.ReadMobile();
m_CorpseName = reader.ReadString();
m_AccessLevel = (AccessLevel)reader.ReadInt();
reader.ReadInt(); // guild reserve
m_Kills = reader.ReadInt();
m_EquipItems = reader.ReadStrongItemList();
break;
}
case 10:
{
m_TimeOfDeath = reader.ReadDeltaTime();
goto case 9;
}
case 9:
{
int count = reader.ReadInt();
for ( int i = 0; i < count; ++i )
{
Item item = reader.ReadItem();
if ( reader.ReadBool() )
SetRestoreInfo( item, reader.ReadPoint3D() );
else if ( item != null )
SetRestoreInfo( item, item.Location );
}
goto case 8;
}
case 8:
{
SetFlag( CorpseFlag.VisitedByTaxidermist, reader.ReadBool() );
goto case 7;
}
case 7:
{
if ( reader.ReadBool() )
BeginDecay( reader.ReadDeltaTime() - DateTime.Now );
goto case 6;
}
case 6:
{
m_Looters = reader.ReadStrongMobileList();
m_Killer = reader.ReadMobile();
goto case 5;
}
case 5:
{
SetFlag( CorpseFlag.Carved, reader.ReadBool() );
goto case 4;
}
case 4:
{
m_Aggressors = reader.ReadStrongMobileList();
goto case 3;
}
case 3:
{
m_Owner = reader.ReadMobile();
goto case 2;
}
case 2:
{
SetFlag( CorpseFlag.NoBones, reader.ReadBool() );
goto case 1;
}
case 1:
{
m_CorpseName = reader.ReadString();
goto case 0;
}
case 0:
{
if ( version < 10 )
m_TimeOfDeath = DateTime.Now;
if ( version < 7 )
BeginDecay( m_DefaultDecayTime );
if ( version < 6 )
m_Looters = new List<Mobile>();
if ( version < 4 )
m_Aggressors = new List<Mobile>();
m_AccessLevel = (AccessLevel)reader.ReadInt();
reader.ReadInt(); // guild reserve
m_Kills = reader.ReadInt();
SetFlag( CorpseFlag.Criminal, reader.ReadBool() );
m_EquipItems = reader.ReadStrongItemList();
break;
}
}
}
public bool DevourCorpse()
{
if( Devoured || Deleted || m_Killer == null || m_Killer.Deleted || !m_Killer.Alive || !(m_Killer is IDevourer) || m_Owner == null || m_Owner.Deleted )
return false;
m_Devourer = (IDevourer)m_Killer; // Set the devourer the killer
return m_Devourer.Devour( this ); // Devour the corpse if it hasn't
}
public override void SendInfoTo( NetState state, bool sendOplPacket )
{
base.SendInfoTo( state, sendOplPacket );
if ( ItemID == 0x2006 )
{
state.Send( new CorpseContent( state.Mobile, this ) );
state.Send( new CorpseEquip( state.Mobile, this ) );
}
}
public bool IsCriminalAction( Mobile from )
{
if ( from == m_Owner || from.AccessLevel >= AccessLevel.GameMaster )
return false;
Party p = Party.Get( m_Owner );
if ( p != null && p.Contains( from ) )
{
PartyMemberInfo pmi = p[m_Owner];
if ( pmi != null && pmi.CanLoot )
return false;
}
return ( NotorietyHandlers.CorpseNotoriety( from, this ) == Notoriety.Innocent );
}
public override bool CheckItemUse( Mobile from, Item item )
{
if ( !base.CheckItemUse( from, item ) )
return false;
if ( item != this )
return CanLoot( from, item );
return true;
}
public override bool CheckLift( Mobile from, Item item, ref LRReason reject )
{
if ( !base.CheckLift( from, item, ref reject ) )
return false;
return CanLoot( from,item );
}
public override void OnItemUsed( Mobile from, Item item )
{
base.OnItemUsed( from, item );
if ( item is Food )
from.RevealingAction();
if ( item != this && IsCriminalAction( from ) )
from.CriminalAction( true );
if ( !m_Looters.Contains( from ) )
m_Looters.Add( from );
}
public override void OnItemLifted( Mobile from, Item item )
{
base.OnItemLifted( from, item );
if ( item != this && from != m_Owner )
from.RevealingAction();
if ( item != this && IsCriminalAction( from ) )
from.CriminalAction( true );
if ( !m_Looters.Contains( from ) )
m_Looters.Add( from );
}
private class OpenCorpseEntry : ContextMenuEntry
{
public OpenCorpseEntry() : base( 6215, 2 )
{
}
public override void OnClick()
{
Corpse corpse = Owner.Target as Corpse;
if ( corpse != null && Owner.From.CheckAlive() )
corpse.Open( Owner.From );
}
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
}
private Dictionary<Item, Point3D> m_RestoreTable;
public bool GetRestoreInfo( Item item, ref Point3D loc )
{
if ( m_RestoreTable == null || item == null )
return false;
return m_RestoreTable.TryGetValue( item, out loc );
}
public void SetRestoreInfo( Item item, Point3D loc )
{
if ( item == null )
return;
if ( m_RestoreTable == null )
m_RestoreTable = new Dictionary<Item, Point3D>();
m_RestoreTable[item] = loc;
}
public void ClearRestoreInfo( Item item )
{
if ( m_RestoreTable == null || item == null )
return;
m_RestoreTable.Remove( item );
if ( m_RestoreTable.Count == 0 )
m_RestoreTable = null;
}
public bool CanLoot( Mobile from, Item item )
{
if ( !IsCriminalAction( from ) )
return true;
Map map = this.Map;
if ( map == null || (map.Rules & MapRules.HarmfulRestrictions) != 0 )
return false;
return true;
}
public bool CheckLoot( Mobile from, Item item )
{
if ( !CanLoot( from, item ) )
{
if ( m_Owner == null || !m_Owner.Player )
from.SendLocalizedMessage( 1005035 ); // You did not earn the right to loot this creature!
else
from.SendLocalizedMessage( 1010049 ); // You may not loot this corpse.
return false;
}
else if ( IsCriminalAction( from ) )
{
if ( m_Owner == null || !m_Owner.Player )
from.SendLocalizedMessage( 1005036 ); // Looting this monster corpse will be a criminal act!
else
from.SendLocalizedMessage( 1005038 ); // Looting this corpse will be a criminal act!
}
return true;
}
public virtual void Open( Mobile from )
{
if ( from.AccessLevel > AccessLevel.Player || from.InRange( this.GetWorldLocation(), 2 ) )
{
if ( !CheckLoot( from, null ) )
return;
base.OnDoubleClick( from );
}
else
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
return;
}
}
public override void OnDoubleClick( Mobile from )
{
Open( from );
}
public override bool CheckContentDisplay( Mobile from )
{
return false;
}
public override bool DisplaysContent{ get{ return false; } }
public override void AddNameProperty( ObjectPropertyList list )
{
if ( ItemID == 0x2006 ) // Corpse form
{
if ( m_CorpseName != null )
list.Add( m_CorpseName );
else
list.Add( 1046414, this.Name ); // the remains of ~1_NAME~
}
else // Bone form
{
list.Add( 1046414, this.Name ); // the remains of ~1_NAME~
}
}
public override void OnSingleClick( Mobile from )
{
int hue = Notoriety.GetHue( NotorietyHandlers.CorpseNotoriety( from, this ) );
if ( ItemID == 0x2006 ) // Corpse form
{
if ( m_CorpseName != null )
from.Send( new AsciiMessage( Serial, ItemID, MessageType.Label, hue, 3, "", m_CorpseName ) );
else
from.Send( new MessageLocalized( Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name ) );
}
else // Bone form
{
from.Send( new MessageLocalized( Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name ) );
}
}
public void Carve( Mobile from, Item item )
{
if ( IsCriminalAction( from ) && this.Map != null && (this.Map.Rules & MapRules.HarmfulRestrictions) != 0 )
{
if ( m_Owner == null || !m_Owner.Player )
from.SendLocalizedMessage( 1005035 ); // You did not earn the right to loot this creature!
else
from.SendLocalizedMessage( 1010049 ); // You may not loot this corpse.
return;
}
Mobile dead = m_Owner;
if ( GetFlag( CorpseFlag.Carved ) || dead == null )
{
from.SendLocalizedMessage( 500485 ); // You see nothing useful to carve from the corpse.
}
else if ( ((Body)Amount).IsHuman && ItemID == 0x2006 )
{
new Blood( 0x122D ).MoveToWorld( Location, Map );
new Torso().MoveToWorld( Location, Map );
new LeftLeg().MoveToWorld( Location, Map );
new LeftArm().MoveToWorld( Location, Map );
new RightLeg().MoveToWorld( Location, Map );
new RightArm().MoveToWorld( Location, Map );
new Head( dead.Name ).MoveToWorld( Location, Map );
SetFlag( CorpseFlag.Carved, true );
ProcessDelta();
SendRemovePacket();
ItemID = Utility.Random( 0xECA, 9 ); // bone graphic
Hue = 0;
ProcessDelta();
if ( IsCriminalAction( from ) )
from.CriminalAction( true );
}
else if ( dead is BaseCreature )
{
((BaseCreature)dead).OnCarve( from, this, item );
}
else
{
from.SendLocalizedMessage( 500485 ); // You see nothing useful to carve from the corpse.
}
}
}
}

View file

@ -0,0 +1,20 @@
using System;
namespace Server
{
[AttributeUsage( AttributeTargets.Class )]
public class CorpseNameAttribute : Attribute
{
private string m_Name;
public string Name
{
get{ return m_Name; }
}
public CorpseNameAttribute( string name )
{
m_Name = name;
}
}
}

View file

@ -0,0 +1,115 @@
using System;
using Server;
namespace Server.Items
{
public class DecayedCorpse : Container
{
private Timer m_DecayTimer;
private DateTime m_DecayTime;
private static TimeSpan m_DefaultDecayTime = TimeSpan.FromMinutes( 7.0 );
public DecayedCorpse( string name ) : base( Utility.Random( 0xECA, 9 ) )
{
Movable = false;
Name = name;
BeginDecay( m_DefaultDecayTime );
}
public void BeginDecay( TimeSpan delay )
{
if ( m_DecayTimer != null )
m_DecayTimer.Stop();
m_DecayTime = DateTime.Now + delay;
m_DecayTimer = new InternalTimer( this, delay );
m_DecayTimer.Start();
}
public override void OnAfterDelete()
{
if ( m_DecayTimer != null )
m_DecayTimer.Stop();
m_DecayTimer = null;
}
private class InternalTimer : Timer
{
private DecayedCorpse m_Corpse;
public InternalTimer( DecayedCorpse c, TimeSpan delay ) : base( delay )
{
m_Corpse = c;
Priority = TimerPriority.FiveSeconds;
}
protected override void OnTick()
{
m_Corpse.Delete();
}
}
// Do not display (x items, y stones)
public override bool CheckContentDisplay( Mobile from )
{
return false;
}
// Do not display (x items, y stones)
public override bool DisplaysContent{ get{ return false; } }
public override void AddNameProperty( ObjectPropertyList list )
{
list.Add( 1046414, Name ); // the remains of ~1_NAME~
}
public override void OnSingleClick( Mobile from )
{
this.LabelTo( from, 1046414, Name ); // the remains of ~1_NAME~
}
public DecayedCorpse( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 1 ); // version
writer.Write( m_DecayTimer != null );
if ( m_DecayTimer != null )
writer.WriteDeltaTime( m_DecayTime );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
BeginDecay( m_DefaultDecayTime );
break;
}
case 1:
{
if ( reader.ReadBool() )
BeginDecay( reader.ReadDeltaTime() - DateTime.Now );
break;
}
}
}
}
}

View file

@ -0,0 +1,125 @@
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Items;
namespace Server.Network
{
public sealed class CorpseEquip : Packet
{
public CorpseEquip( Mobile beholder, Corpse beheld ) : base( 0x89 )
{
List<Item> list = beheld.EquipItems;
int count = list.Count;
if( beheld.Hair != null && beheld.Hair.ItemID > 0 )
count++;
if( beheld.FacialHair != null && beheld.FacialHair.ItemID > 0 )
count++;
EnsureCapacity( 8 + (count * 5) );
m_Stream.Write( (int) beheld.Serial );
for ( int i = 0; i < list.Count; ++i )
{
Item item = list[i];
if ( !item.Deleted && beholder.CanSee( item ) && item.Parent == beheld )
{
m_Stream.Write( (byte) (item.Layer + 1) );
m_Stream.Write( (int) item.Serial );
}
}
if( beheld.Hair != null && beheld.Hair.ItemID > 0 )
{
m_Stream.Write( (byte)(Layer.Hair + 1) );
m_Stream.Write( (int)HairInfo.FakeSerial( beheld.Owner ) - 2 );
}
if( beheld.FacialHair != null && beheld.FacialHair.ItemID > 0 )
{
m_Stream.Write( (byte)(Layer.FacialHair + 1) );
m_Stream.Write( (int)FacialHairInfo.FakeSerial( beheld.Owner ) - 2 );
}
m_Stream.Write( (byte) Layer.Invalid );
}
}
public sealed class CorpseContent : Packet
{
public CorpseContent( Mobile beholder, Corpse beheld )
: base( 0x3C )
{
List<Item> items = beheld.EquipItems;
int count = items.Count;
if( beheld.Hair != null && beheld.Hair.ItemID > 0 )
count++;
if( beheld.FacialHair != null && beheld.FacialHair.ItemID > 0 )
count++;
EnsureCapacity( 5 + (count * 19) );
long pos = m_Stream.Position;
int written = 0;
m_Stream.Write( (ushort)0 );
for( int i = 0; i < items.Count; ++i )
{
Item child = items[i];
if( !child.Deleted && child.Parent == beheld && beholder.CanSee( child ) )
{
m_Stream.Write( (int)child.Serial );
m_Stream.Write( (ushort)child.ItemID );
m_Stream.Write( (byte)0 ); // signed, itemID offset
m_Stream.Write( (ushort)child.Amount );
m_Stream.Write( (short)child.X );
m_Stream.Write( (short)child.Y );
m_Stream.Write( (int)beheld.Serial );
m_Stream.Write( (ushort)child.Hue );
++written;
}
}
if( beheld.Hair != null && beheld.Hair.ItemID > 0 )
{
m_Stream.Write( (int)HairInfo.FakeSerial( beheld.Owner ) - 2 );
m_Stream.Write( (ushort)beheld.Hair.ItemID );
m_Stream.Write( (byte)0 ); // signed, itemID offset
m_Stream.Write( (ushort)1 );
m_Stream.Write( (short)0 );
m_Stream.Write( (short)0 );
m_Stream.Write( (int)beheld.Serial );
m_Stream.Write( (ushort)beheld.Hair.Hue );
++written;
}
if( beheld.FacialHair != null && beheld.FacialHair.ItemID > 0 )
{
m_Stream.Write( (int)FacialHairInfo.FakeSerial( beheld.Owner ) - 2 );
m_Stream.Write( (ushort)beheld.FacialHair.ItemID );
m_Stream.Write( (byte)0 ); // signed, itemID offset
m_Stream.Write( (ushort)1 );
m_Stream.Write( (short)0 );
m_Stream.Write( (short)0 );
m_Stream.Write( (int)beheld.Serial );
m_Stream.Write( (ushort)beheld.FacialHair.Hue );
++written;
}
m_Stream.Seek( pos, SeekOrigin.Begin );
m_Stream.Write( (ushort)written );
}
}
}

View file

@ -0,0 +1,339 @@
using System;
namespace Server.Items
{
public enum ECEffectType
{
None,
Moving,
Location,
Target,
Lightning
}
public enum EffectTriggerType
{
None,
Sequenced,
DoubleClick,
InRange
}
public class EffectController : Item
{
private TimeSpan m_EffectDelay;
private ECEffectType m_EffectType;
private EffectTriggerType m_TriggerType;
private IEntity m_Source;
private IEntity m_Target;
private TimeSpan m_TriggerDelay;
private EffectController m_Trigger;
private int m_ItemID;
private int m_Hue;
private int m_RenderMode;
private int m_Speed;
private int m_Duration;
private bool m_FixedDirection;
private bool m_Explodes;
private int m_ParticleEffect;
private int m_ExplodeParticleEffect;
private int m_ExplodeSound;
private EffectLayer m_EffectLayer;
private int m_Unknown;
private TimeSpan m_SoundDelay;
private int m_SoundID;
private bool m_PlaySoundAtTrigger;
private int m_TriggerRange;
[CommandProperty( AccessLevel.GameMaster )]
public ECEffectType EffectType{ get{ return m_EffectType; } set{ m_EffectType = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public EffectTriggerType TriggerType{ get{ return m_TriggerType; } set{ m_TriggerType = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public EffectLayer EffectLayer{ get{ return m_EffectLayer; } set{ m_EffectLayer = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan EffectDelay{ get{ return m_EffectDelay; } set{ m_EffectDelay = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan TriggerDelay{ get{ return m_TriggerDelay; } set{ m_TriggerDelay = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan SoundDelay{ get{ return m_SoundDelay; } set{ m_SoundDelay = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public Item SourceItem{ get{ return m_Source as Item; } set{ m_Source = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public Mobile SourceMobile{ get{ return m_Source as Mobile; } set{ m_Source = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public bool SourceNull{ get{ return ( m_Source == null ); } set{ if ( value ) m_Source = null; } }
[CommandProperty( AccessLevel.GameMaster )]
public Item TargetItem{ get{ return m_Target as Item; } set{ m_Target = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public Mobile TargetMobile{ get{ return m_Target as Mobile; } set{ m_Target = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public bool TargetNull{ get{ return ( m_Target == null ); } set{ if ( value ) m_Target = null; } }
[CommandProperty( AccessLevel.GameMaster )]
public EffectController Sequence{ get{ return m_Trigger; } set{ m_Trigger = value; } }
[CommandProperty( AccessLevel.GameMaster )]
private bool FixedDirection{ get{ return m_FixedDirection; } set{ m_FixedDirection = value; } }
[CommandProperty( AccessLevel.GameMaster )]
private bool Explodes{ get{ return m_Explodes; } set{ m_Explodes = value; } }
[CommandProperty( AccessLevel.GameMaster )]
private bool PlaySoundAtTrigger{ get{ return m_PlaySoundAtTrigger; } set{ m_PlaySoundAtTrigger = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int EffectItemID{ get{ return m_ItemID; } set{ m_ItemID = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int EffectHue{ get{ return m_Hue; } set{ m_Hue = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int RenderMode{ get{ return m_RenderMode; } set{ m_RenderMode = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int Speed{ get{ return m_Speed; } set{ m_Speed = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int Duration{ get{ return m_Duration; } set{ m_Duration = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int ParticleEffect{ get{ return m_ParticleEffect; } set{ m_ParticleEffect = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int ExplodeParticleEffect{ get{ return m_ExplodeParticleEffect; } set{ m_ExplodeParticleEffect = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int ExplodeSound{ get{ return m_ExplodeSound; } set{ m_ExplodeSound = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int Unknown{ get{ return m_Unknown; } set{ m_Unknown = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int SoundID{ get{ return m_SoundID; } set{ m_SoundID = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int TriggerRange{ get{ return m_TriggerRange; } set{ m_TriggerRange = value; } }
public override string DefaultName
{
get { return "Effect Controller"; }
}
[Constructable]
public EffectController() : base( 0x1B72 )
{
Movable = false;
Visible = false;
m_TriggerType = EffectTriggerType.Sequenced;
m_EffectLayer = (EffectLayer)255;
}
public override void OnDoubleClick( Mobile from )
{
if ( m_TriggerType == EffectTriggerType.DoubleClick )
DoEffect( from );
}
public override bool HandlesOnMovement{ get{ return ( m_TriggerType == EffectTriggerType.InRange ); } }
public override void OnMovement( Mobile m, Point3D oldLocation )
{
if ( m.Location != oldLocation && m_TriggerType == EffectTriggerType.InRange && Utility.InRange( GetWorldLocation(), m.Location, m_TriggerRange ) && !Utility.InRange( GetWorldLocation(), oldLocation, m_TriggerRange ) )
DoEffect( m );
}
public EffectController( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( m_EffectDelay );
writer.Write( m_TriggerDelay );
writer.Write( m_SoundDelay );
if ( m_Source is Item )
writer.Write( m_Source as Item );
else
writer.Write( m_Source as Mobile );
if ( m_Target is Item )
writer.Write( m_Target as Item );
else
writer.Write( m_Target as Mobile );
writer.Write( m_Trigger as Item );
writer.Write( m_FixedDirection );
writer.Write( m_Explodes );
writer.Write( m_PlaySoundAtTrigger );
writer.WriteEncodedInt( (int) m_EffectType );
writer.WriteEncodedInt( (int) m_EffectLayer );
writer.WriteEncodedInt( (int) m_TriggerType );
writer.WriteEncodedInt( m_ItemID );
writer.WriteEncodedInt( m_Hue );
writer.WriteEncodedInt( m_RenderMode );
writer.WriteEncodedInt( m_Speed );
writer.WriteEncodedInt( m_Duration );
writer.WriteEncodedInt( m_ParticleEffect );
writer.WriteEncodedInt( m_ExplodeParticleEffect );
writer.WriteEncodedInt( m_ExplodeSound );
writer.WriteEncodedInt( m_Unknown );
writer.WriteEncodedInt( m_SoundID );
writer.WriteEncodedInt( m_TriggerRange );
}
private IEntity ReadEntity( GenericReader reader )
{
return World.FindEntity( reader.ReadInt() );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_EffectDelay = reader.ReadTimeSpan();
m_TriggerDelay = reader.ReadTimeSpan();
m_SoundDelay = reader.ReadTimeSpan();
m_Source = ReadEntity( reader );
m_Target = ReadEntity( reader );
m_Trigger = reader.ReadItem() as EffectController;
m_FixedDirection = reader.ReadBool();
m_Explodes = reader.ReadBool();
m_PlaySoundAtTrigger = reader.ReadBool();
m_EffectType = (ECEffectType)reader.ReadEncodedInt();
m_EffectLayer = (EffectLayer)reader.ReadEncodedInt();
m_TriggerType = (EffectTriggerType)reader.ReadEncodedInt();
m_ItemID = reader.ReadEncodedInt();
m_Hue = reader.ReadEncodedInt();
m_RenderMode = reader.ReadEncodedInt();
m_Speed = reader.ReadEncodedInt();
m_Duration = reader.ReadEncodedInt();
m_ParticleEffect = reader.ReadEncodedInt();
m_ExplodeParticleEffect = reader.ReadEncodedInt();
m_ExplodeSound = reader.ReadEncodedInt();
m_Unknown = reader.ReadEncodedInt();
m_SoundID = reader.ReadEncodedInt();
m_TriggerRange = reader.ReadEncodedInt();
break;
}
}
}
public void PlaySound( object trigger )
{
IEntity ent = null;
if ( m_PlaySoundAtTrigger )
ent = trigger as IEntity;
if ( ent == null )
ent = this;
Effects.PlaySound( (ent is Item) ? ((Item)ent).GetWorldLocation() : ent.Location, ent.Map, m_SoundID );
}
public void DoEffect( object trigger )
{
if ( Deleted || m_TriggerType == EffectTriggerType.None )
return;
if( trigger is Mobile && ((Mobile)trigger).Hidden && ((Mobile)trigger).AccessLevel > AccessLevel.Player )
return;
if ( m_SoundID > 0 )
Timer.DelayCall( m_SoundDelay, new TimerStateCallback( PlaySound ), trigger );
if ( m_Trigger != null )
Timer.DelayCall( m_TriggerDelay, new TimerStateCallback( m_Trigger.DoEffect ), trigger );
if ( m_EffectType != ECEffectType.None )
Timer.DelayCall( m_EffectDelay, new TimerStateCallback( InternalDoEffect ), trigger );
}
public void InternalDoEffect( object trigger )
{
IEntity from = m_Source, to = m_Target;
if ( from == null )
from = (IEntity)trigger;
if ( to == null )
to = (IEntity)trigger;
switch ( m_EffectType )
{
case ECEffectType.Lightning:
{
Effects.SendBoltEffect( from, false, m_Hue );
break;
}
case ECEffectType.Location:
{
Effects.SendLocationParticles( EffectItem.Create( from.Location, from.Map, EffectItem.DefaultDuration ), m_ItemID, m_Speed, m_Duration, m_Hue, m_RenderMode, m_ParticleEffect, m_Unknown );
break;
}
case ECEffectType.Moving:
{
if ( from == this )
from = EffectItem.Create( from.Location, from.Map, EffectItem.DefaultDuration );
if ( to == this )
to = EffectItem.Create( to.Location, to.Map, EffectItem.DefaultDuration );
Effects.SendMovingParticles( from, to, m_ItemID, m_Speed, m_Duration, m_FixedDirection, m_Explodes, m_Hue, m_RenderMode, m_ParticleEffect, m_ExplodeParticleEffect, m_ExplodeSound, m_EffectLayer, m_Unknown );
break;
}
case ECEffectType.Target:
{
Effects.SendTargetParticles( from, m_ItemID, m_Speed, m_Duration, m_Hue, m_RenderMode, m_ParticleEffect, m_EffectLayer, m_Unknown );
break;
}
}
}
}
}

View file

@ -0,0 +1,95 @@
using System;
using System.Collections;
using Server;
using System.Collections.Generic;
namespace Server.Items
{
public class EffectItem : Item
{
private static List<EffectItem> m_Free = new List<EffectItem>(); // List of available EffectItems
public static readonly TimeSpan DefaultDuration = TimeSpan.FromSeconds( 5.0 );
public static EffectItem Create( Point3D p, Map map, TimeSpan duration )
{
EffectItem item = null;
for ( int i = m_Free.Count - 1; item == null && i >= 0; --i ) // We reuse new entries first so decay works better
{
EffectItem free = m_Free[i];
m_Free.RemoveAt( i );
if ( !free.Deleted && free.Map == Map.Internal )
item = free;
}
if ( item == null )
item = new EffectItem();
else
item.ItemID = 1;
item.MoveToWorld( p, map );
item.BeginFree( duration );
return item;
}
private EffectItem() : base( 1 ) // nodraw
{
Movable = false;
}
public void BeginFree( TimeSpan duration )
{
new FreeTimer( this, duration ).Start();
}
public override bool Decays
{
get
{
return true;
}
}
public EffectItem( 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();
Delete();
}
private class FreeTimer : Timer
{
private EffectItem m_Item;
public FreeTimer( EffectItem item, TimeSpan delay ) : base( delay )
{
m_Item = item;
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
m_Item.Internalize();
m_Free.Add( m_Item );
}
}
}
}

View file

@ -0,0 +1,130 @@
using System;
using System.Reflection;
using System.Collections.Generic;
using Server.Multis;
namespace Server.Items
{
[AttributeUsage( AttributeTargets.Class )]
public class FlipableAddonAttribute : Attribute
{
private static string m_MethodName = "Flip";
private static Type[] m_Params = new Type[]
{
typeof( Mobile ), typeof( Direction )
};
private Direction[] m_Directions;
public Direction[] Directions
{
get { return m_Directions; }
}
public FlipableAddonAttribute( params Direction[] directions )
{
m_Directions = directions;
}
public virtual void Flip( Mobile from, Item addon )
{
if ( m_Directions != null && m_Directions.Length > 1 )
{
try
{
MethodInfo flipMethod = addon.GetType().GetMethod( m_MethodName, m_Params );
if ( flipMethod != null )
{
int index = 0;
for ( int i = 0; i < m_Directions.Length; i++ )
{
if ( addon.Direction == m_Directions[ i ] )
{
index = i + 1;
break;
}
}
if ( index >= m_Directions.Length )
index = 0;
ClearComponents( addon );
flipMethod.Invoke( addon, new object[ 2 ] { from, m_Directions[ index ] } );
BaseHouse house = null;
AddonFitResult result = AddonFitResult.Valid;
addon.Map = Map.Internal;
if ( addon is BaseAddon )
result = ( (BaseAddon) addon ).CouldFit( addon.Location, from.Map, from, ref house );
else if ( addon is BaseAddonContainer )
result = ( (BaseAddonContainer) addon ).CouldFit( addon.Location, from.Map, from, ref house );
addon.Map = from.Map;
if ( result != AddonFitResult.Valid )
{
if ( index == 0 )
index = m_Directions.Length - 1;
else
index -= 1;
ClearComponents( addon );
flipMethod.Invoke( addon, new object[ 2 ] { from, m_Directions[ index ] } );
if ( result == AddonFitResult.Blocked )
from.SendLocalizedMessage( 500269 ); // You cannot build that there.
else if ( result == AddonFitResult.NotInHouse )
from.SendLocalizedMessage( 500274 ); // You can only place this in a house that you own!
else if ( result == AddonFitResult.DoorsNotClosed )
from.SendMessage( "You must close all house doors before placing this." );
else if ( result == AddonFitResult.DoorTooClose )
from.SendLocalizedMessage( 500271 ); // You cannot build near the door.
else if ( result == AddonFitResult.NoWall )
from.SendLocalizedMessage( 500268 ); // This object needs to be mounted on something.
}
addon.Direction = m_Directions[ index ];
}
}
catch
{
}
}
}
private void ClearComponents( Item item )
{
if ( item is BaseAddon )
{
BaseAddon addon = (BaseAddon) item;
foreach ( AddonComponent c in addon.Components )
{
c.Addon = null;
c.Delete();
}
addon.Components.Clear();
}
else if ( item is BaseAddonContainer )
{
BaseAddonContainer addon = (BaseAddonContainer) item;
foreach ( AddonContainerComponent c in addon.Components )
{
c.Addon = null;
c.Delete();
}
addon.Components.Clear();
}
}
}
}

View file

@ -0,0 +1,118 @@
using System;
using Server;
using System.Reflection;
using Server.Targeting;
using Server.Commands;
namespace Server.Items
{
public class FlipCommandHandlers
{
public static void Initialize()
{
CommandSystem.Register( "Flip", AccessLevel.GameMaster, new CommandEventHandler( Flip_OnCommand ) );
}
[Usage( "Flip" )]
[Description( "Turns an item." )]
public static void Flip_OnCommand( CommandEventArgs e )
{
e.Mobile.Target = new FlipTarget();
}
private class FlipTarget : Target
{
public FlipTarget()
: base( -1, false, TargetFlags.None )
{
}
protected override void OnTarget( Mobile from, object targeted )
{
if( targeted is Item )
{
Item item = (Item)targeted;
if( item.Movable == false && from.AccessLevel == AccessLevel.Player )
return;
Type type = targeted.GetType();
FlipableAttribute[] AttributeArray = (FlipableAttribute[])type.GetCustomAttributes( typeof( FlipableAttribute ), false );
if( AttributeArray.Length == 0 )
{
return;
}
FlipableAttribute fa = AttributeArray[0];
fa.Flip( (Item)targeted );
}
}
}
}
[AttributeUsage( AttributeTargets.Class )]
public class DynamicFlipingAttribute : Attribute
{
public DynamicFlipingAttribute()
{
}
}
[AttributeUsage( AttributeTargets.Class )]
public class FlipableAttribute : Attribute
{
private int[] m_ItemIDs;
public int[] ItemIDs
{
get { return m_ItemIDs; }
}
public FlipableAttribute()
: this( null )
{
}
public FlipableAttribute( params int[] itemIDs )
{
m_ItemIDs = itemIDs;
}
public virtual void Flip( Item item )
{
if( m_ItemIDs == null )
{
try
{
MethodInfo flipMethod = item.GetType().GetMethod( "Flip", Type.EmptyTypes );
if( flipMethod != null )
flipMethod.Invoke( item, new object[0] );
}
catch
{
}
}
else
{
int index = 0;
for( int i = 0; i < m_ItemIDs.Length; i++ )
{
if( item.ItemID == m_ItemIDs[i] )
{
index = i + 1;
break;
}
}
if( index > m_ItemIDs.Length - 1 )
index = 0;
item.ItemID = m_ItemIDs[index];
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,74 @@
using System;
namespace Server.Items
{
public class Gold : Item
{
public override double DefaultWeight
{
get { return ( 0.02 ); }
}
[Constructable]
public Gold() : this( 1 )
{
}
[Constructable]
public Gold( int amountFrom, int amountTo ) : this( Utility.RandomMinMax( amountFrom, amountTo ) )
{
}
[Constructable]
public Gold( int amount ) : base( 0xEED )
{
Stackable = true;
Amount = amount;
}
public Gold( Serial serial ) : base( serial )
{
}
public override int GetDropSound()
{
if ( Amount <= 1 )
return 0x2E4;
else if ( Amount <= 5 )
return 0x2E5;
else
return 0x2E6;
}
protected override void OnAmountChange( int oldValue )
{
int newValue = this.Amount;
UpdateTotal( this, TotalType.Gold, newValue - oldValue );
}
public override int GetTotal( TotalType type )
{
int baseTotal = base.GetTotal( type );
if ( type == TotalType.Gold )
baseTotal += this.Amount;
return baseTotal;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,134 @@
using System;
using System.Globalization;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
{
public class GoldDeed : Item
{
private int m_Worth;
[CommandProperty( AccessLevel.GameMaster )]
public int Worth
{
get{ return m_Worth; }
set{ m_Worth = value; InvalidateProperties(); }
}
public GoldDeed( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (int) m_Worth );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Worth = reader.ReadInt();
break;
}
}
}
[Constructable]
public GoldDeed( int worth ) : base( 0x14F0 )
{
Weight = 1.0;
Hue = 0x34;
Name = "gold deed";
m_Worth = worth;
}
public override int LabelNumber{ get{ return 1041361; } } // A gold deed
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
string worth = m_Worth.ToString();
list.Add( 1060738, worth ); // value: ~1_val~
}
public override void OnSingleClick( Mobile from )
{
from.Send( new MessageLocalizedAffix( Serial, ItemID, MessageType.Label, 0x3B2, 3, 1041361, "", AffixType.Append, String.Concat( " ", m_Worth.ToString() ), "" ) ); // A bank check:
}
public override void OnDoubleClick( Mobile from )
{
InnBox box = from.FindInnNoCreate();
if ( box != null && IsChildOf( box ) )
{
Delete();
int deposited = 0;
int toAdd = m_Worth;
Gold gold;
while ( toAdd > 60000 )
{
gold = new Gold( 60000 );
if ( box.TryDropItem( from, gold, false ) )
{
toAdd -= 60000;
deposited += 60000;
}
else
{
gold.Delete();
from.AddToBackpack( new GoldDeed( toAdd ) );
toAdd = 0;
break;
}
}
if ( toAdd > 0 )
{
gold = new Gold( toAdd );
if ( box.TryDropItem( from, gold, false ) )
{
deposited += toAdd;
}
else
{
gold.Delete();
from.AddToBackpack( new GoldDeed( toAdd ) );
}
}
// Gold was deposited in your account:
from.SendLocalizedMessage( 1042672, true, " " + deposited.ToString() );
}
else
{
from.SendLocalizedMessage( 1047026 ); // That must be in your inn chest to use it.
}
}
}
}

View file

@ -0,0 +1,115 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
{
public class Guillotine : Item
{
[Constructable]
public Guillotine()
: base( 4656 )
{
Movable = false;
}
private DateTime m_NextUse;
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( this.GetWorldLocation(), 2 ) || !from.InLOS( this ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that
}
else if ( Visible && ( ItemID == 4656 || ItemID == 4702 ) && DateTime.Now >= m_NextUse )
{
Point3D p = this.GetWorldLocation();
if ( 1 > Utility.Random( Math.Max( Math.Abs( from.X - p.X ), Math.Abs( from.Y - p.Y ) ) ) )
{
Effects.PlaySound( from.Location, from.Map, from.GetHurtSound() );
from.PublicOverheadMessage( MessageType.Regular, from.SpeechHue, true, "Ouch!" );
Spells.SpellHelper.Damage( TimeSpan.FromSeconds( 0.5 ), from, Utility.Dice( 2, 10, 5 ) );
}
Effects.PlaySound( this.GetWorldLocation(), this.Map, 0x387 );
Timer.DelayCall( TimeSpan.FromSeconds( 0.25 ), new TimerCallback( Down1 ) );
Timer.DelayCall( TimeSpan.FromSeconds( 0.50 ), new TimerCallback( Down2 ) );
Timer.DelayCall( TimeSpan.FromSeconds( 5.00 ), new TimerCallback( BackUp ) );
m_NextUse = DateTime.Now + TimeSpan.FromSeconds( 10.0 );
}
}
private void Down1()
{
ItemID = ( ItemID == 4656 ? 4678 : 4712 );
}
private void Down2()
{
ItemID = ( ItemID == 4678 ? 4679 : 4713 );
Point3D p = this.GetWorldLocation();
Map f = this.Map;
if ( f == null )
return;
new Blood( 4650 ).MoveToWorld( p, f );
for ( int i = 0; i < 4; ++i )
{
int x = p.X - 2 + Utility.Random( 5 );
int y = p.Y - 2 + Utility.Random( 5 );
int z = p.Z;
if ( !f.CanFit( x, y, z, 1, false, false, true ) )
{
z = f.GetAverageZ( x, y );
if ( !f.CanFit( x, y, z, 1, false, false, true ) )
continue;
}
new Blood().MoveToWorld( new Point3D( x, y, z ), f );
}
}
private void BackUp()
{
if ( ItemID == 4678 || ItemID == 4679 )
ItemID = 4656;
else if ( ItemID == 4712 || ItemID == 4713 )
ItemID = 4702;
}
public Guillotine( Serial serial )
: base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (byte) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadByte();
if ( ItemID == 4678 || ItemID == 4679 )
ItemID = 4656;
else if ( ItemID == 4712 || ItemID == 4713 )
ItemID = 4702;
}
}
}

View file

@ -0,0 +1,193 @@
using System;
using System.Text;
using Server.Gumps;
using Server.Network;
namespace Server.Items
{
public class HairDye : Item
{
public override int LabelNumber{ get{ return 1041060; } } // Hair Dye
[Constructable]
public HairDye() : base( 0xEFF )
{
Weight = 1.0;
}
public HairDye( 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 )
{
if ( from.InRange( this.GetWorldLocation(), 1 ) )
{
from.CloseGump( typeof( HairDyeGump ) );
from.SendGump( new HairDyeGump( this ) );
}
else
{
from.LocalOverheadMessage( MessageType.Regular, 906, 1019045 ); // I can't reach that.
}
}
}
public class HairDyeGump : Gump
{
private HairDye m_HairDye;
private class HairDyeEntry
{
private string m_Name;
private int m_HueStart;
private int m_HueCount;
public string Name
{
get
{
return m_Name;
}
}
public int HueStart
{
get
{
return m_HueStart;
}
}
public int HueCount
{
get
{
return m_HueCount;
}
}
public HairDyeEntry( string name, int hueStart, int hueCount )
{
m_Name = name;
m_HueStart = hueStart;
m_HueCount = hueCount;
}
}
private static HairDyeEntry[] m_Entries = new HairDyeEntry[]
{
new HairDyeEntry( "*****", 1602, 26 ),
new HairDyeEntry( "*****", 1628, 27 ),
new HairDyeEntry( "*****", 1502, 32 ),
new HairDyeEntry( "*****", 1302, 32 ),
new HairDyeEntry( "*****", 1402, 32 ),
new HairDyeEntry( "*****", 1202, 24 ),
new HairDyeEntry( "*****", 2402, 29 ),
new HairDyeEntry( "*****", 2213, 6 ),
new HairDyeEntry( "*****", 1102, 8 ),
new HairDyeEntry( "*****", 1110, 8 ),
new HairDyeEntry( "*****", 1118, 16 ),
new HairDyeEntry( "*****", 1134, 16 )
};
public HairDyeGump( HairDye dye ) : base( 50, 50 )
{
m_HairDye = dye;
AddPage( 0 );
AddBackground( 100, 10, 350, 355, 2600 );
AddBackground( 120, 54, 110, 270, 5100 );
AddHtmlLocalized( 70, 25, 400, 35, 1011013, false, false ); // <center>Hair Color Selection Menu</center>
AddButton( 149, 328, 4005, 4007, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 185, 329, 250, 35, 1011014, false, false ); // Dye my hair this color!
for ( int i = 0; i < m_Entries.Length; ++i )
{
AddLabel( 130, 59 + (i * 22), m_Entries[i].HueStart - 1, m_Entries[i].Name );
AddButton( 207, 60 + (i * 22), 5224, 5224, 0, GumpButtonType.Page, i + 1 );
}
for ( int i = 0; i < m_Entries.Length; ++i )
{
HairDyeEntry e = m_Entries[i];
AddPage( i + 1 );
for ( int j = 0; j < e.HueCount; ++j )
{
AddLabel( 278 + ((j / 16) * 80), 52 + ((j % 16) * 17), e.HueStart + j - 1, "*****" );
AddRadio( 260 + ((j / 16) * 80), 52 + ((j % 16) * 17), 210, 211, false, (i * 100) + j );
}
}
}
public override void OnResponse( NetState from, RelayInfo info )
{
if ( m_HairDye.Deleted )
return;
Mobile m = from.Mobile;
int[] switches = info.Switches;
if ( !m_HairDye.IsChildOf( m.Backpack ) )
{
m.SendLocalizedMessage( 1042010 ); //You must have the objectin your backpack to use it.
return;
}
if ( info.ButtonID != 0 && switches.Length > 0 )
{
if( m.HairItemID == 0 && m.FacialHairItemID == 0 )
{
m.SendLocalizedMessage( 502623 ); // You have no hair to dye and cannot use this
}
else
{
// To prevent this from being exploited, the hue is abstracted into an internal list
int entryIndex = switches[0] / 100;
int hueOffset = switches[0] % 100;
if ( entryIndex >= 0 && entryIndex < m_Entries.Length )
{
HairDyeEntry e = m_Entries[entryIndex];
if ( hueOffset >= 0 && hueOffset < e.HueCount )
{
int hue = e.HueStart + hueOffset;
m.HairHue = hue;
m.FacialHairHue = hue;
m.SendLocalizedMessage( 501199 ); // You dye your hair
m_HairDye.Delete();
m.PlaySound( 0x4E );
}
}
}
}
else
{
m.SendLocalizedMessage( 501200 ); // You decide not to dye your hair
}
}
}
}

View file

@ -0,0 +1,22 @@
using System;
using Server;
namespace Server.Items
{
interface IDurability
{
int InitMinHits { get; }
int InitMaxHits { get; }
int HitPoints { get; set; }
int MaxHitPoints { get; set; }
void ScaleDurability();
void UnscaleDurability();
}
interface IWearableDurability : IDurability
{
int OnHit( BaseWeapon weapon, int damageTaken );
}
}

469
Scripts/Items/Misc/Key.cs Normal file
View file

@ -0,0 +1,469 @@
using System;
using System.Collections;
using Server.Network;
using Server.Targeting;
using Server.Prompts;
using Server.Misc;
namespace Server.Items
{
public enum KeyType
{
Copper = 0x100E,
Gold = 0x100F,
Iron = 0x1010,
Rusty = 0x1013
}
public interface ILockable
{
bool Locked{ get; set; }
uint KeyValue{ get; set; }
}
public class Key : Item
{
private string m_Description;
private uint m_KeyVal;
private Item m_Link;
private int m_MaxRange;
public static uint RandomValue()
{
return (uint)(0xFFFFFFFE * Utility.RandomDouble()) + 1;
}
public static void RemoveKeys( Mobile m, uint keyValue )
{
if ( keyValue == 0 )
return;
RemoveKeys( m.Backpack, keyValue );
RemoveKeys( m.InnBox, keyValue );
}
public static void RemoveKeys( Container cont, uint keyValue )
{
if ( cont == null || keyValue == 0 )
return;
Item[] items = cont.FindItemsByType( new Type[] { typeof( Key ), typeof( KeyRing ) } );
foreach ( Item item in items )
{
if ( item is Key )
{
Key key = (Key) item;
if ( key.KeyValue == keyValue )
key.Delete();
}
else
{
KeyRing keyRing = (KeyRing) item;
keyRing.RemoveKeys( keyValue );
}
}
}
public static bool ContainsKey( Container cont, uint keyValue )
{
if ( cont == null )
return false;
Item[] items = cont.FindItemsByType( new Type[] { typeof( Key ), typeof( KeyRing ) } );
foreach ( Item item in items )
{
if ( item is Key )
{
Key key = (Key) item;
if ( key.KeyValue == keyValue )
return true;
}
else
{
KeyRing keyRing = (KeyRing) item;
if ( keyRing.ContainsKey( keyValue ) )
return true;
}
}
return false;
}
[CommandProperty( AccessLevel.GameMaster )]
public string Description
{
get
{
return m_Description;
}
set
{
m_Description = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxRange
{
get
{
return m_MaxRange;
}
set
{
m_MaxRange = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public uint KeyValue
{
get
{
return m_KeyVal;
}
set
{
m_KeyVal = value;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public Item Link
{
get
{
return m_Link;
}
set
{
m_Link = value;
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 2 ); // version
writer.Write( (int) m_MaxRange );
writer.Write( (Item) m_Link );
writer.Write( (string) m_Description );
writer.Write( (uint) m_KeyVal );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 2:
{
m_MaxRange = reader.ReadInt();
goto case 1;
}
case 1:
{
m_Link = reader.ReadItem();
goto case 0;
}
case 0:
{
if ( version < 2 || m_MaxRange == 0 )
m_MaxRange = 3;
m_Description = reader.ReadString();
m_KeyVal = reader.ReadUInt();
break;
}
}
}
[Constructable]
public Key() : this( KeyType.Iron, 0 )
{
}
[Constructable]
public Key( KeyType type ) : this( type, 0 )
{
}
[Constructable]
public Key( uint val ) : this ( KeyType.Iron, val )
{
}
[Constructable]
public Key( KeyType type, uint LockVal ) : this( type, LockVal, null )
{
m_KeyVal = LockVal;
}
public Key( KeyType type, uint LockVal, Item link ) : base( (int)type )
{
Weight = 1.0;
m_MaxRange = 3;
m_KeyVal = LockVal;
m_Link = link;
}
public Key( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
if ( !this.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 501661 ); // That key is unreachable.
return;
}
Target t;
int number;
if ( m_KeyVal != 0 )
{
number = 501662; // What shall I use this key on?
t = new UnlockTarget( this );
}
else
{
number = 501663; // This key is a key blank. Which key would you like to make a copy of?
t = new CopyTarget( this );
}
from.SendLocalizedMessage( number );
from.Target = t;
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
string desc;
if ( m_KeyVal == 0 )
desc = "(blank)";
else if ( (desc = m_Description) == null || (desc = desc.Trim()).Length <= 0 )
desc = null;
if ( desc != null )
list.Add( desc );
}
public override void OnSingleClick( Mobile from )
{
base.OnSingleClick( from );
string desc;
if ( m_KeyVal == 0 )
desc = "(blank)";
else if ( (desc = m_Description) == null || (desc = desc.Trim()).Length <= 0 )
desc = "";
if ( desc.Length > 0 )
from.Send( new UnicodeMessage( Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", "", desc ) );
}
public bool UseOn( Mobile from, ILockable o )
{
if ( o.KeyValue == this.KeyValue )
{
if ( o is BaseDoor && !((BaseDoor)o).UseLocks() )
{
return false;
}
else
{
o.Locked = !o.Locked;
if ( o is LockableContainer )
{
LockableContainer cont = (LockableContainer)o;
if ( cont.LockLevel == -255 )
cont.LockLevel = cont.RequiredSkill - 10;
}
if ( o is Item )
{
Item item = (Item) o;
if ( o.Locked )
item.SendLocalizedMessageTo( from, 1048000 ); // You lock it.
else
item.SendLocalizedMessageTo( from, 1048001 ); // You unlock it.
if ( item is LockableContainer )
{
LockableContainer cont = (LockableContainer) item;
if ( cont.TrapType != TrapType.None && cont.TrapOnLockpick )
{
if ( o.Locked )
item.SendLocalizedMessageTo( from, 501673 ); // You re-enable the trap.
else
item.SendLocalizedMessageTo( from, 501672 ); // You disable the trap temporarily. Lock it again to re-enable it.
}
}
}
return true;
}
}
else
{
return false;
}
}
private class RenamePrompt : Prompt
{
private Key m_Key;
public RenamePrompt( Key key )
{
m_Key = key;
}
public override void OnResponse( Mobile from, string text )
{
if ( m_Key.Deleted || !m_Key.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 501661 ); // That key is unreachable.
return;
}
m_Key.Description = Utility.FixHtml( text );
}
}
private class UnlockTarget : Target
{
private Key m_Key;
public UnlockTarget( Key key ) : base( key.MaxRange, false, TargetFlags.None )
{
m_Key = key;
CheckLOS = false;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_Key.Deleted || !m_Key.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 501661 ); // That key is unreachable.
return;
}
int number;
if ( targeted == m_Key )
{
number = 501665; // Enter a description for this key.
from.Prompt = new RenamePrompt( m_Key );
}
else if ( targeted is ILockable )
{
if ( m_Key.UseOn( from, (ILockable) targeted ) )
number = -1;
else
number = 501668; // This key doesn't seem to unlock that.
}
else
{
number = 501666; // You can't unlock that!
}
if ( number != -1 )
{
from.SendLocalizedMessage( number );
}
}
}
private class CopyTarget : Target
{
private Key m_Key;
public CopyTarget( Key key ) : base( 3, false, TargetFlags.None )
{
m_Key = key;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_Key.Deleted || !m_Key.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 501661 ); // That key is unreachable.
return;
}
int number;
if ( targeted is Key )
{
Key k = (Key)targeted;
if ( k.m_KeyVal == 0 )
{
number = 501675; // This key is also blank.
}
else if ( SkillCheck.TestTrade( from, Trades.Tinkering, 0, 75.0 ) )
{
number = 501676; // You make a copy of the key.
m_Key.Description = k.Description;
m_Key.KeyValue = k.KeyValue;
m_Key.Link = k.Link;
m_Key.MaxRange = k.MaxRange;
}
else if ( Utility.RandomDouble() <= 0.1 ) // 10% chance to destroy the key
{
from.SendLocalizedMessage( 501677 ); // You fail to make a copy of the key.
number = 501678; // The key was destroyed in the attempt.
m_Key.Delete();
}
else
{
number = 501677; // You fail to make a copy of the key.
}
}
else
{
number = 501688; // Not a key.
}
from.SendLocalizedMessage( number );
}
}
}
}

View file

@ -0,0 +1,207 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
using System.Collections.Generic;
namespace Server.Items
{
public class KeyRing : Item
{
public static readonly int MaxKeys = 20;
private List<Key> m_Keys;
public List<Key> Keys { get { return m_Keys; } }
[Constructable]
public KeyRing() : base( 0x1011 )
{
Weight = 1.0; // They seem to have no weight on OSI ?!
m_Keys = new List<Key>();
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
if ( !this.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1060640 ); // The item must be in your backpack to use it.
return false;
}
Key key = dropped as Key;
if ( key == null || key.KeyValue == 0 )
{
from.SendLocalizedMessage( 501689 ); // Only non-blank keys can be put on a keyring.
return false;
}
else if ( this.Keys.Count >= MaxKeys )
{
from.SendLocalizedMessage( 1008138 ); // This keyring is full.
return false;
}
else
{
Add( key );
from.SendLocalizedMessage( 501691 ); // You put the key on the keyring.
return true;
}
}
public override void OnDoubleClick( Mobile from )
{
if ( !this.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1060640 ); // The item must be in your backpack to use it.
return;
}
from.SendLocalizedMessage( 501680 ); // What do you want to unlock?
from.Target = new InternalTarget( this );
}
private class InternalTarget : Target
{
private KeyRing m_KeyRing;
public InternalTarget( KeyRing keyRing ) : base( -1, false, TargetFlags.None )
{
m_KeyRing = keyRing;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( m_KeyRing.Deleted || !m_KeyRing.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1060640 ); // The item must be in your backpack to use it.
return;
}
if ( m_KeyRing == targeted )
{
m_KeyRing.Open( from );
from.SendLocalizedMessage( 501685 ); // You open the keyring.
}
else if ( targeted is ILockable )
{
ILockable o = (ILockable) targeted;
foreach ( Key key in m_KeyRing.Keys )
{
if ( key.UseOn( from, o ) )
return;
}
from.SendLocalizedMessage( 1008140 ); // You do not have a key for that.
}
else
{
from.SendLocalizedMessage( 501666 ); // You can't unlock that!
}
}
}
public override void OnDelete()
{
base.OnDelete();
foreach ( Key key in m_Keys )
{
key.Delete();
}
m_Keys.Clear();
}
public void Add( Key key )
{
key.Internalize();
m_Keys.Add( key );
UpdateItemID();
}
public void Open( Mobile from )
{
Container cont = this.Parent as Container;
if ( cont == null )
return;
for ( int i = m_Keys.Count - 1; i >= 0; i-- )
{
Key key = m_Keys[i];
if ( !key.Deleted && !cont.TryDropItem( from, key, true ) )
break;
m_Keys.RemoveAt( i );
}
UpdateItemID();
}
public void RemoveKeys( uint keyValue )
{
for ( int i = m_Keys.Count - 1; i >= 0; i-- )
{
Key key = m_Keys[i];
if ( key.KeyValue == keyValue )
{
key.Delete();
m_Keys.RemoveAt( i );
}
}
UpdateItemID();
}
public bool ContainsKey( uint keyValue )
{
foreach ( Key key in m_Keys )
{
if ( key.KeyValue == keyValue )
return true;
}
return false;
}
private void UpdateItemID()
{
if ( this.Keys.Count < 1 )
this.ItemID = 0x1011;
else if ( this.Keys.Count < 3 )
this.ItemID = 0x1769;
else if ( this.Keys.Count < 5 )
this.ItemID = 0x176A;
else
this.ItemID = 0x176B;
}
public KeyRing( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
writer.WriteItemList<Key>( m_Keys );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_Keys = reader.ReadStrongItemList<Key>();
}
}
}

View file

@ -0,0 +1,119 @@
using System;
using Server;
using Server.Network;
namespace Server.Items
{
public class LOSBlocker : Item
{
public static void Initialize()
{
TileData.ItemTable[0x21A2].Flags = TileFlag.Wall | TileFlag.NoShoot;
TileData.ItemTable[0x21A2].Height = 20;
}
public override string DefaultName
{
get { return "no line of sight"; }
}
[Constructable]
public LOSBlocker() : base( 0x21A2 )
{
Movable = false;
}
public LOSBlocker( Serial serial ) : base( serial )
{
}
protected override Packet GetWorldPacketFor( NetState state ) {
Mobile mob = state.Mobile;
if ( mob != null && mob.AccessLevel >= AccessLevel.GameMaster ) {
return new GMItemPacket( this );
}
return base.GetWorldPacketFor( state );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 1 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
if ( version < 1 && ItemID == 0x2199 )
this.ItemID = 0x21A2;
}
public sealed class GMItemPacket : Packet
{
public GMItemPacket( Item item ) : base( 0x1A )
{
this.EnsureCapacity( 20 );
// 14 base length
// +2 - Amount
// +2 - Hue
// +1 - Flags
uint serial = (uint)item.Serial.Value;
int itemID = 0x36FF;
int amount = item.Amount;
Point3D loc = item.Location;
int x = loc.X;
int y = loc.Y;
int hue = item.Hue;
int flags = item.GetPacketFlags();
int direction = (int)item.Direction;
if ( amount != 0 )
serial |= 0x80000000;
else
serial &= 0x7FFFFFFF;
m_Stream.Write( (uint) serial );
m_Stream.Write( (short) (itemID & 0x7FFF) );
if ( amount != 0 )
m_Stream.Write( (short) amount );
x &= 0x7FFF;
if ( direction != 0 )
x |= 0x8000;
m_Stream.Write( (short) x );
y &= 0x3FFF;
if ( hue != 0 )
y |= 0x8000;
if ( flags != 0 )
y |= 0x4000;
m_Stream.Write( (short) y );
if ( direction != 0 )
m_Stream.Write( (byte) direction );
m_Stream.Write( (sbyte) loc.Z );
if ( hue != 0 )
m_Stream.Write( (ushort) hue );
if ( flags != 0 )
m_Stream.Write( (byte) flags );
}
}
}
}

View file

@ -0,0 +1,63 @@
using System;
using Server;
using Server.Mobiles;
using Server.Misc;
using Server.Network;
namespace Server.Items
{
public class Moongate : Item
{
[Constructable]
public Moongate() : base(0x0F6C)
{
Movable = false;
Name = "moongate";
Light = LightType.Circle300;
}
public Moongate(Serial serial) : base(serial)
{
}
public override bool OnMoveOver( Mobile m )
{
Point3D loc = new Point3D( 2030, 1631, 8 );
if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.NewMoon ) // MOONGLOW
loc = new Point3D( 3958, 2034, 2 );
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.WaxingCrescentMoon ) // BRITAIN
loc = new Point3D( 2030, 1631, 8 );
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.FirstQuarter ) // JHELOM
loc = new Point3D( 1173, 3251, 3 );
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.WaxingGibbous ) // YEW
loc = new Point3D( 1322, 743, 2 );
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.FullMoon ) // MINOC
loc = new Point3D( 3031, 462, 2 );
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.WaningGibbous ) // TRINSIC
loc = new Point3D( 2065, 2828, 2 );
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.LastQuarter ) // SKARA BRAE
loc = new Point3D( 790, 1949, 2 );
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.WaningCrescent ) // MAGINCIA
loc = new Point3D( 3354, 2551, 12 );
BaseCreature.TeleportPets( m, loc, Map.Britannia, false );
m.MoveToWorld ( loc, Map.Britannia );
m.PlaySound( 0x1FE );
return false;
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,146 @@
using System;
namespace Server.Items
{
public class MorphItem : Item
{
private int m_InactiveItemID;
private int m_ActiveItemID;
private int m_InRange;
private int m_OutRange;
[CommandProperty( AccessLevel.GameMaster )]
public int InactiveItemID
{
get{ return m_InactiveItemID; }
set{ m_InactiveItemID = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int ActiveItemID
{
get{ return m_ActiveItemID; }
set{ m_ActiveItemID = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int InRange
{
get{ return m_InRange; }
set{ if ( value > 18 ) value = 18; m_InRange = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int OutRange
{
get{ return m_OutRange; }
set{ if ( value > 18 ) value = 18; m_OutRange = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int CurrentRange{ get{ return ItemID == InactiveItemID ? InRange : OutRange; } }
[Constructable]
public MorphItem( int inactiveItemID, int activeItemID, int range ) : this( inactiveItemID, activeItemID, range, range )
{
}
[Constructable]
public MorphItem( int inactiveItemID, int activeItemID, int inRange, int outRange ) : base( inactiveItemID )
{
Movable = false;
InactiveItemID = inactiveItemID;
ActiveItemID = activeItemID;
InRange = inRange;
OutRange = outRange;
}
public MorphItem( Serial serial ) : base( serial )
{
}
public override bool HandlesOnMovement{ get{ return true; } }
public override void OnMovement( Mobile m, Point3D oldLocation )
{
if ( Utility.InRange( m.Location, Location, CurrentRange ) || Utility.InRange( oldLocation, Location, CurrentRange ) )
Refresh();
}
public override void OnMapChange()
{
if ( !Deleted )
Refresh();
}
public override void OnLocationChange( Point3D oldLoc )
{
if ( !Deleted )
Refresh();
}
public void Refresh()
{
bool found = false;
foreach ( Mobile mob in GetMobilesInRange( CurrentRange ) )
{
if ( mob.Hidden && mob.AccessLevel > AccessLevel.Player )
continue;
found = true;
break;
}
if ( found )
ItemID = ActiveItemID;
else
ItemID = InactiveItemID;
Visible = ( ItemID != 0x1 );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 1 ); // version
writer.Write( (int) m_OutRange );
writer.Write( (int) m_InactiveItemID );
writer.Write( (int) m_ActiveItemID );
writer.Write( (int) m_InRange );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 1:
{
m_OutRange = reader.ReadInt();
goto case 0;
}
case 0:
{
m_InactiveItemID = reader.ReadInt();
m_ActiveItemID = reader.ReadInt();
m_InRange = reader.ReadInt();
if ( version < 1 )
m_OutRange = m_InRange;
break;
}
}
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( Refresh ) );
}
}
}

View file

@ -0,0 +1,111 @@
using System;
using Server;
using Server.Mobiles;
using Server.Targeting;
namespace Server.Items
{
public class OilCloth : Item, IScissorable, IDyable
{
public override int LabelNumber{ get{ return 1041498; } } // oil cloth
public override double DefaultWeight
{
get { return 1.0; }
}
[Constructable]
public OilCloth() : base( 0x175D )
{
Hue = 2001;
}
public bool Dye( Mobile from, DyeTub sender )
{
if ( Deleted )
return false;
Hue = sender.DyedHue;
return true;
}
public bool Scissor( Mobile from, Scissors scissors )
{
if ( Deleted || !from.CanSee( this ) )
return false;
base.ScissorHelper( from, new Bandage(), 1 );
return true;
}
public override void OnDoubleClick( Mobile from )
{
if ( IsChildOf( from.Backpack ) )
{
from.BeginTarget( -1, false, TargetFlags.None, new TargetCallback( OnTarget ) );
from.SendLocalizedMessage( 1005424 ); // Select the weapon or armor you wish to use the cloth on.
}
else
{
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
}
}
public void OnTarget( Mobile from, object obj )
{
if ( !IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
}
else if ( obj is BaseWeapon )
{
BaseWeapon weapon = (BaseWeapon)obj;
if ( weapon.RootParent != from )
{
from.SendLocalizedMessage( 1005425 ); // You may only wipe down items you are holding or carrying.
}
else if ( weapon.Poison == null || weapon.PoisonCharges <= 0 )
{
from.LocalOverheadMessage( Network.MessageType.Regular, 0x3B2, 1005422 ); // Hmmmm... this does not need to be cleaned.
}
else
{
if ( weapon.PoisonCharges < 2 )
weapon.PoisonCharges = 0;
else
weapon.PoisonCharges -= 2;
if ( weapon.PoisonCharges > 0 )
from.SendLocalizedMessage( 1005423 ); // You have removed some of the caustic substance, but not all.
else
from.SendLocalizedMessage( 1010497 ); // You have cleaned the item.
}
}
else
{
from.SendLocalizedMessage( 1005426 ); // The cloth will not work on that.
}
}
public OilCloth( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
}

View file

@ -0,0 +1,437 @@
using System;
using Server;
namespace Server.Items
{
[Furniture]
public class HousePlantA : Item
{
[Constructable]
public HousePlantA() : base( 0x18B8 )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantA( 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();
}
}
[Furniture]
public class HousePlantB : Item
{
[Constructable]
public HousePlantB() : base( 0x18B9 )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantB( 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();
}
}
[Furniture]
public class HousePlantC : Item
{
[Constructable]
public HousePlantC() : base( 0x18BA )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantC( 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();
}
}
[Furniture]
public class HousePlantD : Item
{
[Constructable]
public HousePlantD() : base( 0x18BB )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantD( 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();
}
}
[Furniture]
public class HousePlantE : Item
{
[Constructable]
public HousePlantE() : base( 0x18BC )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantE( 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();
}
}
[Furniture]
public class HousePlantF : Item
{
[Constructable]
public HousePlantF() : base( 0x18BD )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantF( 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();
}
}
[Furniture]
public class HousePlantG : Item
{
[Constructable]
public HousePlantG() : base( 0x18BE )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantG( 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();
}
}
[Furniture]
public class HousePlantH : Item
{
[Constructable]
public HousePlantH() : base( 0x18BF )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantH( 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();
}
}
[Furniture]
public class HousePlantI : Item
{
[Constructable]
public HousePlantI() : base( 0x18C0 )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantI( 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();
}
}
[Furniture]
public class HousePlantJ : Item
{
[Constructable]
public HousePlantJ() : base( 0x18C1 )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantJ( 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();
}
}
[Furniture]
public class HousePlantK : Item
{
[Constructable]
public HousePlantK() : base( 0x18C2 )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantK( 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();
}
}
[Furniture]
public class HousePlantL : Item
{
[Constructable]
public HousePlantL() : base( 0x18C3 )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantL( 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();
}
}
[Furniture]
public class HousePlantM : Item
{
[Constructable]
public HousePlantM() : base( 0x18C4 )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantM( 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();
}
}
[Furniture]
public class HousePlantN : Item
{
[Constructable]
public HousePlantN() : base( 0x18C5 )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantN( 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();
}
}
[Furniture]
public class HousePlantO : Item
{
[Constructable]
public HousePlantO() : base( 0x18C6 )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantO( 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();
}
}
[Furniture]
public class HousePlantP : Item
{
[Constructable]
public HousePlantP() : base( 0x18C7 )
{
Name = "plant";
Weight = 10.0;
}
public HousePlantP( 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();
}
}
}

View file

@ -0,0 +1,640 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Gumps;
using Server.Multis;
using Server.Prompts;
using Server.Mobiles;
using Server.Network;
using Server.ContextMenus;
namespace Server.Items
{
public class PlayerBBSouth : BasePlayerBB
{
public override int LabelNumber{ get{ return 1062421; } } // bulletin board (south)
[Constructable]
public PlayerBBSouth() : base( 0x2311 )
{
Weight = 15.0;
}
public PlayerBBSouth( 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 PlayerBBEast : BasePlayerBB
{
public override int LabelNumber{ get{ return 1062420; } } // bulletin board (east)
[Constructable]
public PlayerBBEast() : base( 0x2312 )
{
Weight = 15.0;
}
public PlayerBBEast( 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 abstract class BasePlayerBB : Item, ISecurable
{
private PlayerBBMessage m_Greeting;
private List<PlayerBBMessage> m_Messages;
private string m_Title;
private SecureLevel m_Level;
public List<PlayerBBMessage> Messages
{
get{ return m_Messages; }
}
public PlayerBBMessage Greeting
{
get{ return m_Greeting; }
set{ m_Greeting = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public string Title
{
get{ return m_Title; }
set{ m_Title = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public SecureLevel Level
{
get{ return m_Level; }
set{ m_Level = value; }
}
public BasePlayerBB( int itemID ) : base( itemID )
{
m_Messages = new List<PlayerBBMessage>();
m_Level = SecureLevel.Anyone;
}
public BasePlayerBB( Serial serial ) : base( serial )
{
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
SetSecureLevelEntry.AddTo( from, this, list );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 1 );
writer.Write( (int) m_Level );
writer.Write( m_Title );
if ( m_Greeting != null )
{
writer.Write( true );
m_Greeting.Serialize( writer );
}
else
{
writer.Write( false );
}
writer.WriteEncodedInt( m_Messages.Count );
for ( int i = 0; i < m_Messages.Count; ++i )
m_Messages[i].Serialize( writer );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 1:
{
m_Level = (SecureLevel)reader.ReadInt();
goto case 0;
}
case 0:
{
if ( version < 1 )
m_Level = SecureLevel.Anyone;
m_Title = reader.ReadString();
if ( reader.ReadBool() )
m_Greeting = new PlayerBBMessage( reader );
int count = reader.ReadEncodedInt();
m_Messages = new List<PlayerBBMessage>( count );
for ( int i = 0; i < count; ++i )
m_Messages.Add( new PlayerBBMessage( reader ) );
break;
}
}
}
public static bool CheckAccess( BaseHouse house, Mobile from )
{
if ( house.Public || !house.IsAosRules )
return !house.IsBanned( from );
return house.HasAccess( from );
}
public override void OnDoubleClick( Mobile from )
{
BaseHouse house = BaseHouse.FindHouseAt( this );
if ( house == null || !house.IsLockedDown( this ) )
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
else if ( !from.InRange( this.GetWorldLocation(), 2 ) || !from.InLOS( this ) )
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
else if ( CheckAccess( house, from ) )
from.SendGump( new PlayerBBGump( from, house, this, 0 ) );
}
public class PostPrompt : Prompt
{
private int m_Page;
private BaseHouse m_House;
private BasePlayerBB m_Board;
private bool m_Greeting;
public PostPrompt( int page, BaseHouse house, BasePlayerBB board, bool greeting )
{
m_Page = page;
m_House = house;
m_Board = board;
m_Greeting = greeting;
}
public override void OnCancel( Mobile from )
{
OnResponse( from, "" );
}
public override void OnResponse( Mobile from, string text )
{
int page = m_Page;
BaseHouse house = m_House;
BasePlayerBB board = m_Board;
if ( house == null || !house.IsLockedDown( board ) )
{
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
return;
}
else if ( !from.InRange( board.GetWorldLocation(), 2 ) || !from.InLOS( board ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
return;
}
else if ( !CheckAccess( house, from ) )
{
from.SendLocalizedMessage( 1062398 ); // You are not allowed to post to this bulletin board.
return;
}
else if ( m_Greeting && !house.IsOwner( from ) )
{
return;
}
text = text.Trim();
if ( text.Length > 255 )
text = text.Substring( 0, 255 );
if ( text.Length > 0 )
{
PlayerBBMessage message = new PlayerBBMessage( DateTime.Now, from, text );
if ( m_Greeting )
{
board.Greeting = message;
}
else
{
board.Messages.Add( message );
if ( board.Messages.Count > 50 )
{
board.Messages.RemoveAt( 0 );
if ( page > 0 )
--page;
}
}
}
from.SendGump( new PlayerBBGump( from, house, board, page ) );
}
}
public class SetTitlePrompt : Prompt
{
private int m_Page;
private BaseHouse m_House;
private BasePlayerBB m_Board;
public SetTitlePrompt( int page, BaseHouse house, BasePlayerBB board )
{
m_Page = page;
m_House = house;
m_Board = board;
}
public override void OnCancel( Mobile from )
{
OnResponse( from, "" );
}
public override void OnResponse( Mobile from, string text )
{
int page = m_Page;
BaseHouse house = m_House;
BasePlayerBB board = m_Board;
if ( house == null || !house.IsLockedDown( board ) )
{
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
return;
}
else if ( !from.InRange( board.GetWorldLocation(), 2 ) || !from.InLOS( board ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
return;
}
else if ( !CheckAccess( house, from ) )
{
from.SendLocalizedMessage( 1062398 ); // You are not allowed to post to this bulletin board.
return;
}
text = text.Trim();
if ( text.Length > 255 )
text = text.Substring( 0, 255 );
if ( text.Length > 0 )
board.Title = text;
from.SendGump( new PlayerBBGump( from, house, board, page ) );
}
}
}
public class PlayerBBMessage
{
private DateTime m_Time;
private Mobile m_Poster;
private string m_Message;
[CommandProperty( AccessLevel.GameMaster )]
public DateTime Time
{
get{ return m_Time; }
set{ m_Time = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Poster
{
get{ return m_Poster; }
set{ m_Poster = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public string Message
{
get{ return m_Message; }
set{ m_Message = value; }
}
public PlayerBBMessage( DateTime time, Mobile poster, string message )
{
m_Time = time;
m_Poster = poster;
m_Message = message;
}
public PlayerBBMessage( GenericReader reader )
{
int version = reader.ReadEncodedInt();
switch ( version )
{
case 0:
{
m_Time = reader.ReadDateTime();
m_Poster = reader.ReadMobile();
m_Message = reader.ReadString();
break;
}
}
}
public void Serialize( GenericWriter writer )
{
writer.WriteEncodedInt( 0 ); // version
writer.Write( m_Time );
writer.Write( m_Poster );
writer.Write( m_Message );
}
}
public class PlayerBBGump : Gump
{
private int m_Page;
private Mobile m_From;
private BaseHouse m_House;
private BasePlayerBB m_Board;
private const int LabelColor = 0x7FFF;
private const int LabelHue = 1153;
public override void OnResponse( NetState sender, RelayInfo info )
{
int page = m_Page;
Mobile from = m_From;
BaseHouse house = m_House;
BasePlayerBB board = m_Board;
if ( house == null || !house.IsLockedDown( board ) )
{
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
return;
}
else if ( !from.InRange( board.GetWorldLocation(), 2 ) || !from.InLOS( board ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
return;
}
else if ( !BasePlayerBB.CheckAccess( house, from ) )
{
from.SendLocalizedMessage( 1062398 ); // You are not allowed to post to this bulletin board.
return;
}
switch ( info.ButtonID )
{
case 1: // Post message
{
from.Prompt = new BasePlayerBB.PostPrompt( page, house, board, false );
from.SendLocalizedMessage( 1062397 ); // Please enter your message:
break;
}
case 2: // Set title
{
if ( house.IsOwner( from ) )
{
from.Prompt = new BasePlayerBB.SetTitlePrompt( page, house, board );
from.SendLocalizedMessage( 1062402 ); // Enter new title:
}
break;
}
case 3: // Post greeting
{
if ( house.IsOwner( from ) )
{
from.Prompt = new BasePlayerBB.PostPrompt( page, house, board, true );
from.SendLocalizedMessage( 1062404 ); // Enter new greeting (this will always be the first post):
}
break;
}
case 4: // Scroll up
{
if ( page == 0 )
page = board.Messages.Count;
else
page -= 1;
from.SendGump( new PlayerBBGump( from, house, board, page ) );
break;
}
case 5: // Scroll down
{
page += 1;
page %= board.Messages.Count + 1;
from.SendGump( new PlayerBBGump( from, house, board, page ) );
break;
}
case 6: // Banish poster
{
if ( house.IsOwner( from ) )
{
if ( page >= 1 && page <= board.Messages.Count )
{
PlayerBBMessage message = (PlayerBBMessage)board.Messages[page - 1];
Mobile poster = message.Poster;
if ( poster == null )
{
from.SendGump( new PlayerBBGump( from, house, board, page ) );
return;
}
if ( poster.AccessLevel > AccessLevel.Player && from.AccessLevel <= poster.AccessLevel )
{
from.SendLocalizedMessage( 501354 ); // Uh oh...a bigger boot may be required.
}
else if ( house.IsFriend( poster ) )
{
from.SendLocalizedMessage( 1060750 ); // That person is a friend, co-owner, or owner of this house, and therefore cannot be banished!
}
else if ( poster is PlayerVendor )
{
from.SendLocalizedMessage( 501351 ); // You cannot eject a vendor.
}
else if ( house.Bans.Count >= BaseHouse.MaxBans )
{
from.SendLocalizedMessage( 501355 ); // The ban limit for this house has been reached!
}
else if ( house.IsBanned( poster ) )
{
from.SendLocalizedMessage( 501356 ); // This person is already banned!
}
else if ( poster is BaseCreature && ((BaseCreature)poster).NoHouseRestrictions )
{
from.SendLocalizedMessage( 1062040 ); // You cannot ban that.
}
else
{
if ( !house.Bans.Contains( poster ) )
house.Bans.Add( poster );
from.SendLocalizedMessage( 1062417 ); // That person has been banned from this house.
if ( house.IsInside( poster ) && !BasePlayerBB.CheckAccess( house, poster ) )
poster.MoveToWorld( house.BanLocation, house.Map );
}
}
from.SendGump( new PlayerBBGump( from, house, board, page ) );
}
break;
}
case 7: // Delete message
{
if ( house.IsOwner( from ) )
{
if ( page >= 1 && page <= board.Messages.Count )
board.Messages.RemoveAt( page - 1 );
from.SendGump( new PlayerBBGump( from, house, board, 0 ) );
}
break;
}
case 8: // Post props
{
if ( from.AccessLevel >= AccessLevel.GameMaster )
{
PlayerBBMessage message = board.Greeting;
if ( page >= 1 && page <= board.Messages.Count )
message = (PlayerBBMessage)board.Messages[page - 1];
from.SendGump( new PlayerBBGump( from, house, board, page ) );
from.SendGump( new PropertiesGump( from, message ) );
}
break;
}
}
}
public PlayerBBGump( Mobile from, BaseHouse house, BasePlayerBB board, int page ) : base( 50, 10 )
{
from.CloseGump( typeof( PlayerBBGump ) );
m_Page = page;
m_From = from;
m_House = house;
m_Board = board;
AddPage( 0 );
AddImage( 30, 30, 5400 );
AddButton( 393, 145, 2084, 2084, 4, GumpButtonType.Reply, 0 ); // Scroll up
AddButton( 390, 371, 2085, 2085, 5, GumpButtonType.Reply, 0 ); // Scroll down
AddButton( 32, 183, 5412, 5413, 1, GumpButtonType.Reply, 0 ); // Post message
if ( house.IsOwner( from ) )
{
AddButton( 63, 90, 5601, 5605, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 81, 89, 230, 20, 1062400, LabelColor, false, false ); // Set title
AddButton( 63, 109, 5601, 5605, 3, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 81, 108, 230, 20, 1062401, LabelColor, false, false ); // Post greeting
}
string title = board.Title;
if ( title != null )
AddHtml( 183, 68, 180, 23, title, false, false );
AddHtmlLocalized( 385, 89, 60, 20, 1062409, LabelColor, false, false ); // Post
AddLabel( 440, 89, LabelHue, page.ToString() );
AddLabel( 455, 89, LabelHue, "/" );
AddLabel( 470, 89, LabelHue, board.Messages.Count.ToString() );
PlayerBBMessage message = board.Greeting;
if ( page >= 1 && page <= board.Messages.Count )
message = (PlayerBBMessage)board.Messages[page - 1];
AddImageTiled( 150, 220, 240, 1, 2700 ); // Separator
AddHtmlLocalized( 150, 180, 100, 20, 1062405, 16715, false, false ); // Posted On:
AddHtmlLocalized( 150, 200, 100, 20, 1062406, 16715, false, false ); // Posted By:
if ( message != null )
{
AddHtml( 255, 180, 150, 20, message.Time.ToString( "yyyy-MM-dd HH:mm:ss" ), false, false );
Mobile poster = message.Poster;
string name = ( poster == null ? null : poster.Name );
if ( name == null || (name = name.Trim()).Length == 0 )
name = "Someone";
AddHtml( 255, 200, 150, 20, name, false, false );
string body = message.Message;
if ( body == null )
body = "";
AddHtml( 150, 240, 250, 100, body, false, false );
if ( message != board.Greeting && house.IsOwner( from ) )
{
AddButton( 130, 395, 1209, 1210, 6, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 150, 393, 150, 20, 1062410, LabelColor, false, false ); // Banish Poster
AddButton( 310, 395, 1209, 1210, 7, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 330, 393, 150, 20, 1062411, LabelColor, false, false ); // Delete Message
}
if ( from.AccessLevel >= AccessLevel.GameMaster )
AddButton( 135, 242, 1209, 1210, 8, GumpButtonType.Reply, 0 ); // Post props
}
}
}
}

View file

@ -0,0 +1,101 @@
using System;
using Server;
using Server.Mobiles;
using Server.Spells;
using System.Collections;
using System.Collections.Generic;
namespace Server.Items
{
public class PoolOfAcid : Item
{
private TimeSpan m_Duration;
private int m_MinDamage;
private int m_MaxDamage;
private DateTime m_Created;
private bool m_Drying;
private Timer m_Timer;
[Constructable]
public PoolOfAcid() : this( TimeSpan.FromSeconds( 10.0 ), 2, 5 )
{
}
public override string DefaultName { get { return "a pool of acid"; } }
[Constructable]
public PoolOfAcid( TimeSpan duration, int minDamage, int maxDamage )
: base( 0x122A )
{
Hue = 0x3F;
Movable = false;
m_MinDamage = minDamage;
m_MaxDamage = maxDamage;
m_Created = DateTime.Now;
m_Duration = duration;
m_Timer = Timer.DelayCall( TimeSpan.Zero, TimeSpan.FromSeconds( 1 ), new TimerCallback( OnTick ) );
}
public override void OnAfterDelete()
{
if( m_Timer != null )
m_Timer.Stop();
}
private void OnTick()
{
DateTime now = DateTime.Now;
TimeSpan age = now - m_Created;
if( age > m_Duration ) {
Delete();
} else {
if( !m_Drying && age > (m_Duration - age) )
{
m_Drying = true;
ItemID = 0x122B;
}
List<Mobile> toDamage = new List<Mobile>();
foreach( Mobile m in GetMobilesInRange( 0 ) )
{
BaseCreature bc = m as BaseCreature;
if( m.Alive && !m.IsDeadBondedPet && (bc == null || bc.Controlled || bc.Summoned) )
{
toDamage.Add( m );
}
}
for ( int i = 0; i < toDamage.Count; i++ )
Damage( toDamage[i] );
}
}
public override bool OnMoveOver( Mobile m )
{
Damage( m );
return true;
}
public void Damage ( Mobile m )
{
m.Damage( Utility.RandomMinMax( m_MinDamage, m_MaxDamage ) );
}
public PoolOfAcid( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
//Don't serialize these
}
public override void Deserialize( GenericReader reader )
{
}
}
}

View file

@ -0,0 +1,93 @@
using System;
using Server.Network;
using Server.Targeting;
namespace Server.Items
{
public class Scales : Item
{
[Constructable]
public Scales() : base( 0x1852 )
{
Weight = 4.0;
}
public Scales( 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 )
{
from.SendLocalizedMessage( 502431 ); // What would you like to weigh?
from.Target = new InternalTarget( this );
}
private class InternalTarget : Target
{
private Scales m_Item;
public InternalTarget( Scales item ) : base( 1, false, TargetFlags.None )
{
m_Item = item;
}
protected override void OnTarget( Mobile from, object targeted )
{
string message;
if ( targeted == m_Item )
{
message = "It cannot weight itself.";
}
else if ( targeted is Item )
{
Item item = (Item)targeted;
object root = item.RootParent;
if ( (root != null && root != from) || item.Parent == from )
{
message = "You decide that item's current location is too awkward to get an accurate result.";
}
else if ( item.Movable )
{
if ( item.Amount > 1 )
message = "You place one item on the scale. ";
else
message = "You place that item on the scale. ";
double weight = item.Weight;
if ( weight <= 0.0 )
message += "It is lighter than a feather.";
else
message += String.Format( "It weighs {0} stones.", weight );
}
else
{
message = "You cannot weigh that object.";
}
}
else
{
message = "You cannot weigh that object.";
}
from.SendMessage( message );
}
}
}
}

View file

@ -0,0 +1,185 @@
using System;
using System.Text;
using Server.Gumps;
using Server.Network;
namespace Server.Items
{
public class SpecialBeardDye : Item
{
public override int LabelNumber{ get{ return 1041087; } } // Special Beard Dye
[Constructable]
public SpecialBeardDye() : base( 0xE26 )
{
Weight = 1.0;
}
public SpecialBeardDye( 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 )
{
if ( from.InRange( this.GetWorldLocation(), 1 ) )
{
from.CloseGump( typeof( SpecialBeardDyeGump ) );
from.SendGump( new SpecialBeardDyeGump( this ) );
}
else
{
from.LocalOverheadMessage( MessageType.Regular, 906, 1019045 ); // I can't reach that.
}
}
}
public class SpecialBeardDyeGump : Gump
{
private SpecialBeardDye m_SpecialBeardDye;
private class SpecialBeardDyeEntry
{
private string m_Name;
private int m_HueStart;
private int m_HueCount;
public string Name
{
get
{
return m_Name;
}
}
public int HueStart
{
get
{
return m_HueStart;
}
}
public int HueCount
{
get
{
return m_HueCount;
}
}
public SpecialBeardDyeEntry( string name, int hueStart, int hueCount )
{
m_Name = name;
m_HueStart = hueStart;
m_HueCount = hueCount;
}
}
private static SpecialBeardDyeEntry[] m_Entries = new SpecialBeardDyeEntry[]
{
new SpecialBeardDyeEntry( "*****", 12, 10 ),
new SpecialBeardDyeEntry( "*****", 32, 5 ),
new SpecialBeardDyeEntry( "*****", 38, 8 ),
new SpecialBeardDyeEntry( "*****", 54, 3 ),
new SpecialBeardDyeEntry( "*****", 62, 10 ),
new SpecialBeardDyeEntry( "*****", 81, 2 ),
new SpecialBeardDyeEntry( "*****", 89, 2 ),
new SpecialBeardDyeEntry( "*****", 1153, 2 )
};
public SpecialBeardDyeGump( SpecialBeardDye dye ) : base( 0, 0 )
{
m_SpecialBeardDye = dye;
AddPage( 0 );
AddBackground( 150, 60, 350, 358, 2600 );
AddBackground( 170, 104, 110, 270, 5100 );
AddHtmlLocalized( 230, 75, 200, 20, 1011013, false, false ); // Hair Color Selection Menu
AddHtmlLocalized( 235, 380, 300, 20, 1013007, false, false ); // Dye my beard this color!
AddButton( 200, 380, 0xFA5, 0xFA7, 1, GumpButtonType.Reply, 0 ); // DYE HAIR
for ( int i = 0; i < m_Entries.Length; ++i )
{
AddLabel( 180, 109 + (i * 22), m_Entries[i].HueStart - 1, m_Entries[i].Name );
AddButton( 257, 110 + (i * 22), 5224, 5224, 0, GumpButtonType.Page, i + 1 );
}
for ( int i = 0; i < m_Entries.Length; ++i )
{
SpecialBeardDyeEntry e = m_Entries[i];
AddPage( i + 1 );
for ( int j = 0; j < e.HueCount; ++j )
{
AddLabel( 328 + ((j / 16) * 80), 102 + ((j % 16) * 17), e.HueStart + j - 1, "*****" );
AddRadio( 310 + ((j / 16) * 80), 102 + ((j % 16) * 17), 210, 211, false, (i * 100) + j );
}
}
}
public override void OnResponse( NetState from, RelayInfo info )
{
if ( m_SpecialBeardDye.Deleted )
return;
Mobile m = from.Mobile;
int[] switches = info.Switches;
if ( !m_SpecialBeardDye.IsChildOf( m.Backpack ) )
{
m.SendLocalizedMessage( 1042010 ); //You must have the objectin your backpack to use it.
return;
}
if ( info.ButtonID != 0 && switches.Length > 0 )
{
if( m.FacialHairItemID == 0 )
{
m.SendLocalizedMessage( 502623 ); // You have no hair to dye and cannot use this
}
else
{
// To prevent this from being exploited, the hue is abstracted into an internal list
int entryIndex = switches[0] / 100;
int hueOffset = switches[0] % 100;
if ( entryIndex >= 0 && entryIndex < m_Entries.Length )
{
SpecialBeardDyeEntry e = m_Entries[entryIndex];
if ( hueOffset >= 0 && hueOffset < e.HueCount )
{
int hue = e.HueStart + hueOffset;
m.FacialHairHue = hue;
m.SendLocalizedMessage( 501199 ); // You dye your hair
m_SpecialBeardDye.Delete();
m.PlaySound( 0x4E );
}
}
}
}
else
{
m.SendLocalizedMessage( 501200 ); // You decide not to dye your hair
}
}
}
}

View file

@ -0,0 +1,190 @@
using System;
using System.Text;
using Server.Gumps;
using Server.Network;
namespace Server.Items
{
public class SpecialHairDye : Item
{
public override string DefaultName
{
get { return "Special Hair Dye"; }
}
[Constructable]
public SpecialHairDye() : base( 0xE26 )
{
Weight = 1.0;
}
public SpecialHairDye( 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 )
{
if ( from.InRange( this.GetWorldLocation(), 1 ) )
{
from.CloseGump( typeof( SpecialHairDyeGump ) );
from.SendGump( new SpecialHairDyeGump( this ) );
}
else
{
from.LocalOverheadMessage( MessageType.Regular, 906, 1019045 ); // I can't reach that.
}
}
}
public class SpecialHairDyeGump : Gump
{
private SpecialHairDye m_SpecialHairDye;
private class SpecialHairDyeEntry
{
private string m_Name;
private int m_HueStart;
private int m_HueCount;
public string Name
{
get
{
return m_Name;
}
}
public int HueStart
{
get
{
return m_HueStart;
}
}
public int HueCount
{
get
{
return m_HueCount;
}
}
public SpecialHairDyeEntry( string name, int hueStart, int hueCount )
{
m_Name = name;
m_HueStart = hueStart;
m_HueCount = hueCount;
}
}
private static SpecialHairDyeEntry[] m_Entries = new SpecialHairDyeEntry[]
{
new SpecialHairDyeEntry( "*****", 12, 10 ),
new SpecialHairDyeEntry( "*****", 32, 5 ),
new SpecialHairDyeEntry( "*****", 38, 8 ),
new SpecialHairDyeEntry( "*****", 54, 3 ),
new SpecialHairDyeEntry( "*****", 62, 10 ),
new SpecialHairDyeEntry( "*****", 81, 2 ),
new SpecialHairDyeEntry( "*****", 89, 2 ),
new SpecialHairDyeEntry( "*****", 1153, 2 )
};
public SpecialHairDyeGump( SpecialHairDye dye ) : base( 0, 0 )
{
m_SpecialHairDye = dye;
AddPage( 0 );
AddBackground( 150, 60, 350, 358, 2600 );
AddBackground( 170, 104, 110, 270, 5100 );
AddHtmlLocalized( 230, 75, 200, 20, 1011013, false, false ); // Hair Color Selection Menu
AddHtmlLocalized( 235, 380, 300, 20, 1011014, false, false ); // Dye my hair this color!
AddButton( 200, 380, 0xFA5, 0xFA7, 1, GumpButtonType.Reply, 0 ); // DYE HAIR
for ( int i = 0; i < m_Entries.Length; ++i )
{
AddLabel( 180, 109 + (i * 22), m_Entries[i].HueStart - 1, m_Entries[i].Name );
AddButton( 257, 110 + (i * 22), 5224, 5224, 0, GumpButtonType.Page, i + 1 );
}
for ( int i = 0; i < m_Entries.Length; ++i )
{
SpecialHairDyeEntry e = m_Entries[i];
AddPage( i + 1 );
for ( int j = 0; j < e.HueCount; ++j )
{
AddLabel( 328 + ((j / 16) * 80), 102 + ((j % 16) * 17), e.HueStart + j - 1, "*****" );
AddRadio( 310 + ((j / 16) * 80), 102 + ((j % 16) * 17), 210, 211, false, (i * 100) + j );
}
}
}
public override void OnResponse( NetState from, RelayInfo info )
{
if ( m_SpecialHairDye.Deleted )
return;
Mobile m = from.Mobile;
int[] switches = info.Switches;
if ( !m_SpecialHairDye.IsChildOf( m.Backpack ) )
{
m.SendLocalizedMessage( 1042010 ); //You must have the objectin your backpack to use it.
return;
}
if ( info.ButtonID != 0 && switches.Length > 0 )
{
if( m.HairItemID == 0 )
{
m.SendLocalizedMessage( 502623 ); // You have no hair to dye and cannot use this
}
else
{
// To prevent this from being exploited, the hue is abstracted into an internal list
int entryIndex = switches[0] / 100;
int hueOffset = switches[0] % 100;
if ( entryIndex >= 0 && entryIndex < m_Entries.Length )
{
SpecialHairDyeEntry e = m_Entries[entryIndex];
if ( hueOffset >= 0 && hueOffset < e.HueCount )
{
m_SpecialHairDye.Delete();
int hue = e.HueStart + hueOffset;
m.HairHue = hue;
m.SendLocalizedMessage( 501199 ); // You dye your hair
m.PlaySound( 0x4E );
}
}
}
}
else
{
m.SendLocalizedMessage( 501200 ); // You decide not to dye your hair
}
}
}
}

View file

@ -0,0 +1,98 @@
using System;
using Server;
namespace Server.Items
{
public class Static : Item
{
public Static() : base( 0x80 )
{
Movable = false;
}
[Constructable]
public Static( int itemID ) : base( itemID )
{
Movable = false;
}
[Constructable]
public Static( int itemID, int count ) : this( Utility.Random( itemID, count ) )
{
}
public Static( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 1 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
if ( version == 0 && Weight == 0 )
Weight = -1;
}
}
public class LocalizedStatic : Static
{
private int m_LabelNumber;
[CommandProperty( AccessLevel.GameMaster )]
public int Number
{
get{ return m_LabelNumber; }
set{ m_LabelNumber = value; InvalidateProperties(); }
}
public override int LabelNumber{ get{ return m_LabelNumber; } }
[Constructable]
public LocalizedStatic( int itemID ) : this( itemID, itemID < 0x4000 ? 1020000 + itemID : 1078872 + itemID )
{
}
[Constructable]
public LocalizedStatic( int itemID, int labelNumber ) : base( itemID )
{
m_LabelNumber = labelNumber;
}
public LocalizedStatic( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (byte) 0 ); // version
writer.WriteEncodedInt( (int) m_LabelNumber );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadByte();
switch ( version )
{
case 0:
{
m_LabelNumber = reader.ReadEncodedInt();
break;
}
}
}
}
}

View file

@ -0,0 +1,517 @@
using System;
using Server;
using Server.Network;
using Server.Spells;
namespace Server.Items
{
public class Teleporter : Item
{
private bool m_Active, m_Creatures, m_CombatCheck;
private Point3D m_PointDest;
private Map m_MapDest;
private bool m_SourceEffect;
private bool m_DestEffect;
private int m_SoundID;
private TimeSpan m_Delay;
[CommandProperty( AccessLevel.GameMaster )]
public bool SourceEffect
{
get{ return m_SourceEffect; }
set{ m_SourceEffect = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool DestEffect
{
get{ return m_DestEffect; }
set{ m_DestEffect = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int SoundID
{
get{ return m_SoundID; }
set{ m_SoundID = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan Delay
{
get{ return m_Delay; }
set{ m_Delay = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Active
{
get { return m_Active; }
set { m_Active = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public Point3D PointDest
{
get { return m_PointDest; }
set { m_PointDest = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public Map MapDest
{
get { return m_MapDest; }
set { m_MapDest = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Creatures
{
get { return m_Creatures; }
set { m_Creatures = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool CombatCheck
{
get { return m_CombatCheck; }
set { m_CombatCheck = value; InvalidateProperties(); }
}
public override int LabelNumber{ get{ return 1026095; } } // teleporter
[Constructable]
public Teleporter() : this( new Point3D( 0, 0, 0 ), null, false )
{
}
[Constructable]
public Teleporter( Point3D pointDest, Map mapDest ) : this( pointDest, mapDest, false )
{
}
[Constructable]
public Teleporter( Point3D pointDest, Map mapDest, bool creatures ) : base( 0x1BC3 )
{
Movable = false;
Visible = false;
m_Active = true;
m_PointDest = pointDest;
m_MapDest = mapDest;
m_Creatures = creatures;
m_CombatCheck = false;
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
if ( m_Active )
list.Add( 1060742 ); // active
else
list.Add( 1060743 ); // inactive
if ( m_MapDest != null )
list.Add( 1060658, "Map\t{0}", m_MapDest );
if ( m_PointDest != Point3D.Zero )
list.Add( 1060659, "Coords\t{0}", m_PointDest );
list.Add( 1060660, "Creatures\t{0}", m_Creatures ? "Yes" : "No" );
}
public override void OnSingleClick( Mobile from )
{
base.OnSingleClick( from );
if ( m_Active )
{
if ( m_MapDest != null && m_PointDest != Point3D.Zero )
LabelTo( from, "{0} [{1}]", m_PointDest, m_MapDest );
else if ( m_MapDest != null )
LabelTo( from, "[{0}]", m_MapDest );
else if ( m_PointDest != Point3D.Zero )
LabelTo( from, m_PointDest.ToString() );
}
else
{
LabelTo( from, "(inactive)" );
}
}
public virtual void StartTeleport( Mobile m )
{
if ( m_Delay == TimeSpan.Zero )
DoTeleport( m );
else
Timer.DelayCall( m_Delay, new TimerStateCallback( DoTeleport_Callback ), m );
}
private void DoTeleport_Callback( object state )
{
DoTeleport( (Mobile) state );
}
public virtual void DoTeleport( Mobile m )
{
Map map = m_MapDest;
if ( map == null || map == Map.Internal )
map = m.Map;
Point3D p = m_PointDest;
if ( p == Point3D.Zero )
p = m.Location;
Server.Mobiles.BaseCreature.TeleportPets( m, p, map );
bool sendEffect = ( !m.Hidden || m.AccessLevel == AccessLevel.Player );
if ( m_SourceEffect && sendEffect )
Effects.SendLocationEffect( m.Location, m.Map, 0x3728, 10, 10 );
m.MoveToWorld( p, map );
if ( m_DestEffect && sendEffect )
Effects.SendLocationEffect( m.Location, m.Map, 0x3728, 10, 10 );
if ( m_SoundID > 0 && sendEffect )
Effects.PlaySound( m.Location, m.Map, m_SoundID );
}
public override bool OnMoveOver( Mobile m )
{
if ( m_Active )
{
if ( !m_Creatures && !m.Player )
return true;
else if ( m_CombatCheck && SpellHelper.CheckCombat( m ) )
{
m.SendLocalizedMessage( 1005564, "", 0x22 ); // Wouldst thou flee during the heat of battle??
return true;
}
StartTeleport( m );
return false;
}
return true;
}
public Teleporter( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 3 ); // version
writer.Write( (bool) m_CombatCheck );
writer.Write( (bool) m_SourceEffect );
writer.Write( (bool) m_DestEffect );
writer.Write( (TimeSpan) m_Delay );
writer.WriteEncodedInt( (int) m_SoundID );
writer.Write( m_Creatures );
writer.Write( m_Active );
writer.Write( m_PointDest );
writer.Write( m_MapDest );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 3:
{
m_CombatCheck = reader.ReadBool();
goto case 2;
}
case 2:
{
m_SourceEffect = reader.ReadBool();
m_DestEffect = reader.ReadBool();
m_Delay = reader.ReadTimeSpan();
m_SoundID = reader.ReadEncodedInt();
goto case 1;
}
case 1:
{
m_Creatures = reader.ReadBool();
goto case 0;
}
case 0:
{
m_Active = reader.ReadBool();
m_PointDest = reader.ReadPoint3D();
m_MapDest = reader.ReadMap();
break;
}
}
}
}
public class SkillTeleporter : Teleporter
{
private SkillName m_Skill;
private double m_Required;
private string m_MessageString;
private int m_MessageNumber;
[CommandProperty( AccessLevel.GameMaster )]
public SkillName Skill
{
get{ return m_Skill; }
set{ m_Skill = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public double Required
{
get{ return m_Required; }
set{ m_Required = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public string MessageString
{
get{ return m_MessageString; }
set{ m_MessageString = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int MessageNumber
{
get{ return m_MessageNumber; }
set{ m_MessageNumber = value; InvalidateProperties(); }
}
private void EndMessageLock( object state )
{
((Mobile)state).EndAction( this );
}
public override bool OnMoveOver( Mobile m )
{
if ( Active )
{
if ( !Creatures && !m.Player )
return true;
Skill sk = m.Skills[m_Skill];
if ( sk == null || sk.Base < m_Required )
{
if ( m.BeginAction( this ) )
{
if ( m_MessageString != null )
m.Send( new UnicodeMessage( Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", null, m_MessageString ) );
else if ( m_MessageNumber != 0 )
m.Send( new MessageLocalized( Serial, ItemID, MessageType.Regular, 0x3B2, 3, m_MessageNumber, null, "" ) );
Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), new TimerStateCallback( EndMessageLock ), m );
}
return false;
}
StartTeleport( m );
return false;
}
return true;
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
int skillIndex = (int)m_Skill;
string skillName;
if ( skillIndex >= 0 && skillIndex < SkillInfo.Table.Length )
skillName = SkillInfo.Table[skillIndex].Name;
else
skillName = "(Invalid)";
list.Add( 1060661, "{0}\t{1:F1}", skillName, m_Required );
if ( m_MessageString != null )
list.Add( 1060662, "Message\t{0}", m_MessageString );
else if ( m_MessageNumber != 0 )
list.Add( 1060662, "Message\t#{0}", m_MessageNumber );
}
[Constructable]
public SkillTeleporter()
{
}
public SkillTeleporter( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (int) m_Skill );
writer.Write( (double) m_Required );
writer.Write( (string) m_MessageString );
writer.Write( (int) m_MessageNumber );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Skill = (SkillName)reader.ReadInt();
m_Required = reader.ReadDouble();
m_MessageString = reader.ReadString();
m_MessageNumber = reader.ReadInt();
break;
}
}
}
}
public class KeywordTeleporter : Teleporter
{
private string m_Substring;
private int m_Keyword;
private int m_Range;
[CommandProperty( AccessLevel.GameMaster )]
public string Substring
{
get{ return m_Substring; }
set{ m_Substring = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int Keyword
{
get{ return m_Keyword; }
set{ m_Keyword = value; InvalidateProperties(); }
}
[CommandProperty( AccessLevel.GameMaster )]
public int Range
{
get{ return m_Range; }
set{ m_Range = value; InvalidateProperties(); }
}
public override bool HandlesOnSpeech{ get{ return true; } }
public override void OnSpeech( SpeechEventArgs e )
{
if ( !e.Handled && Active )
{
Mobile m = e.Mobile;
if ( !Creatures && !m.Player )
return;
if ( !m.InRange( GetWorldLocation(), m_Range ) )
return;
bool isMatch = false;
if ( m_Keyword >= 0 && e.HasKeyword( m_Keyword ) )
isMatch = true;
else if ( m_Substring != null && e.Speech.ToLower().IndexOf( m_Substring.ToLower() ) >= 0 )
isMatch = true;
if ( !isMatch )
return;
e.Handled = true;
StartTeleport( m );
}
}
public override bool OnMoveOver( Mobile m )
{
return true;
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
list.Add( 1060661, "Range\t{0}", m_Range );
if ( m_Keyword >= 0 )
list.Add( 1060662, "Keyword\t{0}", m_Keyword );
if ( m_Substring != null )
list.Add( 1060663, "Substring\t{0}", m_Substring );
}
[Constructable]
public KeywordTeleporter()
{
m_Keyword = -1;
m_Substring = null;
}
public KeywordTeleporter( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( m_Substring );
writer.Write( m_Keyword );
writer.Write( m_Range );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Substring = reader.ReadString();
m_Keyword = reader.ReadInt();
m_Range = reader.ReadInt();
break;
}
}
}
}
}

View file

@ -0,0 +1,150 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Multis;
namespace Server.Items
{
public class TrashBarrel : Container, IChopable
{
public override int LabelNumber{ get{ return 1041064; } } // a trash barrel
public override int DefaultMaxWeight{ get{ return 0; } } // A value of 0 signals unlimited weight
public override bool IsDecoContainer
{
get{ return false; }
}
[Constructable]
public TrashBarrel() : base( 0xE77 )
{
Movable = false;
}
public TrashBarrel( 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 ( Items.Count > 0 )
{
m_Timer = new EmptyTimer( this );
m_Timer.Start();
}
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
if ( !base.OnDragDrop( from, dropped ) )
return false;
if ( TotalItems >= 50 )
{
Empty( 501478 ); // The trash is full! Emptying!
}
else
{
SendLocalizedMessageTo( from, 1010442 ); // The item will be deleted in three minutes
if ( m_Timer != null )
m_Timer.Stop();
else
m_Timer = new EmptyTimer( this );
m_Timer.Start();
}
return true;
}
public override bool OnDragDropInto( Mobile from, Item item, Point3D p )
{
if ( !base.OnDragDropInto( from, item, p ) )
return false;
if ( TotalItems >= 50 )
{
Empty( 501478 ); // The trash is full! Emptying!
}
else
{
SendLocalizedMessageTo( from, 1010442 ); // The item will be deleted in three minutes
if ( m_Timer != null )
m_Timer.Stop();
else
m_Timer = new EmptyTimer( this );
m_Timer.Start();
}
return true;
}
public void OnChop( Mobile from )
{
BaseHouse house = BaseHouse.FindHouseAt( from );
if ( house != null && house.IsCoOwner( from ) )
{
Effects.PlaySound( Location, Map, 0x3B3 );
from.SendLocalizedMessage( 500461 ); // You destroy the item.
Destroy();
}
}
public void Empty( int message )
{
List<Item> items = this.Items;
if ( items.Count > 0 )
{
PublicOverheadMessage( Network.MessageType.Regular, 0x3B2, message, "" );
for ( int i = items.Count - 1; i >= 0; --i )
{
if ( i >= items.Count )
continue;
items[i].Delete();
}
}
if ( m_Timer != null )
m_Timer.Stop();
m_Timer = null;
}
private Timer m_Timer;
private class EmptyTimer : Timer
{
private TrashBarrel m_Barrel;
public EmptyTimer( TrashBarrel barrel ) : base( TimeSpan.FromMinutes( 3.0 ) )
{
m_Barrel = barrel;
Priority = TimerPriority.FiveSeconds;
}
protected override void OnTick()
{
m_Barrel.Empty( 501479 ); // Emptying the trashcan!
}
}
}
}

View file

@ -0,0 +1,242 @@
using System;
using Server;
using Server.Network;
using System.Collections;
using System.Collections.Generic;
namespace Server.Items
{
public class WarningItem : Item
{
private string m_WarningString;
private int m_WarningNumber;
private int m_Range;
private TimeSpan m_ResetDelay;
[CommandProperty( AccessLevel.GameMaster )]
public string WarningString
{
get{ return m_WarningString; }
set{ m_WarningString = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int WarningNumber
{
get{ return m_WarningNumber; }
set{ m_WarningNumber = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int Range
{
get{ return m_Range; }
set{ if ( value > 18 ) value = 18; m_Range = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan ResetDelay
{
get{ return m_ResetDelay; }
set{ m_ResetDelay = value; }
}
[Constructable]
public WarningItem( int itemID, int range, int warning ) : base( itemID )
{
if ( range > 18 )
range = 18;
Movable = false;
m_WarningNumber = warning;
m_Range = range;
}
[Constructable]
public WarningItem( int itemID, int range, string warning ) : base( itemID )
{
if ( range > 18 )
range = 18;
Movable = false;
m_WarningString = warning;
m_Range = range;
}
public WarningItem( Serial serial ) : base( serial )
{
}
private bool m_Broadcasting;
private DateTime m_LastBroadcast;
public virtual void SendMessage( Mobile triggerer, bool onlyToTriggerer, string messageString, int messageNumber )
{
if ( onlyToTriggerer )
{
if ( messageString != null )
triggerer.SendMessage( messageString );
else
triggerer.SendLocalizedMessage( messageNumber );
}
else
{
if ( messageString != null )
PublicOverheadMessage( MessageType.Regular, 0x3B2, false, messageString );
else
PublicOverheadMessage( MessageType.Regular, 0x3B2, messageNumber );
}
}
public virtual bool OnlyToTriggerer{ get{ return false; } }
public virtual int NeighborRange { get { return 5; } }
public virtual void Broadcast( Mobile triggerer )
{
if ( m_Broadcasting || (DateTime.Now < (m_LastBroadcast + m_ResetDelay)) )
return;
m_LastBroadcast = DateTime.Now;
m_Broadcasting = true;
SendMessage( triggerer, this.OnlyToTriggerer, m_WarningString, m_WarningNumber );
if ( NeighborRange >= 0 )
{
List<WarningItem> list = new List<WarningItem>();
foreach ( Item item in GetItemsInRange( NeighborRange ) )
{
if ( item != this && item is WarningItem )
list.Add( (WarningItem)item );
}
for ( int i = 0; i < list.Count; i++ )
list[i].Broadcast( triggerer );
}
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( InternalCallback ) );
}
private void InternalCallback()
{
m_Broadcasting = false;
}
public override bool HandlesOnMovement{ get{ return true; } }
public override void OnMovement( Mobile m, Point3D oldLocation )
{
if ( m.Player && Utility.InRange( m.Location, Location, m_Range ) && !Utility.InRange( oldLocation, Location, m_Range ) )
Broadcast( m );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
writer.Write( (string) m_WarningString );
writer.Write( (int) m_WarningNumber );
writer.Write( (int) m_Range );
writer.Write( (TimeSpan) m_ResetDelay );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_WarningString = reader.ReadString();
m_WarningNumber = reader.ReadInt();
m_Range = reader.ReadInt();
m_ResetDelay = reader.ReadTimeSpan();
break;
}
}
}
}
public class HintItem : WarningItem
{
private string m_HintString;
private int m_HintNumber;
[CommandProperty( AccessLevel.GameMaster )]
public string HintString
{
get{ return m_HintString; }
set{ m_HintString = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public int HintNumber
{
get{ return m_HintNumber; }
set{ m_HintNumber = value; }
}
public override bool OnlyToTriggerer{ get{ return true; } }
[Constructable]
public HintItem( int itemID, int range, int warning, int hint ) : base( itemID, range, warning )
{
m_HintNumber = hint;
}
[Constructable]
public HintItem( int itemID, int range, string warning, string hint ) : base( itemID, range, warning )
{
m_HintString = hint;
}
public HintItem( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
SendMessage( from, true, m_HintString, m_HintNumber );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
writer.Write( (string) m_HintString );
writer.Write( (int) m_HintNumber );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_HintString = reader.ReadString();
m_HintNumber = reader.ReadInt();
break;
}
}
}
}
}

View file

@ -0,0 +1,161 @@
using System;
using Server;
using Server.Targeting;
using Server.Commands;
namespace Server.Items
{
[FlipableAttribute( 0x1f14, 0x1f15, 0x1f16, 0x1f17 )]
public class WayPoint : Item
{
public static void Initialize()
{
CommandSystem.Register( "WayPointSeq", AccessLevel.GameMaster, new CommandEventHandler( WayPointSeq_OnCommand ) );
}
public static void WayPointSeq_OnCommand( CommandEventArgs arg )
{
arg.Mobile.SendMessage( "Target the position of the first way point." );
arg.Mobile.Target = new WayPointSeqTarget( null );
}
private WayPoint m_Next;
public override string DefaultName
{
get { return "AI Way Point"; }
}
[Constructable]
public WayPoint() : base( 0x1f14 )
{
this.Hue = 0x498;
this.Visible = false;
//this.Movable = false;
}
public WayPoint( WayPoint prev ) : this()
{
if ( prev != null )
prev.NextPoint = this;
}
[CommandProperty( AccessLevel.GameMaster )]
public WayPoint NextPoint
{
get
{
return m_Next;
}
set
{
if ( m_Next != this )
m_Next = value;
}
}
public override void OnDoubleClick( Mobile from )
{
if ( from.AccessLevel >= AccessLevel.GameMaster )
{
from.SendMessage( "Target the next way point in the sequence." );
from.Target = new NextPointTarget( this );
}
}
public override void OnSingleClick( Mobile from )
{
base.OnSingleClick( from );
if ( m_Next == null )
LabelTo( from, "(Unlinked)" );
else
LabelTo( from, "(Linked: {0})", m_Next.Location );
}
public WayPoint( Serial serial ) : base( serial )
{
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch( version )
{
case 0:
{
m_Next = reader.ReadItem() as WayPoint;
break;
}
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
writer.Write( m_Next );
}
}
public class NextPointTarget : Target
{
private WayPoint m_Point;
public NextPointTarget( WayPoint pt ) : base( -1, false, TargetFlags.None )
{
m_Point = pt;
}
protected override void OnTarget( Mobile from, object target )
{
if ( target is WayPoint && m_Point != null )
{
m_Point.NextPoint = (WayPoint)target;
}
else
{
from.SendMessage( "Target a way point." );
}
}
}
public class WayPointSeqTarget : Target
{
private WayPoint m_Last;
public WayPointSeqTarget( WayPoint last ) : base( -1, true, TargetFlags.None )
{
m_Last = last;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted is WayPoint )
{
if ( m_Last != null )
m_Last.NextPoint = (WayPoint)targeted;
}
else if ( targeted is IPoint3D )
{
Point3D p = new Point3D( (IPoint3D)targeted );
WayPoint point = new WayPoint( m_Last );
point.MoveToWorld( p, from.Map );
from.Target = new WayPointSeqTarget( point );
from.SendMessage( "Target the position of the next way point in the sequence, or target a way point link the newest way point to." );
}
else
{
from.SendMessage( "Target a position, or another way point." );
}
}
}
}