This commit is contained in:
mark 2006-06-15 04:14:30 +00:00
commit 47711d616e
2644 changed files with 479454 additions and 0 deletions

View file

@ -0,0 +1,201 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.Targeting;
namespace Server.Items
{
public class ArcaneGem : Item
{
public override string DefaultName
{
get { return "arcane gem"; }
}
[Constructable]
public ArcaneGem() : base( 0x1EA7 )
{
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)(m.Skills[SkillName.Tailoring].Value / 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;
IArcaneEquip eq = (IArcaneEquip)obj;
if ( !item.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
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." );
Delete();
}
}
else if ( from.Skills[SkillName.Tailoring].Value >= 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).Crafter = from;
else if ( item is BaseArmor )
((BaseArmor)item).Crafter = from;
else if ( item is BaseWeapon )
((BaseWeapon)item).Crafter = from;
eq.CurArcaneCharges = eq.MaxArcaneCharges = charges;
item.Hue = DefaultArcaneHue;
from.SendMessage( "You enhance the item with your gem." );
Delete();
}
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 cannot use the gem on that." );
}
}
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,161 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using Server.Engines.Quests;
using Necro = Server.Engines.Quests.Necro;
using Haven = Server.Engines.Quests.Haven;
namespace Server.Items
{
public class BankCheck : Item
{
private int m_Worth;
[CommandProperty( AccessLevel.GameMaster )]
public int Worth
{
get{ return m_Worth; }
set{ m_Worth = value; InvalidateProperties(); }
}
public BankCheck( 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 );
LootType = LootType.Blessed;
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Worth = reader.ReadInt();
break;
}
}
}
[Constructable]
public BankCheck( int worth ) : base( 0x14F0 )
{
Weight = 1.0;
Hue = 0x34;
LootType = LootType.Blessed;
m_Worth = worth;
}
public override bool DisplayLootType{ get{ return Core.AOS; } }
public override int LabelNumber{ get{ return 1041361; } } // A bank check
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties( list );
list.Add( 1060738, m_Worth.ToString() ); // 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 )
{
BankBox box = from.BankBox;
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 BankCheck( 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 BankCheck( toAdd ) );
}
}
// Gold was deposited in your account:
from.SendLocalizedMessage( 1042672, true, " " + deposited.ToString() );
PlayerMobile pm = from as PlayerMobile;
if ( pm != null )
{
QuestSystem qs = pm.Quest;
if ( qs is Necro.DarkTidesQuest )
{
QuestObjective obj = qs.FindObjective( typeof( Necro.CashBankCheckObjective ) );
if ( obj != null && !obj.Completed )
obj.Complete();
}
if ( qs is Haven.UzeraanTurmoilQuest )
{
QuestObjective obj = qs.FindObjective( typeof( Haven.CashBankCheckObjective ) );
if ( obj != null && !obj.Completed )
obj.Complete();
}
}
}
else
{
from.SendLocalizedMessage( 1047026 ); // That must be in your bank box to use it.
}
}
}
}

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,110 @@
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 )
{
}
public override void SendInfoTo( NetState state )
{
Mobile mob = state.Mobile;
if ( mob != null && mob.AccessLevel >= AccessLevel.GameMaster )
state.Send( new GMItemPacket( this ) );
else
state.Send( WorldPacket );
if ( ObjectPropertyList.Enabled )
state.Send( OPLPacket );
}
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( 0x1645 )
{
}
[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();
}
}
}
}

198
Scripts/Items/Misc/Bola.cs Normal file
View file

@ -0,0 +1,198 @@
using System;
using System.Collections;
using Server;
using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Items
{
public class Bola : Item
{
[Constructable]
public Bola() : this( 1 )
{
}
[Constructable]
public Bola( int amount ) : base( 0x26AC )
{
Weight = 4.0;
Stackable = true;
Amount = amount;
}
public override void OnDoubleClick( Mobile from )
{
if ( !IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1040019 ); // The bola must be in your pack to use it.
}
else if ( !from.CanBeginAction( typeof( Bola ) ) )
{
from.SendLocalizedMessage( 1049624 ); // You have to wait a few moments before you can use another bola!
}
else if ( from.Target is BolaTarget )
{
from.SendLocalizedMessage( 1049631 ); // This bola is already being used.
}
else if ( !Core.AOS && (from.FindItemOnLayer( Layer.OneHanded ) != null || from.FindItemOnLayer( Layer.TwoHanded ) != null) )
{
from.SendLocalizedMessage( 1040015 ); // Your hands must be free to use this
}
else if ( from.Mounted )
{
from.SendLocalizedMessage( 1040016 ); // You cannot use this while riding a mount
}
else if ( Server.Spells.Ninjitsu.AnimalForm.UnderTransformation( from ) )
{
from.SendLocalizedMessage( 1070902 ); // You can't use this while in an animal form!
}
else
{
EtherealMount.StopMounting( from );
Item one = from.FindItemOnLayer( Layer.OneHanded );
Item two = from.FindItemOnLayer( Layer.TwoHanded );
if ( one != null )
from.AddToBackpack( one );
if ( two != null )
from.AddToBackpack( two );
from.Target = new BolaTarget( this );
from.LocalOverheadMessage( MessageType.Emote, 0x3B2, 1049632 ); // * You begin to swing the bola...*
from.NonlocalOverheadMessage( MessageType.Emote, 0x3B2, 1049633, from.Name ); // ~1_NAME~ begins to menacingly swing a bola...
}
}
private static void ReleaseBolaLock( object state )
{
((Mobile)state).EndAction( typeof( Bola ) );
}
private static void FinishThrow( object state )
{
object[] states = (object[])state;
Mobile from = (Mobile)states[0];
Mobile to = (Mobile)states[1];
if ( Core.AOS )
new Bola().MoveToWorld( to.Location, to.Map );
to.Damage( 1, from );
IMount mt = to.Mount;
if ( mt != null )
mt.Rider = null;
to.SendLocalizedMessage( 1040023 ); // You have been knocked off of your mount!
BaseMount.SetMountPrevention( to, BlockMountType.Dazed, TimeSpan.FromSeconds( 3.0 ) );
Timer.DelayCall( TimeSpan.FromSeconds( 2.0 ), new TimerStateCallback( ReleaseBolaLock ), from );
}
private class BolaTarget : Target
{
private Bola m_Bola;
public BolaTarget( Bola bola ) : base( 8, false, TargetFlags.Harmful )
{
m_Bola = bola;
}
protected override void OnTarget( Mobile from, object obj )
{
if ( m_Bola.Deleted )
return;
if ( obj is Mobile )
{
Mobile to = (Mobile)obj;
if ( !m_Bola.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1040019 ); // The bola must be in your pack to use it.
}
else if ( !Core.AOS && (from.FindItemOnLayer( Layer.OneHanded ) != null || from.FindItemOnLayer( Layer.TwoHanded ) != null) )
{
from.SendLocalizedMessage( 1040015 ); // Your hands must be free to use this
}
else if ( from.Mounted )
{
from.SendLocalizedMessage( 1040016 ); // You cannot use this while riding a mount
}
else if ( Server.Spells.Ninjitsu.AnimalForm.UnderTransformation( from ) )
{
from.SendLocalizedMessage( 1070902 ); // You can't use this while in an animal form!
}
else if ( !to.Mounted )
{
from.SendLocalizedMessage( 1049628 ); // You have no reason to throw a bola at that.
}
else if ( !from.CanBeHarmful( to ) )
{
}
else if ( from.BeginAction( typeof( Bola ) ) )
{
EtherealMount.StopMounting( from );
Item one = from.FindItemOnLayer( Layer.OneHanded );
Item two = from.FindItemOnLayer( Layer.TwoHanded );
if ( one != null )
from.AddToBackpack( one );
if ( two != null )
from.AddToBackpack( two );
from.DoHarmful( to );
if ( Core.AOS )
BaseMount.SetMountPrevention( from, BlockMountType.BolaRecovery, TimeSpan.FromSeconds( 3.0 ) );
m_Bola.Consume();
from.Direction = from.GetDirectionTo( to );
from.Animate( 11, 5, 1, true, false, 0 );
from.MovingEffect( to, 0x26AC, 10, 0, false, false );
Timer.DelayCall( TimeSpan.FromSeconds( 0.5 ), new TimerStateCallback( FinishThrow ), new object[]{ from, to } );
}
else
{
from.SendLocalizedMessage( 1049624 ); // You have to wait a few moments before you can use another bola!
}
}
else
{
from.SendLocalizedMessage( 1049629 ); // You cannot throw a bola at that.
}
}
}
public Bola( 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,44 @@
using System;
namespace Server.Items
{
public class BolaBall : Item
{
[Constructable]
public BolaBall() : this( 1 )
{
}
[Constructable]
public BolaBall( int amount ) : base( 0xE73 )
{
Weight = 4.0;
Stackable = true;
Amount = amount;
Hue = 0x8AC;
}
public BolaBall( 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();
if ( Hue == 0 )
Hue = 0x8AC;
}
}
}

View file

@ -0,0 +1,614 @@
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();
from.Send( new BBDisplayBoard( this ) );
from.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;
ArrayList list = new ArrayList();
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 = (BulletinEquip[])list.ToArray( typeof( BulletinEquip ) );
}
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,134 @@
using System;
using Server;
using Server.Mobiles;
using Server.Spells;
namespace Server.Items
{
public class ClockworkAssembly : Item
{
public override string DefaultName
{
get { return "clockwork assembly"; }
}
[Constructable]
public ClockworkAssembly() : base( 0x1EA8 )
{
Weight = 5.0;
Hue = 1102;
}
public ClockworkAssembly( 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.
return;
}
double tinkerSkill = from.Skills[SkillName.Tinkering].Value;
if ( tinkerSkill < 60.0 )
{
from.SendMessage( "You must have at least 60.0 skill in tinkering to construct a golem." );
return;
}
else if ( (from.Followers + 4) > from.FollowersMax )
{
from.SendLocalizedMessage( 1049607 ); // You have too many followers to control that creature.
return;
}
double scalar;
if ( tinkerSkill >= 100.0 )
scalar = 1.0;
else if ( tinkerSkill >= 90.0 )
scalar = 0.9;
else if ( tinkerSkill >= 80.0 )
scalar = 0.8;
else if ( tinkerSkill >= 70.0 )
scalar = 0.7;
else
scalar = 0.6;
Container pack = from.Backpack;
if ( pack == null )
return;
int res = pack.ConsumeTotal(
new Type[]
{
typeof( PowerCrystal ),
typeof( IronIngot ),
typeof( BronzeIngot ),
typeof( Gears )
},
new int[]
{
1,
50,
50,
5
} );
switch ( res )
{
case 0:
{
from.SendMessage( "You must have a power crystal to construct the golem." );
break;
}
case 1:
{
from.SendMessage( "You must have 50 iron ingots to construct the golem." );
break;
}
case 2:
{
from.SendMessage( "You must have 50 bronze ingots to construct the golem." );
break;
}
case 3:
{
from.SendMessage( "You must have 5 gears to construct the golem." );
break;
}
default:
{
Golem g = new Golem( true, scalar );
if ( g.SetControlMaster( from ) )
{
Delete();
g.MoveToWorld( from.Location, from.Map );
from.PlaySound( 0x241 );
}
break;
}
}
}
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,483 @@
using System;
using System.Collections;
using Server;
using Server.Network;
using Server.Targeting;
namespace Server.Items
{
public class CrystalRechargeInfo
{
public static readonly CrystalRechargeInfo[] Table = new CrystalRechargeInfo[]
{
new CrystalRechargeInfo( typeof( Citrine ), 500 ),
new CrystalRechargeInfo( typeof( Amber ), 500 ),
new CrystalRechargeInfo( typeof( Tourmaline ), 750 ),
new CrystalRechargeInfo( typeof( Emerald ), 1000 ),
new CrystalRechargeInfo( typeof( Sapphire ), 1000 ),
new CrystalRechargeInfo( typeof( Amethyst ), 1000 ),
new CrystalRechargeInfo( typeof( StarSapphire ), 1250 ),
new CrystalRechargeInfo( typeof( Diamond ), 2000 )
};
public static CrystalRechargeInfo Get( Type type )
{
foreach ( CrystalRechargeInfo info in Table )
{
if ( info.Type == type )
return info;
}
return null;
}
private Type m_Type;
private int m_Amount;
public Type Type{ get{ return m_Type; } }
public int Amount{ get{ return m_Amount; } }
private CrystalRechargeInfo( Type type, int amount )
{
m_Type = type;
m_Amount = amount;
}
}
public class BroadcastCrystal : Item
{
public static readonly int MaxCharges = 2000;
public override int LabelNumber{ get{ return 1060740; } } // communication crystal
private int m_Charges;
private ArrayList m_Receivers;
[CommandProperty( AccessLevel.GameMaster )]
public bool Active
{
get{ return this.ItemID == 0x1ECD; }
set
{
this.ItemID = value ? 0x1ECD : 0x1ED0;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int Charges
{
get{ return m_Charges; }
set
{
m_Charges = value;
InvalidateProperties();
}
}
public ArrayList Receivers
{
get{ return m_Receivers; }
}
[Constructable]
public BroadcastCrystal() : this( 2000 )
{
}
[Constructable]
public BroadcastCrystal( int charges ) : base( 0x1ED0 )
{
Light = LightType.Circle150;
m_Charges = charges;
m_Receivers = new ArrayList();
}
public BroadcastCrystal( Serial serial ) : base( serial )
{
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
list.Add( this.Active ? 1060742 : 1060743 ); // active / inactive
list.Add( 1060745 ); // broadcast
list.Add( 1060741, this.Charges.ToString() ); // charges: ~1_val~
if ( Receivers.Count > 0 )
list.Add( 1060746, Receivers.Count.ToString() ); // links: ~1_val~
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick( from );
LabelTo( from, this.Active ? 1060742 : 1060743 ); // active / inactive
LabelTo( from, 1060745 ); // broadcast
LabelTo( from, 1060741, this.Charges.ToString() ); // charges: ~1_val~
if ( Receivers.Count > 0 )
LabelTo( from, 1060746, Receivers.Count.ToString() ); // links: ~1_val~
}
public override bool HandlesOnSpeech
{
get{ return Active && Receivers.Count > 0 && ( RootParent == null || RootParent is Mobile ); }
}
public override void OnSpeech( SpeechEventArgs e )
{
if ( !Active || Receivers.Count == 0 || ( RootParent != null && !(RootParent is Mobile) ) )
return;
if ( e.Type == MessageType.Emote )
return;
Mobile from = e.Mobile;
string speech = e.Speech;
foreach ( ReceiverCrystal receiver in new ArrayList( Receivers ) )
{
if ( receiver.Deleted )
{
Receivers.Remove( receiver );
}
else if ( Charges > 0 )
{
receiver.TransmitMessage( from, speech );
Charges--;
}
else
{
this.Active = false;
break;
}
}
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( GetWorldLocation(), 2 ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
return;
}
from.Target = new InternalTarget( this );
}
private class InternalTarget : Target
{
private BroadcastCrystal m_Crystal;
public InternalTarget( BroadcastCrystal crystal ) : base( 2, false, TargetFlags.None )
{
m_Crystal = crystal;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( !m_Crystal.IsAccessibleTo( from ) )
return;
if ( from.Map != m_Crystal.Map || !from.InRange( m_Crystal.GetWorldLocation(), 2 ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
return;
}
if ( targeted == m_Crystal )
{
if ( m_Crystal.Active )
{
m_Crystal.Active = false;
from.SendLocalizedMessage( 500672 ); // You turn the crystal off.
}
else
{
if ( m_Crystal.Charges > 0 )
{
m_Crystal.Active = true;
from.SendLocalizedMessage( 500673 ); // You turn the crystal on.
}
else
{
from.SendLocalizedMessage( 500676 ); // This crystal is out of charges.
}
}
}
else if ( targeted is ReceiverCrystal )
{
ReceiverCrystal receiver = (ReceiverCrystal) targeted;
if ( m_Crystal.Receivers.Count >= 10 )
{
from.SendLocalizedMessage( 1010042 ); // This broadcast crystal is already linked to 10 receivers.
}
else if ( receiver.Sender == m_Crystal )
{
from.SendLocalizedMessage( 500674 ); // This crystal is already linked with that crystal.
}
else if ( receiver.Sender != null )
{
from.SendLocalizedMessage( 1010043 ); // That receiver crystal is already linked to another broadcast crystal.
}
else
{
receiver.Sender = m_Crystal;
from.SendLocalizedMessage( 500675 ); // That crystal has been linked to this crystal.
}
}
else if ( targeted == from )
{
foreach ( ReceiverCrystal receiver in new ArrayList( m_Crystal.Receivers ) )
{
receiver.Sender = null;
}
from.SendLocalizedMessage( 1010046 ); // You unlink the broadcast crystal from all of its receivers.
}
else
{
Item targItem = targeted as Item;
if ( targItem != null && targItem.VerifyMove( from ) )
{
CrystalRechargeInfo info = CrystalRechargeInfo.Get( targItem.GetType() );
if ( info != null )
{
if ( m_Crystal.Charges >= MaxCharges )
{
from.SendLocalizedMessage( 500678 ); // This crystal is already fully charged.
}
else
{
targItem.Consume();
if ( m_Crystal.Charges + info.Amount >= MaxCharges )
{
m_Crystal.Charges = MaxCharges;
from.SendLocalizedMessage( 500679 ); // You completely recharge the crystal.
}
else
{
m_Crystal.Charges += info.Amount;
from.SendLocalizedMessage( 500680 ); // You recharge the crystal.
}
}
return;
}
}
from.SendLocalizedMessage( 500681 ); // You cannot use this crystal on that.
}
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
writer.WriteEncodedInt( m_Charges );
writer.WriteItemList( m_Receivers );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_Charges = reader.ReadEncodedInt();
m_Receivers = reader.ReadItemList();
}
}
public class ReceiverCrystal : Item
{
public override int LabelNumber{ get{ return 1060740; } } // communication crystal
private BroadcastCrystal m_Sender;
[CommandProperty( AccessLevel.GameMaster )]
public bool Active
{
get{ return this.ItemID == 0x1ED1; }
set
{
this.ItemID = value ? 0x1ED1 : 0x1ED0;
InvalidateProperties();
}
}
[CommandProperty( AccessLevel.GameMaster )]
public BroadcastCrystal Sender
{
get{ return m_Sender; }
set
{
if ( m_Sender != null )
{
m_Sender.Receivers.Remove( this );
m_Sender.InvalidateProperties();
}
m_Sender = value;
if ( value != null )
{
value.Receivers.Add( this );
value.InvalidateProperties();
}
}
}
[Constructable]
public ReceiverCrystal() : base( 0x1ED0 )
{
Light = LightType.Circle150;
}
public ReceiverCrystal( Serial serial ) : base( serial )
{
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
list.Add( this.Active ? 1060742 : 1060743 ); // active / inactive
list.Add( 1060744 ); // receiver
}
public override void OnSingleClick( Mobile from )
{
base.OnSingleClick( from );
LabelTo( from, this.Active ? 1060742 : 1060743 ); // active / inactive
LabelTo( from, 1060744 ); // receiver
}
public void TransmitMessage( Mobile from, string message )
{
if ( !this.Active )
return;
string text = String.Format( "{0} says {1}", from.Name, message );
if ( this.RootParent is Mobile )
{
((Mobile)this.RootParent).SendMessage( 0x2B2, "Crystal: " + text );
}
else if ( this.RootParent is Item )
{
((Item)this.RootParent).PublicOverheadMessage( MessageType.Regular, 0x2B2, false, "Crystal: " + text );
}
else
{
PublicOverheadMessage( MessageType.Regular, 0x2B2, false, text );
}
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( GetWorldLocation(), 2 ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
return;
}
from.Target = new InternalTarget( this );
}
private class InternalTarget : Target
{
private ReceiverCrystal m_Crystal;
public InternalTarget( ReceiverCrystal crystal ) : base( -1, false, TargetFlags.None )
{
m_Crystal = crystal;
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( !m_Crystal.IsAccessibleTo( from ) )
return;
if ( from.Map != m_Crystal.Map || !from.InRange( m_Crystal.GetWorldLocation(), 2 ) )
{
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
return;
}
if ( targeted == m_Crystal )
{
if ( m_Crystal.Active )
{
m_Crystal.Active = false;
from.SendLocalizedMessage( 500672 ); // You turn the crystal off.
}
else
{
m_Crystal.Active = true;
from.SendLocalizedMessage( 500673 ); // You turn the crystal on.
}
}
else if ( targeted == from )
{
if ( m_Crystal.Sender != null )
{
m_Crystal.Sender = null;
from.SendLocalizedMessage( 1010044 ); // You unlink the receiver crystal.
}
else
{
from.SendLocalizedMessage( 1010045 ); // That receiver crystal is not linked.
}
}
else
{
Item targItem = targeted as Item;
if ( targItem != null && targItem.VerifyMove( from ) )
{
CrystalRechargeInfo info = CrystalRechargeInfo.Get( targItem.GetType() );
if ( info != null )
{
from.SendLocalizedMessage( 500677 ); // This crystal cannot be recharged.
return;
}
}
from.SendLocalizedMessage( 1010045 ); // That receiver crystal is not linked.
}
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
writer.Write( (Item) m_Sender );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_Sender = (BroadcastCrystal) reader.ReadItem();
}
}
}

View file

@ -0,0 +1,965 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server;
using Server.ContextMenus;
using Server.Engines.PartySystem;
using Server.Engines.Quests;
using Server.Engines.Quests.Doom;
using Server.Engines.Quests.Haven;
using Server.Guilds;
using Server.Misc;
using Server.Mobiles;
using Server.Network;
namespace Server.Items
{
public class Corpse : Container, ICarvable
{
private Mobile m_Owner; // Whos corpse is this?
private Mobile m_Killer; // Who killed the owner?
private bool m_Carved; // Has this corpse been carved?
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 bool m_NoBones; // If true, this corpse will not turn into bones
private bool m_VisitedByTaxidermist; // Has this corpse yet been visited by a taxidermist?
private bool m_Channeled; // Has this corpse yet been used to channel spiritual energy? (AOS Spirit Speak)
// 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 bool m_Criminal; // Was the owner criminal 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 IsDecoContainer
{
get{ return false; }
}
[CommandProperty( AccessLevel.GameMaster )]
public DateTime TimeOfDeath
{
get{ return m_TimeOfDeath; }
set{ m_TimeOfDeath = value; }
}
public HairInfo Hair { get { return m_Hair; } }
public FacialHairInfo FacialHair { get { return m_FacialHair; } }
[CommandProperty( AccessLevel.GameMaster )]
public bool Carved
{
get{ return m_Carved; }
set{ m_Carved = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool VisitedByTaxidermist
{
get{ return m_VisitedByTaxidermist; }
set{ m_VisitedByTaxidermist = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool Channeled
{
get{ return m_Channeled; }
set{ m_Channeled = 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 m_Criminal; }
set{ m_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();
m_NoBones = true;
BeginDecay( m_BoneDecayTime );
/*DecayedCorpse c = new DecayedCorpse( Name );
c.MoveToWorld( Location, Map );
ArrayList list = Items;
for ( int i = list.Count - 1; i >= 0; --i )
{
if ( i < list.Count )
c.AddItem( (Item)list[i] );
}
Delete();*/
}
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.m_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;
if( owner is MilitiaFighter )
c = new MilitiaFighterCorpse( owner, hair, facialhair, shouldFillCorpse ? equipItems : new List<Item>() );
else
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];
if ( Core.AOS && owner.Player && item.Parent == owner.Backpack )
c.AddItem( item );
else
c.DropItem( item );
if ( owner.Player && Core.AOS )
c.SetRestoreInfo( item, item.Location );
}
}
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;
m_Criminal = owner.Criminal;
m_Hair = hair;
m_FacialHair = facialhair;
#if false
// This corpse does not turn to bones if:
// (the owner is not a player) and (the owner doesn't have a human body)
m_NoBones = !owner.Player && !owner.Body.IsHuman;
#else
// This corpse does not turn to bones if:
// (the owner is not a player)
m_NoBones = !owner.Player;
#endif
m_Looters = new List<Mobile>();
m_EquipItems = equipItems;
m_Aggressors = new List<Mobile>( owner.Aggressors.Count + owner.Aggressed.Count );
bool addToAggressors = !( 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 ( addToAggressors && !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 ( addToAggressors )
m_Aggressors.Add( info.Defender );
}
if ( !addToAggressors )
{
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 );
}
public Corpse( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 10 ); // version
writer.WriteDeltaTime( m_TimeOfDeath );
ArrayList list = ( m_RestoreTable == null ? null : new ArrayList( m_RestoreTable ) );
int count = ( list == null ? 0 : list.Count );
writer.Write( count );
for ( int i = 0; list != null && i < list.Count; ++i )
{
DictionaryEntry de = (DictionaryEntry)list[i];
Item item = (Item)de.Key;
Point3D loc = (Point3D)de.Value;
writer.Write( item );
if ( item.Location == loc )
{
writer.Write( false );
}
else
{
writer.Write( true );
writer.Write( loc );
}
}
writer.Write( m_VisitedByTaxidermist );
writer.Write( m_DecayTimer != null );
if ( m_DecayTimer != null )
writer.WriteDeltaTime( m_DecayTime );
writer.Write( m_Looters );
writer.Write( m_Killer );
writer.Write( (bool) m_Carved );
writer.Write( m_Aggressors );
writer.Write( m_Owner );
writer.Write( m_NoBones );
writer.Write( (string) m_CorpseName );
writer.Write( (int) m_AccessLevel );
writer.Write( (Guild) m_Guild );
writer.Write( (int) m_Kills );
writer.Write( (bool) m_Criminal );
writer.Write( m_EquipItems );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
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:
{
m_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:
{
m_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:
{
m_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();
m_Criminal = reader.ReadBool();
m_EquipItems = reader.ReadStrongItemList();
break;
}
}
}
public override void SendInfoTo( NetState state )
{
base.SendInfoTo( state );
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 );
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 );
}
public override void OnItemUsed( Mobile from, Item item )
{
base.OnItemUsed( from, item );
if ( from != m_Owner )
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, false );
}
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
if ( Core.AOS && m_Owner == from && from.Alive )
list.Add( new OpenCorpseEntry() );
}
private Hashtable m_RestoreTable;
public bool GetRestoreInfo( Item item, ref Point3D loc )
{
if ( m_RestoreTable == null || item == null )
return false;
object obj = m_RestoreTable[item];
if ( obj == null )
return false;
loc = (Point3D)obj;
return true;
}
public void SetRestoreInfo( Item item, Point3D loc )
{
if ( item == null )
return;
if ( m_RestoreTable == null )
m_RestoreTable = new Hashtable();
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 )
{
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 )
{
if ( !CanLoot( from ) )
{
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, bool checkSelfLoot )
{
if ( from.AccessLevel > AccessLevel.Player || from.InRange( this.GetWorldLocation(), 2 ) )
{
bool selfLoot = ( checkSelfLoot && ( from == m_Owner ) );
if ( selfLoot )
{
List<Item> items = new List<Item>( this.Items );
bool gathered = false;
bool didntFit = false;
Container pack = from.Backpack;
bool checkRobe = true;
for ( int i = 0; !didntFit && i < items.Count; ++i )
{
Item item = items[i];
Point3D loc = item.Location;
if ( (item.Layer == Layer.Hair || item.Layer == Layer.FacialHair) || !item.Movable || !GetRestoreInfo( item, ref loc ) )
continue;
if ( checkRobe )
{
DeathRobe robe = from.FindItemOnLayer( Layer.OuterTorso ) as DeathRobe;
if ( robe != null )
{
if ( Core.SE )
{
robe.Delete();
}
else
{
Map map = from.Map;
if ( map != null && map != Map.Internal )
robe.MoveToWorld( from.Location, map );
}
}
}
if ( m_EquipItems.Contains( item ) && from.EquipItem( item ) )
{
gathered = true;
}
else if ( pack != null && pack.CheckHold( from, item, false, true ) )
{
item.Location = loc;
pack.AddItem( item );
gathered = true;
}
else
{
didntFit = true;
}
}
if ( gathered && !didntFit )
{
m_Carved = true;
if ( ItemID == 0x2006 )
{
ProcessDelta();
SendRemovePacket();
ItemID = Utility.Random( 0xECA, 9 ); // bone graphic
Hue = 0;
ProcessDelta();
}
from.PlaySound( 0x3E3 );
from.SendLocalizedMessage( 1062471 ); // You quickly gather all of your belongings.
return;
}
if ( gathered && didntFit )
from.SendLocalizedMessage( 1062472 ); // You gather some of your belongings. The rest remain on the corpse.
}
if ( !CheckLoot( from ) )
return;
PlayerMobile player = from as PlayerMobile;
if ( player != null )
{
QuestSystem qs = player.Quest;
if ( qs is UzeraanTurmoilQuest )
{
GetDaemonBoneObjective obj = qs.FindObjective( typeof( GetDaemonBoneObjective ) ) as GetDaemonBoneObjective;
if ( obj != null && obj.CorpseWithBone == this && ( !obj.Completed || UzeraanTurmoilQuest.HasLostDaemonBone( player ) ) )
{
Item bone = new QuestDaemonBone();
if ( player.PlaceInBackpack( bone ) )
{
obj.CorpseWithBone = null;
player.SendLocalizedMessage( 1049341, "", 0x22 ); // You rummage through the bones and find a Daemon Bone! You quickly place the item in your pack.
if ( !obj.Completed )
obj.Complete();
}
else
{
bone.Delete();
player.SendLocalizedMessage( 1049342, "", 0x22 ); // Rummaging through the bones you find a Daemon Bone, but can't pick it up because your pack is too full. Come back when you have more room in your pack.
}
return;
}
}
else if ( qs is TheSummoningQuest )
{
VanquishDaemonObjective obj = qs.FindObjective( typeof( VanquishDaemonObjective ) ) as VanquishDaemonObjective;
if ( obj != null && obj.Completed && obj.CorpseWithSkull == this )
{
GoldenSkull sk = new GoldenSkull();
if ( player.PlaceInBackpack( sk ) )
{
obj.CorpseWithSkull = null;
player.SendLocalizedMessage( 1050022 ); // For your valor in combating the devourer, you have been awarded a golden skull.
qs.Complete();
}
else
{
sk.Delete();
player.SendLocalizedMessage( 1050023 ); // You find a golden skull, but your backpack is too full to carry it.
}
}
}
}
base.OnDoubleClick( from );
if ( from != m_Owner )
from.RevealingAction();
}
else
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
return;
}
}
public override void OnDoubleClick( Mobile from )
{
Open( from, Core.AOS );
}
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 OnAosSingleClick( Mobile from )
{
int hue = Notoriety.GetHue( NotorietyHandlers.CorpseNotoriety( from, this ) );
ObjectPropertyList opl = this.PropertyList;
if ( opl.Header > 0 )
from.Send( new MessageLocalized( Serial, ItemID, MessageType.Label, hue, 3, opl.Header, Name, opl.HeaderArgs ) );
}
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 )
{
Mobile dead = m_Owner;
if ( m_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 );
m_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 );
}
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,336 @@
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 ( 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,94 @@
using System;
using System.Collections;
using Server;
namespace Server.Items
{
public class EffectItem : Item
{
private static ArrayList m_Free = new ArrayList(); // 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 = (EffectItem)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 Item m_Item;
public FreeTimer( Item 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,31 @@
using System;
namespace Server.Items
{
public class ExecutionersCap : Item
{
[Constructable]
public ExecutionersCap() : base(0xF83)
{
Weight = 1.0;
}
public ExecutionersCap(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,116 @@
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,76 @@
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,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,21 @@
using System;
using Server;
namespace Server.Items
{
interface IDurability
{
int InitMinHits { get; }
int InitMaxHits { get; }
int HitPoints { get; set; }
int MaxHitPoints { get; set; }
//Maybe a scale/unscale durability?
}
interface IWearableDurability : IDurability
{
int OnHit( BaseWeapon weapon, int damageTaken );
}
}

View file

@ -0,0 +1,247 @@
using System;
using Server;
using Server.Network;
using Server.Regions;
using Server.Multis;
using Server.Gumps;
using Server.Targeting;
namespace Server.Items
{
public enum DecorateCommand
{
None,
Turn,
Up,
Down
}
public class InteriorDecorator : Item
{
private DecorateCommand m_Command;
[CommandProperty( AccessLevel.GameMaster )]
public DecorateCommand Command{ get{ return m_Command; } set{ m_Command = value; InvalidateProperties(); } }
[Constructable]
public InteriorDecorator() : base( 0xFC1 )
{
Weight = 1.0;
LootType = LootType.Blessed;
}
public override int LabelNumber{ get{ return 1041280; } } // an interior decorator
public InteriorDecorator( Serial serial ) : base( serial )
{
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
if ( m_Command != DecorateCommand.None )
list.Add( 1018322 + (int)m_Command ); // Turn/Up/Down
}
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 ( !CheckUse( this, from ) )
return;
if ( m_Command == DecorateCommand.None )
from.SendGump( new InternalGump( this ) );
else
from.Target = new InternalTarget( this );
}
public static bool InHouse( Mobile from )
{
BaseHouse house = BaseHouse.FindHouseAt( from );
return ( house != null && house.IsCoOwner( from ) );
}
public static bool CheckUse( InteriorDecorator tool, Mobile from )
{
/*if ( tool.Deleted || !tool.IsChildOf( from.Backpack ) )
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
else*/
if ( !InHouse( from ) )
from.SendLocalizedMessage( 502092 ); // You must be in your house to do this.
else
return true;
return false;
}
private class InternalGump : Gump
{
private InteriorDecorator m_Decorator;
public InternalGump( InteriorDecorator decorator ) : base( 150, 50 )
{
m_Decorator = decorator;
AddBackground( 0, 0, 200, 200, 2600 );
AddButton( 50, 45, 2152, 2154, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 90, 50, 70, 40, 1018323, false, false ); // Turn
AddButton( 50, 95, 2152, 2154, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 90, 100, 70, 40, 1018324, false, false ); // Up
AddButton( 50, 145, 2152, 2154, 3, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 90, 150, 70, 40, 1018325, false, false ); // Down
}
public override void OnResponse( NetState sender, RelayInfo info )
{
DecorateCommand command = DecorateCommand.None;
switch ( info.ButtonID )
{
case 1: command = DecorateCommand.Turn; break;
case 2: command = DecorateCommand.Up; break;
case 3: command = DecorateCommand.Down; break;
}
if ( command != DecorateCommand.None )
{
m_Decorator.Command = command;
sender.Mobile.Target = new InternalTarget( m_Decorator );
}
}
}
private class InternalTarget : Target
{
private InteriorDecorator m_Decorator;
public InternalTarget( InteriorDecorator decorator ) : base( -1, false, TargetFlags.None )
{
CheckLOS = false;
m_Decorator = decorator;
}
protected override void OnTargetNotAccessible( Mobile from, object targeted )
{
OnTarget( from, targeted );
}
protected override void OnTarget( Mobile from, object targeted )
{
if ( targeted == m_Decorator )
{
m_Decorator.Command = DecorateCommand.None;
from.SendGump( new InternalGump( m_Decorator ) );
}
else if ( targeted is Item && InteriorDecorator.CheckUse( m_Decorator, from ) )
{
BaseHouse house = BaseHouse.FindHouseAt( from );
Item item = (Item)targeted;
if ( house == null || !house.IsCoOwner( from ) )
{
from.SendLocalizedMessage( 502092 ); // You must be in your house to do this.
}
else if ( item.Parent != null || !house.IsInside( item ) )
{
from.SendLocalizedMessage( 1042270 ); // That is not in your house.
}
else if ( !house.IsLockedDown( item ) && !house.IsSecure( item ) )
{
from.SendLocalizedMessage( 1042271 ); // That is not locked down.
}
else if ( item is VendorRentalContract )
{
from.SendLocalizedMessage( 1062491 ); // You cannot use the house decorator on that object.
}
else if ( item.TotalWeight + item.PileWeight > 100 )
{
from.SendLocalizedMessage( 1042272 ); // That is too heavy.
}
else
{
switch ( m_Decorator.Command )
{
case DecorateCommand.Up: Up( item, from ); break;
case DecorateCommand.Down: Down( item, from ); break;
case DecorateCommand.Turn: Turn( item, from ); break;
}
}
}
}
private static void Turn( Item item, Mobile from )
{
FlipableAttribute[] attributes = (FlipableAttribute[])item.GetType().GetCustomAttributes( typeof( FlipableAttribute ), false );
if( attributes.Length > 0 )
attributes[0].Flip( item );
else
from.SendLocalizedMessage( 1042273 ); // You cannot turn that.
}
private static void Up( Item item, Mobile from )
{
int floorZ = GetFloorZ( item );
if ( floorZ > int.MinValue && item.Z < (floorZ + 15) ) // Confirmed : no height checks here
item.Location = new Point3D( item.Location, item.Z + 1 );
else
from.SendLocalizedMessage( 1042274 ); // You cannot raise it up any higher.
}
private static void Down( Item item, Mobile from )
{
int floorZ = GetFloorZ( item );
if ( floorZ > int.MinValue && item.Z > GetFloorZ( item ) )
item.Location = new Point3D( item.Location, item.Z - 1 );
else
from.SendLocalizedMessage( 1042275 ); // You cannot lower it down any further.
}
private static int GetFloorZ( Item item )
{
Map map = item.Map;
if ( map == null )
return int.MinValue;
Tile[] tiles = map.Tiles.GetStaticTiles( item.X, item.Y, true );
int z = int.MinValue;
for ( int i = 0; i < tiles.Length; ++i )
{
Tile tile = tiles[i];
ItemData id = TileData.ItemTable[tile.ID & 0x3FFF];
int top = tile.Z; // Confirmed : no height checks here
if ( id.Surface && !id.Impassable && top > z && top <= item.Z )
z = top;
}
return z;
}
}
}
}

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

@ -0,0 +1,468 @@
using System;
using System.Collections;
using Server.Network;
using Server.Targeting;
using Server.Prompts;
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.BankBox, 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 ( from.CheckTargetSkill( SkillName.Tinkering, k, 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,206 @@
using System;
using System.Collections;
using Server;
using Server.Targeting;
namespace Server.Items
{
public class KeyRing : Item
{
public static readonly int MaxKeys = 20;
private ArrayList m_Keys;
public ArrayList Keys{ get{ return m_Keys; } }
[Constructable]
public KeyRing() : base( 0x1011 )
{
Weight = 1.0; // They seem to have no weight on OSI ?!
m_Keys = new ArrayList();
}
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 = (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 = (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( m_Keys );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_Keys = reader.ReadItemList();
}
}
}

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[0x2199].Flags = TileFlag.Wall | TileFlag.NoShoot;
TileData.ItemTable[0x2199].Height = 20;
}
public override string DefaultName
{
get { return "no line of sight"; }
}
[Constructable]
public LOSBlocker() : base( 0x2199 )
{
Movable = false;
}
public LOSBlocker( Serial serial ) : base( serial )
{
}
public override void SendInfoTo( NetState state )
{
Mobile mob = state.Mobile;
if ( mob != null && mob.AccessLevel >= AccessLevel.GameMaster )
state.Send( new GMItemPacket( this ) );
else
state.Send( WorldPacket );
if ( ObjectPropertyList.Enabled )
state.Send( OPLPacket );
}
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 = 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,203 @@
using System;
using Server;
using Server.Network;
using Server.Mobiles;
namespace Server.Items
{
public enum MoonstoneType
{
Felucca, Trammel
}
public class Moonstone : Item
{
private MoonstoneType m_Type;
[CommandProperty( AccessLevel.GameMaster )]
public MoonstoneType Type
{
get
{
return m_Type;
}
set
{
m_Type = value;
InvalidateProperties();
}
}
public override int LabelNumber{ get{ return 1041490 + (int)m_Type; } }
[Constructable]
public Moonstone( MoonstoneType type ) : base( 0xF8B )
{
Weight = 1.0;
m_Type = type;
}
public Moonstone( Serial serial ) : base( serial )
{
}
public override void OnSingleClick( Mobile from )
{
if ( IsChildOf( from.Backpack ) )
{
Hue = Utility.RandomBirdHue();
ProcessDelta();
from.SendLocalizedMessage( 1005398 ); // The stone's substance shifts as you examine it.
}
base.OnSingleClick( from );
}
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 if ( from.Mounted )
{
from.SendLocalizedMessage( 1005399 ); // You can not bury a stone while you sit on a mount.
}
else if ( !from.Body.IsHuman )
{
from.SendLocalizedMessage( 1005400 ); // You can not bury a stone in this form.
}
else if ( Factions.Sigil.ExistsOn( from ) )
{
from.SendLocalizedMessage( 1061632 ); // You can't do that while carrying the sigil.
}
else if ( from.Map == GetTargetMap() || ( from.Map != Map.Trammel && from.Map != Map.Felucca ) )
{
from.SendLocalizedMessage( 1005401 ); // You cannot bury the stone here.
}
else if ( from is PlayerMobile && ((PlayerMobile)from).Young )
{
from.SendLocalizedMessage( 1049543 ); // You decide against traveling to Felucca while you are still young.
}
else if ( from.Kills >= 5 )
{
from.SendLocalizedMessage( 1005402 ); // The magic of the stone cannot be evoked by someone with blood on their hands.
}
else if ( from.Criminal )
{
from.SendLocalizedMessage( 1005403 ); // The magic of the stone cannot be evoked by the lawless.
}
else if ( !Region.Find( from.Location, from.Map ).IsDefault || !Region.Find( from.Location, GetTargetMap() ).IsDefault )
{
from.SendLocalizedMessage( 1005401 ); // You cannot bury the stone here.
}
else if ( !GetTargetMap().CanFit( from.Location, 16 ) )
{
from.SendLocalizedMessage( 1005408 ); // Something is blocking the facet gate exit.
}
else
{
Movable = false;
MoveToWorld( from.Location, from.Map );
from.Animate( 32, 5, 1, true, false, 0 );
new SettleTimer( this, from.Location, from.Map, GetTargetMap(), from ).Start();
}
}
public Map GetTargetMap()
{
return ( m_Type == MoonstoneType.Felucca ) ? Map.Felucca : Map.Trammel;
}
private class SettleTimer : Timer
{
private Item m_Stone;
private Point3D m_Location;
private Map m_Map, m_TargetMap;
private Mobile m_Caster;
private int m_Count;
public SettleTimer( Item stone, Point3D loc, Map map, Map targetMap, Mobile caster ) : base( TimeSpan.FromSeconds( 2.5 ), TimeSpan.FromSeconds( 1.0 ) )
{
m_Stone = stone;
m_Location = loc;
m_Map = map;
m_TargetMap = targetMap;
m_Caster = caster;
}
protected override void OnTick()
{
++m_Count;
if ( m_Count == 1 )
{
m_Stone.PublicOverheadMessage( MessageType.Regular, 0x3B2, 1005414 ); // The stone settles into the ground.
}
else if ( m_Count >= 10 )
{
m_Stone.Location = new Point3D( m_Stone.X, m_Stone.Y, m_Stone.Z - 1 );
if ( m_Count == 16 )
{
if ( !Region.Find( m_Location, m_Map ).IsDefault || !Region.Find( m_Location, m_TargetMap ).IsDefault )
{
m_Stone.Movable = true;
m_Caster.AddToBackpack( m_Stone );
Stop();
return;
}
else if ( !m_TargetMap.CanFit( m_Location, 16 ) )
{
m_Stone.Movable = true;
m_Caster.AddToBackpack( m_Stone );
Stop();
return;
}
int hue = m_Stone.Hue;
if ( hue == 0 )
hue = Utility.RandomBirdHue();
new MoonstoneGate( m_Location, m_TargetMap, m_Map, m_Caster, hue );
new MoonstoneGate( m_Location, m_Map, m_TargetMap, m_Caster, hue );
m_Stone.Delete();
Stop();
}
}
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (int) m_Type );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_Type = (MoonstoneType)reader.ReadInt();
break;
}
}
}
}
}

View file

@ -0,0 +1,85 @@
using System;
using Server;
using Server.Network;
using Server.Engines.PartySystem;
namespace Server.Items
{
public class MoonstoneGate : Moongate
{
private Mobile m_Caster;
public MoonstoneGate( Point3D loc, Map map, Map targetMap, Mobile caster, int hue ) : base( loc, targetMap )
{
MoveToWorld( loc, map );
Dispellable = false;
Hue = hue;
m_Caster = caster;
new InternalTimer( this ).Start();
Effects.PlaySound( loc, map, 0x20E );
}
public MoonstoneGate( Serial serial ) : base( serial )
{
}
public override void CheckGate( Mobile m, int range )
{
if ( m.Kills >= 5 )
return;
Party casterParty = Party.Get( m_Caster );
Party userParty = Party.Get( m );
if ( m == m_Caster || (casterParty != null && userParty == casterParty) )
base.CheckGate( m, range );
}
public override void UseGate( Mobile m )
{
if ( m.Kills >= 5 )
return;
Party casterParty = Party.Get( m_Caster );
Party userParty = Party.Get( m );
if ( m == m_Caster || (casterParty != null && userParty == casterParty) )
base.UseGate( m );
}
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 InternalTimer : Timer
{
private Item m_Item;
public InternalTimer( Item item ) : base( TimeSpan.FromSeconds( 30.0 ) )
{
m_Item = item;
Priority = TimerPriority.OneSecond;
}
protected override void OnTick()
{
m_Item.Delete();
}
}
}
}

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,142 @@
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() : this( 1 )
{
}
[Constructable]
public OilCloth( int amount ) : base( 0x175D )
{
Hue = 2001;
Stackable = true;
Amount = amount;
}
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 )
{
// TODO: Need details on how oil cloths should get consumed here
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 if ( obj == from && obj is PlayerMobile )
{
PlayerMobile pm = (PlayerMobile)obj;
if ( pm.BodyMod == 183 || pm.BodyMod == 184 )
{
pm.SavagePaintExpiration = TimeSpan.Zero;
pm.BodyMod = 0;
pm.HueMod = -1;
from.SendLocalizedMessage( 1040006 ); // You wipe away all of your body paint.
Consume();
}
else
{
from.LocalOverheadMessage( Network.MessageType.Regular, 0x3B2, 1005422 ); // Hmmmm... this does not need to be cleaned.
}
}
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,247 @@
using System;
using Server;
using Server.Network;
namespace Server.Items
{
public class OrigamiPaper : Item
{
public override int LabelNumber{ get{ return 1030288; } } // origami paper
[Constructable]
public OrigamiPaper() : base( 0x2830 )
{
}
public OrigamiPaper( 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
{
this.Delete();
Item i = null;
switch ( Utility.Random( (from.BAC >= 5) ? 6 : 5) )
{
case 0: i = new OrigamiButterfly(); break;
case 1: i = new OrigamiSwan(); break;
case 2: i = new OrigamiFrog(); break;
case 3: i = new OrigamiShape(); break;
case 4: i = new OrigamiSongbird(); break;
case 5: i = new OrigamiFish(); break;
}
if( i != null )
from.AddToBackpack( i );
from.SendLocalizedMessage( 1070822 ); // You fold the paper into an interesting shape.
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class OrigamiButterfly : Item
{
public override int LabelNumber{ get{ return 1030296; } } // a delicate origami butterfly
[Constructable]
public OrigamiButterfly() : base( 0x2838 )
{
LootType = LootType.Blessed;
}
public OrigamiButterfly( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class OrigamiSwan : Item
{
public override int LabelNumber{ get{ return 1030297; } } // a delicate origami swan
[Constructable]
public OrigamiSwan() : base( 0x2839 )
{
LootType = LootType.Blessed;
}
public OrigamiSwan( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class OrigamiFrog : Item
{
public override int LabelNumber{ get{ return 1030298; } } // a delicate origami frog
[Constructable]
public OrigamiFrog() : base( 0x283A )
{
LootType = LootType.Blessed;
}
public OrigamiFrog( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class OrigamiShape : Item
{
public override int LabelNumber{ get{ return 1030299; } } // an intricate geometric origami shape
[Constructable]
public OrigamiShape() : base( 0x283B )
{
LootType = LootType.Blessed;
}
public OrigamiShape( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class OrigamiSongbird : Item
{
public override int LabelNumber{ get{ return 1030300; } } // a delicate origami songbird
[Constructable]
public OrigamiSongbird() : base( 0x283C )
{
LootType = LootType.Blessed;
}
public OrigamiSongbird( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class OrigamiFish : Item
{
public override int LabelNumber{ get{ return 1030301; } } // a delicate origami fish
[Constructable]
public OrigamiFish() : base( 0x283D )
{
LootType = LootType.Blessed;
}
public OrigamiFish( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,640 @@
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Multis;
using Server.Prompts;
using Server.Mobiles;
using Server.Network;
using System.Collections.Generic;
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 ArrayList m_Messages;
private string m_Title;
private SecureLevel m_Level;
public ArrayList 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 ArrayList();
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 )
((PlayerBBMessage)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 ArrayList( 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 ); // Seperator
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,104 @@
using System;
using Server;
using Server.Mobiles;
using Server.Multis;
namespace Server.Items
{
public class ContractOfEmployment : Item
{
public override int LabelNumber{ get{ return 1041243; } } // a contract of employment
[Constructable]
public ContractOfEmployment() : base( 0x14F0 )
{
Weight = 1.0;
//LootType = LootType.Blessed;
}
public ContractOfEmployment( 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 ( !IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
}
else if ( from.AccessLevel >= AccessLevel.GameMaster )
{
from.SendLocalizedMessage( 503248 ); // Your godly powers allow you to place this vendor whereever you wish.
Mobile v = new PlayerVendor( from, BaseHouse.FindHouseAt( from ) );
v.Direction = from.Direction & Direction.Mask;
v.MoveToWorld( from.Location, from.Map );
v.SayTo( from, 503246 ); // Ah! it feels good to be working again.
this.Delete();
}
else
{
BaseHouse house = BaseHouse.FindHouseAt( from );
if ( house == null )
{
from.SendLocalizedMessage( 503240 ); // Vendors can only be placed in houses.
}
else if ( !BaseHouse.NewVendorSystem && !house.IsFriend( from ) )
{
from.SendLocalizedMessage( 503242 ); // You must ask the owner of this building to name you a friend of the household in order to place a vendor here.
}
else if ( BaseHouse.NewVendorSystem && !house.IsOwner( from ) )
{
from.SendLocalizedMessage( 1062423 ); // Only the house owner can directly place vendors. Please ask the house owner to offer you a vendor contract so that you may place a vendor in this house.
}
else if ( !house.Public || !house.CanPlaceNewVendor() )
{
from.SendLocalizedMessage( 503241 ); // You cannot place this vendor or barkeep. Make sure the house is public and has sufficient storage available.
}
else
{
bool vendor, contract;
BaseHouse.IsThereVendor( from.Location, from.Map, out vendor, out contract );
if ( vendor )
{
from.SendLocalizedMessage( 1062677 ); // You cannot place a vendor or barkeep at this location.
}
else if ( contract )
{
from.SendLocalizedMessage( 1062678 ); // You cannot place a vendor or barkeep on top of a rental contract!
}
else
{
Mobile v = new PlayerVendor( from, house );
v.Direction = from.Direction & Direction.Mask;
v.MoveToWorld( from.Location, from.Map );
v.SayTo( from, 503246 ); // Ah! it feels good to be working again.
this.Delete();
}
}
}
}
}
}

View file

@ -0,0 +1,161 @@
using System;
using Server;
using Server.Mobiles;
using Server.Spells;
using System.Collections;
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;
[CommandProperty( AccessLevel.GameMaster )]
public bool Drying
{
get
{
return m_Drying;
}
set
{
m_Drying = value;
if( m_Drying )
ItemID = 0x122A;
else
ItemID = 0x122B;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public TimeSpan Duration{ get{ return m_Duration; } set{ m_Duration = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public int MinDamage
{
get
{
return m_MinDamage;
}
set
{
if ( value < 1 )
value = 1;
m_MinDamage = value;
}
}
[CommandProperty( AccessLevel.GameMaster )]
public int MaxDamage
{
get
{
return m_MaxDamage;
}
set
{
if ( value < 1 )
value = 1;
if ( value < MinDamage )
value = MinDamage;
m_MaxDamage = value;
}
}
[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( !Drying && age > (m_Duration - age) )
Drying = true;
ArrayList toDamage = new ArrayList();
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( (Mobile)toDamage[i] );
}
}
public override bool OnMoveOver( Mobile m )
{
Damage( m );
return true;
}
public void Damage( Mobile m )
{
m.Damage( Utility.RandomMinMax( MinDamage, 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,45 @@
using System;
using Server.Network;
namespace Server.Items
{
public class PowerCrystal : Item
{
public override string DefaultName
{
get { return "power crystal"; }
}
[Constructable]
public PowerCrystal() : base( 0x1F1C )
{
Weight = 1.0;
}
public PowerCrystal( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( this.GetWorldLocation(), 3 ))
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
else
from.SendAsciiMessage( "This looks like part of a larger contraption." );
}
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,571 @@
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Network;
namespace Server.Items
{
public class PowerGenerator : BaseAddon
{
[Constructable]
public PowerGenerator() : this( Utility.RandomMinMax( 3, 6 ) )
{
}
[Constructable]
public PowerGenerator( int sideLength )
{
AddGeneratorComponent( 0x4FA1, 0, 0, 0 );
AddGeneratorComponent( 0x76, -1, 0, 0 );
AddGeneratorComponent( 0x75, 0, -1, 0 );
AddGeneratorComponent( 0x37F4, 0, 0, 13 );
AddComponent( new ControlPanel( sideLength ), 1, 0, -2 );
}
public override bool ShareHue{ get{ return false; } }
private void AddGeneratorComponent( int itemID, int x, int y, int z )
{
AddonComponent component = new AddonComponent( itemID );
component.Name = "a power generator";
component.Hue = 0x451;
AddComponent( component, x, y, z );
}
public PowerGenerator( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class ControlPanel : AddonComponent
{
private static readonly TimeSpan m_UseTimeout = TimeSpan.FromMinutes( 2.0 );
public struct Node
{
private int m_X;
private int m_Y;
public int X{ get{ return m_X; } set{ m_X = value; } }
public int Y{ get{ return m_Y; } set{ m_Y = value; } }
public Node( int x, int y )
{
m_X = x;
m_Y = y;
}
}
private int m_SideLength;
private Node[] m_Path;
[CommandProperty( AccessLevel.GameMaster )]
public int SideLength
{
get{ return m_SideLength; }
set
{
if ( value < 3 )
value = 3;
else if ( value > 6 )
value = 6;
if ( m_SideLength != value )
{
m_SideLength = value;
InitPath();
}
}
}
public Node[] Path{ get{ return m_Path; } }
public override string DefaultName
{
get { return "a control panel"; }
}
public ControlPanel( int sideLength ) : base( 0xBDC )
{
Hue = 0x835;
SideLength = sideLength;
}
private enum PathDirection
{
Left,
Up,
Right,
Down
}
public void InitPath()
{
// Depth-First Search algorithm
int totalNodes = SideLength * SideLength;
Node[] stack = new Node[totalNodes];
Node current = stack[0] = new Node( 0, 0 );
int stackSize = 1;
bool[,] visited = new bool[SideLength, SideLength];
visited[0, 0] = true;
while ( true )
{
PathDirection[] choices = new PathDirection[4];
int count = 0;
if ( current.X > 0 && !visited[current.X - 1, current.Y] )
choices[count++] = PathDirection.Left;
if ( current.Y > 0 && !visited[current.X, current.Y - 1] )
choices[count++] = PathDirection.Up;
if ( current.X < SideLength - 1 && !visited[current.X + 1, current.Y] )
choices[count++] = PathDirection.Right;
if ( current.Y < SideLength - 1 && !visited[current.X, current.Y + 1] )
choices[count++] = PathDirection.Down;
if ( count > 0 )
{
PathDirection dir = choices[Utility.Random( count )];
switch ( dir )
{
case PathDirection.Left:
current = new Node( current.X - 1, current.Y );
break;
case PathDirection.Up:
current = new Node( current.X, current.Y - 1 );
break;
case PathDirection.Right:
current = new Node( current.X + 1, current.Y );
break;
default:
current = new Node( current.X, current.Y + 1 );
break;
}
stack[stackSize++] = current;
if ( current.X == SideLength - 1 && current.Y == SideLength - 1 )
break;
visited[current.X, current.Y] = true;
}
else
{
current = stack[--stackSize - 1];
}
}
m_Path = new Node[stackSize];
for ( int i = 0; i < stackSize; i++ )
{
m_Path[i] = stack[i];
}
if ( m_User != null )
{
m_User.CloseGump( typeof( GameGump ) );
m_User = null;
}
}
private Mobile m_User;
private DateTime m_LastUse;
public override void OnDoubleClick( Mobile from )
{
if ( !from.InRange( this, 3 ) )
{
from.SendLocalizedMessage( 500446 ); // That is too far away.
return;
}
if ( m_User != null )
{
if ( m_User == from )
return;
if ( m_User.Deleted || m_User.Map != Map || !m_User.InRange( this, 3 )
|| m_User.NetState == null || DateTime.Now - m_LastUse >= m_UseTimeout )
{
m_User.CloseGump( typeof( GameGump ) );
}
else
{
from.SendMessage( "Someone is currently using the control panel." );
return;
}
}
m_User = from;
m_LastUse = DateTime.Now;
from.SendGump( new GameGump( this, from, 0, false ) );
}
private class GameGump : Gump
{
private enum NodeHue
{
Gray,
Blue,
Red
}
private ControlPanel m_Panel;
private Mobile m_From;
private int m_Step;
public GameGump( ControlPanel panel, Mobile from, int step, bool hint ) : base( 5, 30 )
{
m_Panel = panel;
m_From = from;
m_Step = step;
int sideLength = panel.SideLength;
AddBackground( 50, 0, 530, 410, 0xA28 );
AddImage( 0, 0, 0x28C8 );
AddImage( 547, 0, 0x28C9 );
AddBackground( 95, 20, 442, 90, 0xA28 );
AddHtml( 229, 35, 300, 45, "GENERATOR CONTROL PANEL", false, false );
AddHtml( 223, 60, 300, 70, "Use the Directional Controls to", false, false );
AddHtml( 253, 75, 300, 85, "Close the Grid Circuit", false, false );
AddImage( 140, 40, 0x28D3 );
AddImage( 420, 40, 0x28D3 );
AddBackground( 365, 120, 178, 210, 0x1400 );
AddImage( 365, 115, 0x28D4 );
AddImage( 365, 288, 0x28D4 );
AddImage( 414, 189, 0x589 );
AddImage( 435, 210, 0xA52 );
AddButton( 408, 222, 0x29EA, 0x29EC, 1, GumpButtonType.Reply, 0 ); // Left
AddButton( 448, 185, 0x29CC, 0x29CE, 2, GumpButtonType.Reply, 0 ); // Up
AddButton( 473, 222, 0x29D6, 0x29D8, 3, GumpButtonType.Reply, 0 ); // Right
AddButton( 448, 243, 0x29E0, 0x29E2, 4, GumpButtonType.Reply, 0 ); // Down
AddBackground( 90, 115, 30 + 40 * sideLength, 30 + 40 * sideLength, 0xA28 );
AddBackground( 100, 125, 10 + 40 * sideLength, 10 + 40 * sideLength, 0x1400 );
for ( int i = 0; i < sideLength; i++ )
{
for ( int j = 0; j < sideLength - 1; j++ )
{
AddImage( 120 + 40 * i, 162 + 40 * j, 0x13F9 );
}
}
for ( int i = 0; i < sideLength - 1; i++ )
{
for ( int j = 0; j < sideLength; j++ )
{
AddImage( 138 + 40 * i, 147 + 40 * j, 0x13FD );
}
}
Node[] path = panel.Path;
NodeHue[,] hues = new NodeHue[sideLength, sideLength];
for ( int i = 0; i <= step; i++ )
{
Node n = path[i];
hues[n.X, n.Y] = NodeHue.Blue;
}
Node lastNode = path[path.Length - 1];
hues[lastNode.X, lastNode.Y] = NodeHue.Red;
for ( int i = 0; i < sideLength; i++ )
{
for ( int j = 0; j < sideLength; j++ )
{
AddNode( 110 + 40 * i, 135 + 40 * j, hues[i, j] );
}
}
Node curNode = path[step];
AddImage( 118 + 40 * curNode.X, 143 + 40 * curNode.Y, 0x13A8 );
if ( hint )
{
Node nextNode = path[step + 1];
AddImage( 119 + 40 * nextNode.X, 143 + 40 * nextNode.Y, 0x939 );
}
if ( from.Skills.Lockpicking.Value >= 65.0 )
{
AddButton( 365, 350, 0xFA6, 0xFA7, 5, GumpButtonType.Reply, 0 );
AddHtml( 405, 345, 140, 40, "Attempt to Decipher the Circuit Path", false, false );
}
}
private void AddNode( int x, int y, NodeHue hue )
{
int id;
switch ( hue )
{
case NodeHue.Gray: id = 0x25F8; break;
case NodeHue.Blue: id = 0x868; break;
default: id = 0x9A8; break;
}
AddImage( x, y, id );
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( m_Panel.Deleted || info.ButtonID == 0 || !m_From.CheckAlive() )
{
m_Panel.m_User = null;
return;
}
if ( m_From.Map != m_Panel.Map || !m_From.InRange( m_Panel, 3 ) )
{
m_From.SendLocalizedMessage( 500446 ); // That is too far away.
m_Panel.m_User = null;
return;
}
Node nextNode = m_Panel.Path[m_Step + 1];
if ( info.ButtonID == 5 ) // Attempt to Decipher
{
double lockpicking = m_From.Skills.Lockpicking.Value;
if ( lockpicking < 65.0 )
return;
m_From.PlaySound( 0x241 );
if ( 40.0 + Utility.RandomDouble() * 80.0 < lockpicking )
{
m_From.SendGump( new GameGump( m_Panel, m_From, m_Step, true ) );
m_Panel.m_LastUse = DateTime.Now;
}
else
{
m_Panel.DoDamage( m_From );
m_Panel.m_User = null;
}
}
else
{
Node curNode = m_Panel.Path[m_Step];
int newX, newY;
switch ( info.ButtonID )
{
case 1: // Left
newX = curNode.X - 1;
newY = curNode.Y;
break;
case 2: // Up
newX = curNode.X;
newY = curNode.Y - 1;
break;
case 3: // Right
newX = curNode.X + 1;
newY = curNode.Y;
break;
case 4: // Down
newX = curNode.X;
newY = curNode.Y + 1;
break;
default:
return;
}
if ( nextNode.X == newX && nextNode.Y == newY )
{
if ( m_Step + 1 == m_Panel.Path.Length - 1 )
{
m_Panel.Solve( m_From );
m_Panel.m_User = null;
}
else
{
m_From.PlaySound( 0x1F4 );
m_From.SendGump( new GameGump( m_Panel, m_From, m_Step + 1, false ) );
m_Panel.m_LastUse = DateTime.Now;
}
}
else
{
m_Panel.DoDamage( m_From );
m_Panel.m_User = null;
}
}
}
}
private Hashtable m_DamageTable = new Hashtable();
public void DoDamage( Mobile to )
{
to.Send( new UnicodeMessage( Serial, ItemID, MessageType.Regular, 0x3B2, 3, "", "", "The generator shoots an arc of electricity at you!" ) );
to.BoltEffect( 0 );
to.LocalOverheadMessage( MessageType.Regular, 0xC9, true, "* Your body convulses from electric shock *" );
to.NonlocalOverheadMessage( MessageType.Regular, 0xC9, true, string.Format( "* {0} spasms from electric shock *", to.Name ) );
AOS.Damage( to, to, 60, 0, 0, 0, 0, 100 );
if ( !to.Alive )
return;
if ( m_DamageTable[to] == null )
{
to.Frozen = true;
DamageTimer timer = new DamageTimer( this, to );
m_DamageTable[to] = timer;
timer.Start();
}
}
private class DamageTimer : Timer
{
private ControlPanel m_Panel;
private Mobile m_To;
private int m_Step;
public DamageTimer( ControlPanel panel, Mobile to ) : base( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 5.0 ) )
{
m_Panel = panel;
m_To = to;
m_Step = 0;
Priority = TimerPriority.TwoFiftyMS;
}
protected override void OnTick()
{
if ( m_Panel.Deleted || m_To.Deleted || !m_To.Alive )
{
End();
return;
}
m_To.PlaySound( 0x28 );
m_To.LocalOverheadMessage( MessageType.Regular, 0xC9, true, "* Your body convulses from electric shock *" );
m_To.NonlocalOverheadMessage( MessageType.Regular, 0xC9, true, string.Format( "* {0} spasms from electric shock *", m_To.Name ) );
AOS.Damage( m_To, m_To, 20, 0, 0, 0, 0, 100 );
if ( ++m_Step >= 3 || !m_To.Alive )
{
End();
}
}
private void End()
{
m_Panel.m_DamageTable.Remove( m_To );
m_To.Frozen = false;
Stop();
}
}
public void Solve( Mobile from )
{
Effects.PlaySound( Location, Map, 0x211 );
Effects.PlaySound( Location, Map, 0x1F3 );
Effects.SendLocationEffect( Location, Map, 0x36B0, 4, 4 );
Effects.SendLocationEffect( new Point3D( X - 1, Y - 1, Z + 2 ), Map, 0x36B0, 4, 4 );
Effects.SendLocationEffect( new Point3D( X - 2, Y - 1, Z + 2 ), Map, 0x36B0, 4, 4 );
from.SendMessage( "You scrounge some gems from the wreckage." );
for ( int i = 0; i < SideLength; i++ )
{
from.AddToBackpack( new ArcaneGem() );
}
from.AddToBackpack( new Diamond( SideLength ) );
Item ore = new ShadowIronOre( 9 );
ore.MoveToWorld( new Point3D( X - 1, Y, Z + 2 ), Map );
ore = new ShadowIronOre( 14 );
ore.MoveToWorld( new Point3D( X - 2, Y - 1, Z + 2 ), Map );
Delete();
}
public ControlPanel( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( (int) 0 ); // version
writer.WriteEncodedInt( (int) m_SideLength );
writer.WriteEncodedInt( (int) m_Path.Length );
for ( int i = 0; i < m_Path.Length; i++ )
{
Node cur = m_Path[i];
writer.WriteEncodedInt( cur.X );
writer.WriteEncodedInt( cur.Y );
}
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_SideLength = reader.ReadEncodedInt();
m_Path = new Node[reader.ReadEncodedInt()];
for ( int i = 0; i < m_Path.Length; i++ )
{
m_Path[i] = new Node( reader.ReadEncodedInt(), reader.ReadEncodedInt() );
}
}
}
}

View file

@ -0,0 +1,159 @@
using System;
using Server;
using Server.Gumps;
using Server.Network;
namespace Server.Items
{
public abstract class PromotionalToken : Item
{
public abstract Item CreateItemFor( Mobile from );
public abstract TextDefinition ItemName{ get; }
public abstract TextDefinition ItemRecieveMessage { get; }
public abstract TextDefinition ItemGumpName { get; }
public PromotionalToken() : base( 0x2AAA )
{
LootType = LootType.Blessed;
Light = LightType.Circle300;
Weight = 5.0;
}
public PromotionalToken( Serial serial ) : base( serial )
{
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
list.Add( 1070998, ItemName.ToString() ); // Use this to redeem<br>your ~1_PROMO~
}
public override void OnDoubleClick( Mobile from )
{
if( !IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1062334 ); // This item must be in your backpack to be used.
}
else
{
from.CloseGump( typeof( PromotionalTokenGump ) );
from.SendGump( new PromotionalTokenGump( this ) );
}
}
public override void OnRemoved( object parent )
{
Mobile m = null;
if( parent is Item )
m = ((Item)parent).RootParent as Mobile;
else if( parent is Mobile )
m = (Mobile)parent;
if( m != null )
m.CloseGump( typeof( PromotionalTokenGump ) );
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int)0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public override int LabelNumber { get { return 1070997; } } // A promotional token
private class PromotionalTokenGump : Gump
{
private PromotionalToken m_Token;
public PromotionalTokenGump( PromotionalToken token ) : base( 10, 10 )
{
m_Token = token;
AddPage( 0 );
AddBackground( 0, 0, 240, 135, 0x2422 );
AddHtmlLocalized( 15, 15, 210, 75, 1070972, 0x0, true, false ); // Click "OKAY" to redeem the following promotional item:
TextDefinition.AddHtmlText( this, 15, 60, 210, 75, m_Token.ItemGumpName, false, false );
AddButton( 160, 95, 0xF7, 0xF8, 1, GumpButtonType.Reply, 0 ); //Okay
AddButton( 90, 95, 0xF2, 0xF1, 0, GumpButtonType.Reply, 0 ); //Cancel
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if( info.ButtonID != 1 )
return;
Mobile from = sender.Mobile;
if( !m_Token.IsChildOf( from.Backpack ) )
{
from.SendLocalizedMessage( 1062334 ); // This item must be in your backpack to be used.
}
else
{
Item i = m_Token.CreateItemFor( from );
if( i != null )
{
from.BankBox.AddItem( i );
TextDefinition.SendMessageTo( from, m_Token.ItemRecieveMessage );
m_Token.Delete();
}
}
}
}
}
public class SoulstoneFragmentToken : PromotionalToken
{
public override Item CreateItemFor( Mobile from )
{
if( from != null && from.Account != null )
return new SoulstoneFragment( from.Account.ToString() );
else
return null;
}
public override TextDefinition ItemGumpName{ get{ return 1070999; } }// <center>Soulstone Fragment</center>
public override TextDefinition ItemName { get { return 1071000; } }//soulstone fragment
public override TextDefinition ItemRecieveMessage{ get{ return 1070976; } } // A soulstone fragment has been created in your bank box.
[Constructable]
public SoulstoneFragmentToken() : base()
{
}
public SoulstoneFragmentToken( 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,467 @@
using System;
using System.Collections;
using Server;
using Server.Gumps;
using Server.Network;
using Server.Mobiles;
using Server.Commands;
namespace Server.Items
{
public class PublicMoongate : Item
{
public override bool ForceShowProperties{ get{ return ObjectPropertyList.Enabled; } }
[Constructable]
public PublicMoongate() : base( 0xF6C )
{
Movable = false;
Light = LightType.Circle300;
}
public PublicMoongate( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
if ( !from.Player )
return;
if ( from.InRange( GetWorldLocation(), 1 ) )
UseGate( from );
else
from.SendLocalizedMessage( 500446 ); // That is too far away.
}
public override bool OnMoveOver( Mobile m )
{
// Changed so criminals are not blocked by it.
if ( m.Player )
UseGate( m );
return true;
}
public override bool HandlesOnMovement{ get{ return true; } }
public override void OnMovement( Mobile m, Point3D oldLocation )
{
if ( m is PlayerMobile )
{
if ( !Utility.InRange( m.Location, this.Location, 1 ) && Utility.InRange( oldLocation, this.Location, 1 ) )
m.CloseGump( typeof( MoongateGump ) );
}
}
public bool UseGate( Mobile m )
{
if ( m.Criminal )
{
m.SendLocalizedMessage( 1005561, "", 0x22 ); // Thou'rt a criminal and cannot escape so easily.
return false;
}
else if ( Server.Spells.SpellHelper.CheckCombat( m ) )
{
m.SendLocalizedMessage( 1005564, "", 0x22 ); // Wouldst thou flee during the heat of battle??
return false;
}
else if ( m.Spell != null )
{
m.SendLocalizedMessage( 1049616 ); // You are too busy to do that at the moment.
return false;
}
else
{
m.CloseGump( typeof( MoongateGump ) );
m.SendGump( new MoongateGump( m, this ) );
if ( !m.Hidden || m.AccessLevel == AccessLevel.Player )
Effects.PlaySound( m.Location, m.Map, 0x20E );
return true;
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
public static void Initialize()
{
CommandSystem.Register( "MoonGen", AccessLevel.Administrator, new CommandEventHandler( MoonGen_OnCommand ) );
}
[Usage( "MoonGen" )]
[Description( "Generates public moongates. Removes all old moongates." )]
public static void MoonGen_OnCommand( CommandEventArgs e )
{
DeleteAll();
int count = 0;
count += MoonGen( PMList.Trammel );
count += MoonGen( PMList.Felucca );
count += MoonGen( PMList.Ilshenar );
count += MoonGen( PMList.Malas );
count += MoonGen( PMList.Tokuno );
World.Broadcast( 0x35, true, "{0} moongates generated.", count );
}
private static void DeleteAll()
{
ArrayList list = new ArrayList();
foreach ( Item item in World.Items.Values )
{
if ( item is PublicMoongate )
list.Add( item );
}
foreach ( Item item in list )
item.Delete();
if ( list.Count > 0 )
World.Broadcast( 0x35, true, "{0} moongates removed.", list.Count );
}
private static int MoonGen( PMList list )
{
foreach ( PMEntry entry in list.Entries )
{
Item item = new PublicMoongate();
item.MoveToWorld( entry.Location, list.Map );
if ( entry.Number == 1060642 ) // Umbra
item.Hue = 0x497;
}
return list.Entries.Length;
}
}
public class PMEntry
{
private Point3D m_Location;
private int m_Number;
public Point3D Location
{
get
{
return m_Location;
}
}
public int Number
{
get
{
return m_Number;
}
}
public PMEntry( Point3D loc, int number )
{
m_Location = loc;
m_Number = number;
}
}
public class PMList
{
private int m_Number, m_SelNumber;
private Map m_Map;
private PMEntry[] m_Entries;
public int Number
{
get
{
return m_Number;
}
}
public int SelNumber
{
get
{
return m_SelNumber;
}
}
public Map Map
{
get
{
return m_Map;
}
}
public PMEntry[] Entries
{
get
{
return m_Entries;
}
}
public PMList( int number, int selNumber, Map map, PMEntry[] entries )
{
m_Number = number;
m_SelNumber = selNumber;
m_Map = map;
m_Entries = entries;
}
public static readonly PMList Trammel =
new PMList( 1012000, 1012012, Map.Trammel, new PMEntry[]
{
new PMEntry( new Point3D( 4467, 1283, 5 ), 1012003 ), // Moonglow
new PMEntry( new Point3D( 1336, 1997, 5 ), 1012004 ), // Britain
new PMEntry( new Point3D( 1499, 3771, 5 ), 1012005 ), // Jhelom
new PMEntry( new Point3D( 771, 752, 5 ), 1012006 ), // Yew
new PMEntry( new Point3D( 2701, 692, 5 ), 1012007 ), // Minoc
new PMEntry( new Point3D( 1828, 2948,-20), 1012008 ), // Trinsic
new PMEntry( new Point3D( 643, 2067, 5 ), 1012009 ), // Skara Brae
new PMEntry( new Point3D( 3563, 2139, 34), 1012010 ), // Magincia
new PMEntry( new Point3D( 3763, 2771, 50), 1046259 ) // Haven
} );
public static readonly PMList Felucca =
new PMList( 1012001, 1012013, Map.Felucca, new PMEntry[]
{
new PMEntry( new Point3D( 4467, 1283, 5 ), 1012003 ), // Moonglow
new PMEntry( new Point3D( 1336, 1997, 5 ), 1012004 ), // Britain
new PMEntry( new Point3D( 1499, 3771, 5 ), 1012005 ), // Jhelom
new PMEntry( new Point3D( 771, 752, 5 ), 1012006 ), // Yew
new PMEntry( new Point3D( 2701, 692, 5 ), 1012007 ), // Minoc
new PMEntry( new Point3D( 1828, 2948,-20), 1012008 ), // Trinsic
new PMEntry( new Point3D( 643, 2067, 5 ), 1012009 ), // Skara Brae
new PMEntry( new Point3D( 3563, 2139, 34), 1012010 ), // Magincia
new PMEntry( new Point3D( 2711, 2234, 0 ), 1019001 ) // Buccaneer's Den
} );
public static readonly PMList Ilshenar =
new PMList( 1012002, 1012014, Map.Ilshenar, new PMEntry[]
{
new PMEntry( new Point3D( 1215, 467, -13 ), 1012015 ), // Compassion
new PMEntry( new Point3D( 722, 1366, -60 ), 1012016 ), // Honesty
new PMEntry( new Point3D( 744, 724, -28 ), 1012017 ), // Honor
new PMEntry( new Point3D( 281, 1016, 0 ), 1012018 ), // Humility
new PMEntry( new Point3D( 987, 1011, -32 ), 1012019 ), // Justice
new PMEntry( new Point3D( 1174, 1286, -30 ), 1012020 ), // Sacrifice
new PMEntry( new Point3D( 1532, 1340, - 3 ), 1012021 ), // Spirituality
new PMEntry( new Point3D( 528, 216, -45 ), 1012022 ), // Valor
new PMEntry( new Point3D( 1721, 218, 96 ), 1019000 ) // Chaos
} );
public static readonly PMList Malas =
new PMList( 1060643, 1062039, Map.Malas, new PMEntry[]
{
new PMEntry( new Point3D( 1015, 527, -65 ), 1060641 ), // Luna
new PMEntry( new Point3D( 1997, 1386, -85 ), 1060642 ) // Umbra
} );
public static readonly PMList Tokuno =
new PMList( 1063258, 1063415, Map.Tokuno, new PMEntry[]
{
new PMEntry( new Point3D( 1169, 998, 41 ), 1063412 ), // Isamu-Jima
new PMEntry( new Point3D( 802, 1204, 25 ), 1063413 ), // Makoto-Jima
new PMEntry( new Point3D( 270, 628, 15 ), 1063414 ) // Homare-Jima
} );
public static readonly PMList[] UORLists = new PMList[] { Trammel, Felucca };
public static readonly PMList[] UORlistsYoung = new PMList[] { Trammel };
public static readonly PMList[] LBRLists = new PMList[] { Trammel, Felucca, Ilshenar };
public static readonly PMList[] LBRListsYoung = new PMList[] { Trammel, Ilshenar };
public static readonly PMList[] AOSLists = new PMList[] { Trammel, Felucca, Ilshenar, Malas };
public static readonly PMList[] AOSListsYoung = new PMList[] { Trammel, Ilshenar, Malas };
public static readonly PMList[] SELists = new PMList[] { Trammel, Felucca, Ilshenar, Malas, Tokuno };
public static readonly PMList[] SEListsYoung = new PMList[] { Trammel, Ilshenar, Malas, Tokuno };
public static readonly PMList[] RedLists = new PMList[] { Felucca };
public static readonly PMList[] SigilLists = new PMList[] { Felucca };
}
public class MoongateGump : Gump
{
private Mobile m_Mobile;
private Item m_Moongate;
private PMList[] m_Lists;
public MoongateGump( Mobile mobile, Item moongate ) : base( 100, 100 )
{
m_Mobile = mobile;
m_Moongate = moongate;
PMList[] checkLists;
if ( mobile.Player )
{
if ( Factions.Sigil.ExistsOn( mobile ) )
{
checkLists = PMList.SigilLists;
}
else if ( mobile.Kills >= 5 )
{
checkLists = PMList.RedLists;
}
else
{
int flags = mobile.NetState == null ? 0 : mobile.NetState.Flags;
bool young = mobile is PlayerMobile ? ((PlayerMobile)mobile).Young : false;
if ( Core.SE && (flags & 0x10) != 0 )
checkLists = young ? PMList.SEListsYoung : PMList.SELists;
else if ( Core.AOS && (flags & 0x8) != 0 )
checkLists = young ? PMList.AOSListsYoung : PMList.AOSLists;
else if ( (flags & 0x4) != 0 )
checkLists = young ? PMList.LBRListsYoung : PMList.LBRLists;
else
checkLists = young ? PMList.UORlistsYoung : PMList.UORLists;
}
}
else
{
checkLists = PMList.SELists;
}
m_Lists = new PMList[checkLists.Length];
for ( int i = 0; i < m_Lists.Length; ++i )
m_Lists[i] = checkLists[i];
for ( int i = 0; i < m_Lists.Length; ++i )
{
if ( m_Lists[i].Map == mobile.Map )
{
PMList temp = m_Lists[i];
m_Lists[i] = m_Lists[0];
m_Lists[0] = temp;
break;
}
}
AddPage( 0 );
AddBackground( 0, 0, 380, 280, 5054 );
AddButton( 10, 210, 4005, 4007, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 45, 210, 140, 25, 1011036, false, false ); // OKAY
AddButton( 10, 235, 4005, 4007, 0, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 45, 235, 140, 25, 1011012, false, false ); // CANCEL
AddHtmlLocalized( 5, 5, 200, 20, 1012011, false, false ); // Pick your destination:
for ( int i = 0; i < checkLists.Length; ++i )
{
AddButton( 10, 35 + (i * 25), 2117, 2118, 0, GumpButtonType.Page, Array.IndexOf( m_Lists, checkLists[i] ) + 1 );
AddHtmlLocalized( 30, 35 + (i * 25), 150, 20, checkLists[i].Number, false, false );
}
for ( int i = 0; i < m_Lists.Length; ++i )
RenderPage( i, Array.IndexOf( checkLists, m_Lists[i] ) );
}
private void RenderPage( int index, int offset )
{
PMList list = m_Lists[index];
AddPage( index + 1 );
AddButton( 10, 35 + (offset * 25), 2117, 2118, 0, GumpButtonType.Page, index + 1 );
AddHtmlLocalized( 30, 35 + (offset * 25), 150, 20, list.SelNumber, false, false );
PMEntry[] entries = list.Entries;
for ( int i = 0; i < entries.Length; ++i )
{
AddRadio( 200, 35 + (i * 25), 210, 211, false, (index * 100) + i );
AddHtmlLocalized( 225, 35 + (i * 25), 150, 20, entries[i].Number, false, false );
}
}
public override void OnResponse( NetState state, RelayInfo info )
{
if ( info.ButtonID == 0 ) // Cancel
return;
else if ( m_Mobile.Deleted || m_Moongate.Deleted || m_Mobile.Map == null )
return;
int[] switches = info.Switches;
if ( switches.Length == 0 )
return;
int switchID = switches[0];
int listIndex = switchID / 100;
int listEntry = switchID % 100;
if ( listIndex < 0 || listIndex >= m_Lists.Length )
return;
PMList list = m_Lists[listIndex];
if ( listEntry < 0 || listEntry >= list.Entries.Length )
return;
PMEntry entry = list.Entries[listEntry];
if ( !m_Mobile.InRange( m_Moongate.GetWorldLocation(), 1 ) || m_Mobile.Map != m_Moongate.Map )
{
m_Mobile.SendLocalizedMessage( 1019002 ); // You are too far away to use the gate.
}
else if ( m_Mobile.Player && m_Mobile.Kills >= 5 && list.Map != Map.Felucca )
{
m_Mobile.SendLocalizedMessage( 1019004 ); // You are not allowed to travel there.
}
else if ( Factions.Sigil.ExistsOn( m_Mobile ) && list.Map != Factions.Faction.Facet )
{
m_Mobile.SendLocalizedMessage( 1019004 ); // You are not allowed to travel there.
}
else if ( m_Mobile.Criminal )
{
m_Mobile.SendLocalizedMessage( 1005561, "", 0x22 ); // Thou'rt a criminal and cannot escape so easily.
}
else if ( Server.Spells.SpellHelper.CheckCombat( m_Mobile ) )
{
m_Mobile.SendLocalizedMessage( 1005564, "", 0x22 ); // Wouldst thou flee during the heat of battle??
}
else if ( m_Mobile.Spell != null )
{
m_Mobile.SendLocalizedMessage( 1049616 ); // You are too busy to do that at the moment.
}
else if ( m_Mobile.Map == list.Map && m_Mobile.InRange( entry.Location, 1 ) )
{
m_Mobile.SendLocalizedMessage( 1019003 ); // You are already there.
}
else
{
BaseCreature.TeleportPets( m_Mobile, entry.Location, list.Map );
m_Mobile.Combatant = null;
m_Mobile.Warmode = false;
m_Mobile.Hidden = true;
m_Mobile.MoveToWorld( entry.Location, list.Map );
Effects.PlaySound( entry.Location, list.Map, 0x1FE );
}
}
}
}

718
Scripts/Items/Misc/Rares.cs Normal file
View file

@ -0,0 +1,718 @@
using System;
namespace Server.Items
{
public class Rope : Item
{
[Constructable]
public Rope() : this( 1 )
{
}
[Constructable]
public Rope( int amount ) : base( 0x14F8 )
{
Stackable = true;
Weight = 1.0;
Amount = amount;
}
public Rope( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class IronWire : Item
{
[Constructable]
public IronWire() : this( 1 )
{
}
[Constructable]
public IronWire( int amount ) : base( 0x1876 )
{
Stackable = true;
Weight = 5.0;
Amount = amount;
}
public IronWire( 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();
if ( version < 1 && Weight == 2.0 )
Weight = 5.0;
}
}
public class SilverWire : Item
{
[Constructable]
public SilverWire() : this( 1 )
{
}
[Constructable]
public SilverWire( int amount ) : base( 0x1877 )
{
Stackable = true;
Weight = 5.0;
Amount = amount;
}
public SilverWire( Serial serial ) : base( serial )
{
}
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 && Weight == 2.0 )
Weight = 5.0;
}
}
public class GoldWire : Item
{
[Constructable]
public GoldWire() : this( 1 )
{
}
[Constructable]
public GoldWire( int amount ) : base( 0x1878 )
{
Stackable = true;
Weight = 5.0;
Amount = amount;
}
public GoldWire( Serial serial ) : base( serial )
{
}
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 && Weight == 2.0 )
Weight = 5.0;
}
}
public class CopperWire : Item
{
[Constructable]
public CopperWire() : this( 1 )
{
}
[Constructable]
public CopperWire( int amount ) : base( 0x1879 )
{
Stackable = true;
Weight = 5.0;
Amount = amount;
}
public CopperWire( Serial serial ) : base( serial )
{
}
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 && Weight == 2.0 )
Weight = 5.0;
}
}
public class WhiteDriedFlowers : Item
{
[Constructable]
public WhiteDriedFlowers() : this( 1 )
{
}
[Constructable]
public WhiteDriedFlowers( int amount ) : base( 0xC3C )
{
Stackable = true;
Weight = 1.0;
Amount = amount;
}
public WhiteDriedFlowers( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class GreenDriedFlowers : Item
{
[Constructable]
public GreenDriedFlowers() : this( 1 )
{
}
[Constructable]
public GreenDriedFlowers( int amount ) : base( 0xC3E )
{
Stackable = true;
Weight = 1.0;
Amount = amount;
}
public GreenDriedFlowers( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class DriedOnions : Item
{
[Constructable]
public DriedOnions() : this( 1 )
{
}
[Constructable]
public DriedOnions( int amount ) : base( 0xC40 )
{
Stackable = true;
Weight = 1.0;
Amount = amount;
}
public DriedOnions( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class DriedHerbs : Item
{
[Constructable]
public DriedHerbs() : this( 1 )
{
}
[Constructable]
public DriedHerbs( int amount ) : base( 0xC42 )
{
Stackable = true;
Weight = 1.0;
Amount = amount;
}
public DriedHerbs( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class HorseShoes : Item
{
[Constructable]
public HorseShoes() : base( 0xFB6 )
{
Weight = 3.0;
}
public HorseShoes( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class ForgedMetal : Item
{
[Constructable]
public ForgedMetal() : base( 0xFB8 )
{
Weight = 5.0;
}
public ForgedMetal( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class Whip : Item
{
[Constructable]
public Whip() : base( 0x166E )
{
Weight = 1.0;
}
public Whip( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class PaintsAndBrush : Item
{
[Constructable]
public PaintsAndBrush() : base( 0xFC1 )
{
Weight = 1.0;
}
public PaintsAndBrush( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class PenAndInk : Item
{
[Constructable]
public PenAndInk() : base( 0xFBF )
{
Weight = 1.0;
}
public PenAndInk( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
}
}
public class ChiselsNorth : Item
{
[Constructable]
public ChiselsNorth() : base( 0x1026 )
{
Weight = 1.0;
}
public ChiselsNorth( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class ChiselsWest : Item
{
[Constructable]
public ChiselsWest() : base( 0x1027 )
{
Weight = 1.0;
}
public ChiselsWest( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class DirtyPan : Item
{
[Constructable]
public DirtyPan() : base( 0x9E8 )
{
Weight = 1.0;
}
public DirtyPan( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class DirtySmallRoundPot : Item
{
[Constructable]
public DirtySmallRoundPot() : base( 0x9E7 )
{
Weight = 1.0;
}
public DirtySmallRoundPot( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class DirtyPot : Item
{
[Constructable]
public DirtyPot() : base( 0x9E6 )
{
Weight = 1.0;
}
public DirtyPot( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class DirtyRoundPot : Item
{
[Constructable]
public DirtyRoundPot() : base( 0x9DF )
{
Weight = 1.0;
}
public DirtyRoundPot( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class DirtyFrypan : Item
{
[Constructable]
public DirtyFrypan() : base( 0x9DE )
{
Weight = 1.0;
}
public DirtyFrypan( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class DirtySmallPot : Item
{
[Constructable]
public DirtySmallPot() : base( 0x9DD )
{
Weight = 1.0;
}
public DirtySmallPot( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
public class DirtyKettle : Item
{
[Constructable]
public DirtyKettle() : base( 0x9DC )
{
Weight = 1.0;
}
public DirtyKettle( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
}
}
}

View file

@ -0,0 +1,57 @@
using System;
using Server.Gumps;
namespace Server.Items
{
public class ResGate : Item
{
public override string DefaultName
{
get { return "a resurrection gate"; }
}
[Constructable]
public ResGate() : base( 0xF6C )
{
Movable = false;
Hue = 0x2D1;
Light = LightType.Circle300;
}
public ResGate( Serial serial ) : base( serial )
{
}
public override bool OnMoveOver( Mobile m )
{
if ( !m.Alive && m.Map != null && m.Map.CanFit( m.Location, 16, false, false ) )
{
m.PlaySound( 0x214 );
m.FixedEffect( 0x376A, 10, 16 );
m.CloseGump( typeof( ResurrectGump ) );
m.SendGump( new ResurrectGump( m ) );
}
else
{
m.SendLocalizedMessage( 502391 ); // Thou can not be resurrected there!
}
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,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,126 @@
using System;
using Server;
using Server.Multis;
namespace Server.Items
{
public class SerpentPillar : Item
{
private bool m_Active;
private string m_Word;
private Rectangle2D m_Destination;
[CommandProperty( AccessLevel.GameMaster )]
public bool Active
{
get{ return m_Active; }
set{ m_Active = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public string Word
{
get{ return m_Word; }
set{ m_Word = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public Rectangle2D Destination
{
get{ return m_Destination; }
set{ m_Destination = value; }
}
[Constructable]
public SerpentPillar() : this( null, new Rectangle2D(), false )
{
}
public SerpentPillar( string word, Rectangle2D destination ) : this( word, destination, true )
{
}
public SerpentPillar( string word, Rectangle2D destination, bool active ) : base( 0x233F )
{
Movable = false;
m_Active = active;
m_Word = word;
m_Destination = destination;
}
public override bool HandlesOnSpeech{ get{ return true; } }
public override void OnSpeech( SpeechEventArgs e )
{
Mobile from = e.Mobile;
if ( !e.Handled && from.InRange( this, 10 ) && e.Speech.ToLower() == this.Word )
{
BaseBoat boat = BaseBoat.FindBoatAt( from, from.Map );
if ( boat == null )
return;
if ( !this.Active )
{
if ( boat.TillerMan != null )
boat.TillerMan.Say( 502507 ); // Ar, Legend has it that these pillars are inactive! No man knows how it might be undone!
return;
}
Map map = from.Map;
for ( int i = 0; i < 5; i++ ) // Try 5 times
{
int x = Utility.Random( Destination.X, Destination.Width );
int y = Utility.Random( Destination.Y, Destination.Height );
int z = map.GetAverageZ( x, y );
Point3D dest = new Point3D( x, y, z );
if ( boat.CanFit( dest, map, boat.ItemID ) )
{
int xOffset = x - boat.X;
int yOffset = y - boat.Y;
int zOffset = z - boat.Z;
boat.Teleport( xOffset, yOffset, zOffset );
return;
}
}
if ( boat.TillerMan != null )
boat.TillerMan.Say( 502508 ); // Ar, I refuse to take that matey through here!
}
}
public SerpentPillar( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
writer.Write( (bool) m_Active );
writer.Write( (string) m_Word );
writer.Write( (Rectangle2D) m_Destination );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_Active = reader.ReadBool();
m_Word = reader.ReadString();
m_Destination = reader.ReadRect2D();
}
}
}

View file

@ -0,0 +1,186 @@
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;
LootType = LootType.Newbied;
}
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,191 @@
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;
LootType = LootType.Newbied;
}
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,99 @@
using System;
using Server;
namespace Server.Items
{
public class Static : Item
{
public Static() //Dupe-tastic!
: 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, 1020000 + 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,37 @@
using System;
namespace Server.Items
{
public class SwarmOfFlies : Item
{
public override string DefaultName
{
get { return "a swarm of flies"; }
}
[Constructable]
public SwarmOfFlies() : base( 0x91B )
{
Hue = 1;
Movable = false;
}
public SwarmOfFlies( 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,494 @@
using System;
using Server;
using Server.Network;
namespace Server.Items
{
public class Teleporter : Item
{
private bool m_Active, m_Creatures;
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(); }
}
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;
}
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;
StartTeleport( m );
return false;
}
return true;
}
public Teleporter( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 2 ); // version
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 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,151 @@
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 )
{
Hue = 0x3B2;
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, 0x11C );
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,61 @@
using System;
namespace Server.Items
{
[FlipableAttribute( 0xE41, 0xE40 )]
public class TrashChest : Container
{
public override int DefaultMaxWeight{ get{ return 0; } } // A value of 0 signals unlimited weight
public override bool IsDecoContainer
{
get{ return false; }
}
[Constructable]
public TrashChest() : base( 0xE41 )
{
Movable = false;
}
public TrashChest( 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 bool OnDragDrop( Mobile from, Item dropped )
{
if ( !base.OnDragDrop( from, dropped ) )
return false;
PublicOverheadMessage( Network.MessageType.Regular, 0x3B2, Utility.Random( 1042891, 8 ) );
dropped.Delete();
return true;
}
public override bool OnDragDropInto( Mobile from, Item item, Point3D p )
{
if ( !base.OnDragDropInto( from, item, p ) )
return false;
PublicOverheadMessage( Network.MessageType.Regular, 0x3B2, Utility.Random( 1042891, 8 ) );
item.Delete();
return true;
}
}
}

View file

@ -0,0 +1,46 @@
using System;
namespace Server.Items
{
public class TribalBerry : Item
{
public override int LabelNumber{ get{ return 1040001; } } // tribal berry
[Constructable]
public TribalBerry() : this( 1 )
{
}
[Constructable]
public TribalBerry( int amount ) : base( 0x9D0 )
{
Weight = 1.0;
Stackable = true;
Amount = amount;
Hue = 6;
}
public TribalBerry( 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();
if ( Hue == 4 )
Hue = 6;
}
}
}

View file

@ -0,0 +1,83 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Items
{
public class TribalPaint : Item
{
public override int LabelNumber{ get{ return 1040000; } } // savage kin paint
[Constructable]
public TribalPaint() : base( 0x9EC )
{
Hue = 2101;
Weight = 2.0;
}
public TribalPaint( Serial serial ) : base( serial )
{
}
public override void OnDoubleClick( Mobile from )
{
if ( IsChildOf( from.Backpack ) )
{
if ( Factions.Sigil.ExistsOn( from ) )
{
from.SendLocalizedMessage( 1010465 ); // You cannot disguise yourself while holding a sigil.
}
else if ( !from.CanBeginAction( typeof( Spells.Fifth.IncognitoSpell ) ) )
{
from.SendLocalizedMessage( 501698 ); // You cannot disguise yourself while incognitoed.
}
else if ( !from.CanBeginAction( typeof( Spells.Seventh.PolymorphSpell ) ) )
{
from.SendLocalizedMessage( 501699 ); // You cannot disguise yourself while polymorphed.
}
else if ( Spells.Necromancy.TransformationSpell.UnderTransformation( from ) )
{
from.SendLocalizedMessage( 501699 ); // You cannot disguise yourself while polymorphed.
}
else if ( Spells.Ninjitsu.AnimalForm.UnderTransformation( from ) )
{
from.SendLocalizedMessage( 1061634 ); // You cannot disguise yourself while in that form.
}
else if ( from.IsBodyMod || from.FindItemOnLayer( Layer.Helm ) is OrcishKinMask )
{
from.SendLocalizedMessage( 501605 ); // You are already disguised.
}
else
{
from.BodyMod = ( from.Female ? 184 : 183 );
from.HueMod = 0;
if ( from is PlayerMobile )
((PlayerMobile)from).SavagePaintExpiration = TimeSpan.FromDays( 7.0 );
from.SendLocalizedMessage( 1042537 ); // You now bear the markings of the savage tribe. Your body paint will last about a week or you can remove it with an oil cloth.
Consume();
}
}
else
{
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
}
}
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,117 @@
using System;
using Server;
using Server.Mobiles;
namespace Server.Items
{
public class UnholyBone : Item, ICarvable
{
private SpawnTimer m_Timer;
public override string DefaultName
{
get { return "unholy bone"; }
}
[Constructable]
public UnholyBone() : base( 0xF7E )
{
Movable = false;
Hue = 0x497;
m_Timer = new SpawnTimer( this );
m_Timer.Start();
}
public void Carve( Mobile from, Item item )
{
Effects.PlaySound( GetWorldLocation(), Map, 0x48F );
Effects.SendLocationEffect( GetWorldLocation(), Map, 0x3728, 10, 10, 0, 0 );
if ( 0.3 > Utility.RandomDouble() )
{
if ( ItemID == 0xF7E )
from.SendMessage( "You destroy the bone." );
else
from.SendMessage( "You destroy the bone pile." );
Gold gold = new Gold( 25, 100 );
gold.MoveToWorld( GetWorldLocation(), Map );
Delete();
m_Timer.Stop();
}
else
{
if ( ItemID == 0xF7E )
from.SendMessage( "You damage the bone." );
else
from.SendMessage( "You damage the bone pile." );
}
}
public UnholyBone( 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();
m_Timer = new SpawnTimer( this );
m_Timer.Start();
}
private class SpawnTimer : Timer
{
private Item m_Item;
public SpawnTimer( Item item ) : base( TimeSpan.FromSeconds( Utility.RandomMinMax( 5, 10 ) ) )
{
Priority = TimerPriority.FiftyMS;
m_Item = item;
}
protected override void OnTick()
{
if ( m_Item.Deleted )
return;
Mobile spawn;
switch ( Utility.Random( 12 ) )
{
default:
case 0: spawn = new Skeleton(); break;
case 1: spawn = new Zombie(); break;
case 2: spawn = new Wraith(); break;
case 3: spawn = new Spectre(); break;
case 4: spawn = new Ghoul(); break;
case 5: spawn = new Mummy(); break;
case 6: spawn = new Bogle(); break;
case 7: spawn = new RottingCorpse(); break;
case 8: spawn = new BoneKnight(); break;
case 9: spawn = new SkeletalKnight(); break;
case 10: spawn = new Lich(); break;
case 11: spawn = new LichLord(); break;
}
spawn.MoveToWorld( m_Item.Location, m_Item.Map );
m_Item.Delete();
}
}
}
}

View file

@ -0,0 +1,241 @@
using System;
using Server;
using Server.Network;
using System.Collections;
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 )
{
ArrayList list = new ArrayList();
foreach ( Item item in GetItemsInRange( NeighborRange ) )
{
if ( item != this && item is WarningItem )
list.Add( item );
}
for ( int i = 0; i < list.Count; i++ )
( (WarningItem) 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." );
}
}
}
}

View file

@ -0,0 +1,189 @@
using System;
using Server;
using Server.Multis;
using Server.Gumps;
using Server.Items;
using Server.Network;
namespace Server.Items
{
public abstract class BaseWindChimes : Item
{
private bool m_TurnedOn;
[CommandProperty( AccessLevel.GameMaster )]
public bool TurnedOn
{
get{ return m_TurnedOn; }
set{ m_TurnedOn = value; InvalidateProperties(); }
}
public BaseWindChimes( int itemID ) : base( itemID )
{
}
private static int[] m_Sounds = new int[] { 0x505, 0x506, 0x507 };
public static int[] Sounds
{
get{ return m_Sounds; }
}
public override bool HandlesOnMovement{ get{ return m_TurnedOn && IsLockedDown; } }
public override void OnMovement( Mobile m, Point3D oldLocation )
{
if ( m_TurnedOn && IsLockedDown && (!m.Hidden || m.AccessLevel == AccessLevel.Player) && Utility.InRange( m.Location, this.Location, 2 ) && !Utility.InRange( oldLocation, this.Location, 2 ) )
Effects.PlaySound( this.Location, this.Map, m_Sounds[Utility.Random( m_Sounds.Length )] );
base.OnMovement( m, oldLocation );
}
public BaseWindChimes( Serial serial ) : base( serial )
{
}
public override void GetProperties( ObjectPropertyList list )
{
base.GetProperties( list );
if ( m_TurnedOn )
list.Add( 502695 ); // turned on
else
list.Add( 502696 ); // turned off
}
public bool IsOwner( Mobile mob )
{
BaseHouse house = BaseHouse.FindHouseAt( this );
return ( house != null && house.IsOwner( mob ) );
}
public override void OnDoubleClick( Mobile from )
{
if ( IsOwner( from ) )
{
OnOffGump onOffGump = new OnOffGump( this );
from.SendGump( onOffGump );
}
else
{
from.SendLocalizedMessage( 502691 ); // You must be the owner to use this.
}
}
private class OnOffGump : Gump
{
private BaseWindChimes m_Chimes;
public OnOffGump( BaseWindChimes chimes ) : base( 150, 200 )
{
m_Chimes = chimes;
AddBackground( 0, 0, 300, 150, 0xA28 );
AddHtmlLocalized( 45, 20, 300, 35, chimes.TurnedOn ? 1011035 : 1011034, false, false ); // [De]Activate this item
AddButton( 40, 53, 0xFA5, 0xFA7, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 80, 55, 65, 35, 1011036, false, false ); // OKAY
AddButton( 150, 53, 0xFA5, 0xFA7, 0, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 190, 55, 100, 35, 1011012, false, false ); // CANCEL
}
public override void OnResponse( NetState sender, RelayInfo info )
{
Mobile from = sender.Mobile;
if ( info.ButtonID == 1 )
{
bool newValue = !m_Chimes.TurnedOn;
m_Chimes.TurnedOn = newValue;
if ( newValue && !m_Chimes.IsLockedDown )
from.SendLocalizedMessage( 502693 ); // Remember, this only works when locked down.
}
else
{
from.SendLocalizedMessage( 502694 ); // Cancelled action.
}
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (bool) m_TurnedOn );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 0:
{
m_TurnedOn = reader.ReadBool();
break;
}
}
}
}
public class WindChimes : BaseWindChimes
{
public override int LabelNumber{ get{ return 1030290; } }
[Constructable]
public WindChimes() : base( 0x2832 )
{
}
public WindChimes( 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 FancyWindChimes : BaseWindChimes
{
public override int LabelNumber{ get{ return 1030291; } }
[Constructable]
public FancyWindChimes() : base( 0x2833 )
{
}
public FancyWindChimes( 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();
}
}
}