#W# Initial Commit: Avatars Conquest
This commit is contained in:
commit
5df497787a
7510 changed files with 416048 additions and 0 deletions
99
Scripts/Items/Misc/AcidSlime.cs
Normal file
99
Scripts/Items/Misc/AcidSlime.cs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class AcidSlime : Item
|
||||
{
|
||||
private TimeSpan m_Duration;
|
||||
private int m_MinDamage;
|
||||
private int m_MaxDamage;
|
||||
private DateTime m_Created;
|
||||
private bool m_Drying;
|
||||
private Timer m_Timer;
|
||||
|
||||
[Constructable]
|
||||
public AcidSlime() : this( TimeSpan.FromSeconds( 10.0 ), 5, 10 )
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName { get { return "slime"; } }
|
||||
|
||||
[Constructable]
|
||||
public AcidSlime( TimeSpan duration, int minDamage, int maxDamage )
|
||||
: base( 0x122A )
|
||||
{
|
||||
Hue = 0x3F;
|
||||
Movable = false;
|
||||
m_MinDamage = minDamage;
|
||||
m_MaxDamage = maxDamage;
|
||||
m_Created = DateTime.Now;
|
||||
m_Duration = duration;
|
||||
m_Timer = Timer.DelayCall( TimeSpan.Zero, TimeSpan.FromSeconds( 1 ), new TimerCallback( OnTick ) );
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
if( m_Timer != null )
|
||||
m_Timer.Stop();
|
||||
}
|
||||
|
||||
private void OnTick()
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
TimeSpan age = now - m_Created;
|
||||
|
||||
if( age > m_Duration ) {
|
||||
Delete();
|
||||
} else {
|
||||
if( !m_Drying && age > (m_Duration - age) )
|
||||
{
|
||||
m_Drying = true;
|
||||
ItemID = 0x122B;
|
||||
}
|
||||
|
||||
List<Mobile> toDamage = new List<Mobile>();
|
||||
|
||||
foreach( Mobile m in GetMobilesInRange( 0 ) )
|
||||
{
|
||||
BaseCreature bc = m as BaseCreature;
|
||||
if( m.Alive && !m.IsDeadBondedPet && (bc == null || bc.Controlled || bc.Summoned) )
|
||||
{
|
||||
toDamage.Add( m );
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < toDamage.Count; i++ )
|
||||
Damage( toDamage[i] );
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnMoveOver( Mobile m )
|
||||
{
|
||||
Damage( m );
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Damage ( Mobile m )
|
||||
{
|
||||
int damage = Utility.RandomMinMax( m_MinDamage, m_MaxDamage );
|
||||
m.Damage( damage );
|
||||
}
|
||||
|
||||
public AcidSlime( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
228
Scripts/Items/Misc/ArcaneGem.cs
Normal file
228
Scripts/Items/Misc/ArcaneGem.cs
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Misc;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ArcaneGem : Item
|
||||
{
|
||||
public override string DefaultName
|
||||
{
|
||||
get { return "arcane gem"; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public ArcaneGem() : base( 0x1EA7 )
|
||||
{
|
||||
Stackable = false;
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public ArcaneGem( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( !IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.BeginTarget( 2, false, TargetFlags.None, new TargetCallback( OnTarget ) );
|
||||
from.SendMessage( "What do you wish to use the gem on?" );
|
||||
}
|
||||
}
|
||||
|
||||
public int GetChargesFor( Mobile m )
|
||||
{
|
||||
int v = (int)(Server.Misc.SkillCheck.TradeSkill( m, Trades.Tailoring, false ) / 5);
|
||||
|
||||
if ( v < 16 )
|
||||
return 16;
|
||||
else if ( v > 24 )
|
||||
return 24;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
public const int DefaultArcaneHue = 2117;
|
||||
|
||||
public void OnTarget( Mobile from, object obj )
|
||||
{
|
||||
if ( !IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if ( obj is IArcaneEquip && obj is Item )
|
||||
{
|
||||
Item item = (Item)obj;
|
||||
CraftResource resource = CraftResource.None;
|
||||
|
||||
if( item is BaseClothing )
|
||||
resource = ((BaseClothing)item).Resource;
|
||||
else if( item is BaseArmor )
|
||||
resource = ((BaseArmor)item).Resource;
|
||||
else if( item is BaseWeapon ) // Sanity, weapons cannot recieve gems...
|
||||
resource = ((BaseWeapon)item).Resource;
|
||||
|
||||
IArcaneEquip eq = (IArcaneEquip)obj;
|
||||
|
||||
if ( !item.IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
|
||||
return;
|
||||
}
|
||||
else if ( resource != CraftResource.None && resource != CraftResource.Leathered )
|
||||
{
|
||||
from.SendLocalizedMessage( 1049690 ); // Arcane gems can not be used on that type of leather.
|
||||
return;
|
||||
}
|
||||
|
||||
int charges = GetChargesFor( from );
|
||||
|
||||
if ( eq.IsArcane )
|
||||
{
|
||||
if ( eq.CurArcaneCharges >= eq.MaxArcaneCharges )
|
||||
{
|
||||
from.SendMessage( "That item is already fully charged." );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( eq.CurArcaneCharges <= 0 )
|
||||
item.Hue = DefaultArcaneHue;
|
||||
|
||||
if ( (eq.CurArcaneCharges + charges) > eq.MaxArcaneCharges )
|
||||
eq.CurArcaneCharges = eq.MaxArcaneCharges;
|
||||
else
|
||||
eq.CurArcaneCharges += charges;
|
||||
|
||||
from.SendMessage( "You recharge the item." );
|
||||
if ( Amount <= 1 )
|
||||
Delete();
|
||||
else Amount--;
|
||||
}
|
||||
}
|
||||
else if ( Server.Misc.SkillCheck.TradeSkill( from, Trades.Tailoring, false ) >= 80.0 )
|
||||
{
|
||||
bool isExceptional = false;
|
||||
|
||||
if ( item is BaseClothing )
|
||||
isExceptional = ( ((BaseClothing)item).Quality == ClothingQuality.Exceptional );
|
||||
else if ( item is BaseArmor )
|
||||
isExceptional = ( ((BaseArmor)item).Quality == ArmorQuality.Exceptional );
|
||||
else if ( item is BaseWeapon )
|
||||
isExceptional = ( ((BaseWeapon)item).Quality == WeaponQuality.Exceptional );
|
||||
|
||||
if ( isExceptional )
|
||||
{
|
||||
if ( item is BaseClothing )
|
||||
{
|
||||
((BaseClothing)item).Quality = ClothingQuality.Regular;
|
||||
((BaseClothing)item).Crafter = from;
|
||||
}
|
||||
else if ( item is BaseArmor )
|
||||
{
|
||||
((BaseArmor)item).Quality = ArmorQuality.Regular;
|
||||
((BaseArmor)item).Crafter = from;
|
||||
}
|
||||
else if ( item is BaseWeapon ) // Sanity, weapons cannot recieve gems...
|
||||
{
|
||||
((BaseWeapon)item).Quality = WeaponQuality.Regular;
|
||||
((BaseWeapon)item).Crafter = from;
|
||||
}
|
||||
|
||||
eq.CurArcaneCharges = eq.MaxArcaneCharges = charges;
|
||||
|
||||
item.Hue = DefaultArcaneHue;
|
||||
|
||||
from.SendMessage( "You enhance the item with your gem." );
|
||||
if ( Amount <= 1 )
|
||||
Delete();
|
||||
else Amount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( "Only exceptional items can be enhanced with the gem." );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( "You do not have enough skill in tailoring to enhance the item." );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendMessage( "You can only use this on exceptionally crafted robes, thigh boots, cloaks, or leather gloves." );
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ConsumeCharges( Mobile from, int amount )
|
||||
{
|
||||
List<Item> items = from.Items;
|
||||
int avail = 0;
|
||||
|
||||
for ( int i = 0; i < items.Count; ++i )
|
||||
{
|
||||
Item obj = items[i];
|
||||
|
||||
if ( obj is IArcaneEquip )
|
||||
{
|
||||
IArcaneEquip eq = (IArcaneEquip)obj;
|
||||
|
||||
if ( eq.IsArcane )
|
||||
avail += eq.CurArcaneCharges;
|
||||
}
|
||||
}
|
||||
|
||||
if ( avail < amount )
|
||||
return false;
|
||||
|
||||
for ( int i = 0; i < items.Count; ++i )
|
||||
{
|
||||
Item obj = items[i];
|
||||
|
||||
if ( obj is IArcaneEquip )
|
||||
{
|
||||
IArcaneEquip eq = (IArcaneEquip)obj;
|
||||
|
||||
if ( eq.IsArcane )
|
||||
{
|
||||
if ( eq.CurArcaneCharges > amount )
|
||||
{
|
||||
eq.CurArcaneCharges -= amount;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
amount -= eq.CurArcaneCharges;
|
||||
eq.CurArcaneCharges = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
40
Scripts/Items/Misc/Beeswax.cs
Normal file
40
Scripts/Items/Misc/Beeswax.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
106
Scripts/Items/Misc/Blocker.cs
Normal file
106
Scripts/Items/Misc/Blocker.cs
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Blocker : Item
|
||||
{
|
||||
public override int LabelNumber{ get{ return 503057; } } // Impassable!
|
||||
|
||||
[Constructable]
|
||||
public Blocker() : base( 0x21A4 )
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public Blocker( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
protected override Packet GetWorldPacketFor( NetState state ) {
|
||||
Mobile mob = state.Mobile;
|
||||
|
||||
if ( mob != null && mob.AccessLevel >= AccessLevel.GameMaster )
|
||||
return new GMItemPacket( this );
|
||||
|
||||
return base.GetWorldPacketFor( state );
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public sealed class GMItemPacket : Packet
|
||||
{
|
||||
public GMItemPacket( Item item ) : base( 0x1A )
|
||||
{
|
||||
this.EnsureCapacity( 20 );
|
||||
|
||||
// 14 base length
|
||||
// +2 - Amount
|
||||
// +2 - Hue
|
||||
// +1 - Flags
|
||||
|
||||
uint serial = (uint)item.Serial.Value;
|
||||
int itemID = 0x1183;
|
||||
int amount = item.Amount;
|
||||
Point3D loc = item.Location;
|
||||
int x = loc.X;
|
||||
int y = loc.Y;
|
||||
int hue = item.Hue;
|
||||
int flags = item.GetPacketFlags();
|
||||
int direction = (int)item.Direction;
|
||||
|
||||
if ( amount != 0 )
|
||||
serial |= 0x80000000;
|
||||
else
|
||||
serial &= 0x7FFFFFFF;
|
||||
|
||||
m_Stream.Write( (uint) serial );
|
||||
m_Stream.Write( (short) (itemID & 0x7FFF) );
|
||||
|
||||
if ( amount != 0 )
|
||||
m_Stream.Write( (short) amount );
|
||||
|
||||
x &= 0x7FFF;
|
||||
|
||||
if ( direction != 0 )
|
||||
x |= 0x8000;
|
||||
|
||||
m_Stream.Write( (short) x );
|
||||
|
||||
y &= 0x3FFF;
|
||||
|
||||
if ( hue != 0 )
|
||||
y |= 0x8000;
|
||||
|
||||
if ( flags != 0 )
|
||||
y |= 0x4000;
|
||||
|
||||
m_Stream.Write( (short) y );
|
||||
|
||||
if ( direction != 0 )
|
||||
m_Stream.Write( (byte) direction );
|
||||
|
||||
m_Stream.Write( (sbyte) loc.Z );
|
||||
|
||||
if ( hue != 0 )
|
||||
m_Stream.Write( (ushort) hue );
|
||||
|
||||
if ( flags != 0 )
|
||||
m_Stream.Write( (byte) flags );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Scripts/Items/Misc/Blood.cs
Normal file
57
Scripts/Items/Misc/Blood.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Blood : Item
|
||||
{
|
||||
[Constructable]
|
||||
public Blood() : this( Utility.RandomList( 0x1645, 0x122A, 0x122B, 0x122C, 0x122D, 0x122E, 0x122F ))
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Blood( int itemID ) : base( itemID )
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
new InternalTimer( this ).Start();
|
||||
}
|
||||
|
||||
public Blood( Serial serial ) : base( serial )
|
||||
{
|
||||
new InternalTimer( this ).Start();
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Item m_Blood;
|
||||
|
||||
public InternalTimer( Item blood ) : base( TimeSpan.FromSeconds( 5.0 ) )
|
||||
{
|
||||
Priority = TimerPriority.OneSecond;
|
||||
|
||||
m_Blood = blood;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Blood.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
620
Scripts/Items/Misc/BulletinBoards.cs
Normal file
620
Scripts/Items/Misc/BulletinBoards.cs
Normal file
|
|
@ -0,0 +1,620 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Flipable( 0x1E5E, 0x1E5F )]
|
||||
public class BulletinBoard : BaseBulletinBoard
|
||||
{
|
||||
[Constructable]
|
||||
public BulletinBoard() : base( 0x1E5E )
|
||||
{
|
||||
}
|
||||
|
||||
public BulletinBoard( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BaseBulletinBoard : Item
|
||||
{
|
||||
private string m_BoardName;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string BoardName
|
||||
{
|
||||
get{ return m_BoardName; }
|
||||
set{ m_BoardName = value; }
|
||||
}
|
||||
|
||||
public BaseBulletinBoard( int itemID ) : base( itemID )
|
||||
{
|
||||
m_BoardName = "bulletin board";
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
// Threads will be removed six hours after the last post was made
|
||||
private static TimeSpan ThreadDeletionTime = TimeSpan.FromHours( 6.0 );
|
||||
|
||||
// A player may only create a thread once every two minutes
|
||||
private static TimeSpan ThreadCreateTime = TimeSpan.FromMinutes( 2.0 );
|
||||
|
||||
// A player may only reply once every thirty seconds
|
||||
private static TimeSpan ThreadReplyTime = TimeSpan.FromSeconds( 30.0 );
|
||||
|
||||
public static bool CheckTime( DateTime time, TimeSpan range )
|
||||
{
|
||||
return (time + range) < DateTime.Now;
|
||||
}
|
||||
|
||||
public static string FormatTS( TimeSpan ts )
|
||||
{
|
||||
int totalSeconds = (int)ts.TotalSeconds;
|
||||
int seconds = totalSeconds % 60;
|
||||
int minutes = totalSeconds / 60;
|
||||
|
||||
if ( minutes != 0 && seconds != 0 )
|
||||
return String.Format( "{0} minute{1} and {2} second{3}", minutes, minutes==1?"":"s", seconds, seconds==1?"":"s" );
|
||||
else if ( minutes != 0 )
|
||||
return String.Format( "{0} minute{1}", minutes, minutes==1?"":"s" );
|
||||
else
|
||||
return String.Format( "{0} second{1}", seconds, seconds==1?"":"s" );
|
||||
}
|
||||
|
||||
public virtual void Cleanup()
|
||||
{
|
||||
List<Item> items = this.Items;
|
||||
|
||||
for ( int i = items.Count - 1; i >= 0; --i )
|
||||
{
|
||||
if ( i >= items.Count )
|
||||
continue;
|
||||
|
||||
BulletinMessage msg = items[i] as BulletinMessage;
|
||||
|
||||
if ( msg == null )
|
||||
continue;
|
||||
|
||||
if ( msg.Thread == null && CheckTime( msg.LastPostTime, ThreadDeletionTime ) )
|
||||
{
|
||||
msg.Delete();
|
||||
RecurseDelete( msg ); // A root-level thread has expired
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RecurseDelete( BulletinMessage msg )
|
||||
{
|
||||
List<Item> found = new List<Item>();
|
||||
List<Item> items = this.Items;
|
||||
|
||||
for ( int i = items.Count - 1; i >= 0; --i )
|
||||
{
|
||||
if ( i >= items.Count )
|
||||
continue;
|
||||
|
||||
BulletinMessage check = items[i] as BulletinMessage;
|
||||
|
||||
if ( check == null )
|
||||
continue;
|
||||
|
||||
if ( check.Thread == msg )
|
||||
{
|
||||
check.Delete();
|
||||
found.Add( check );
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < found.Count; ++i )
|
||||
RecurseDelete( (BulletinMessage)found[i] );
|
||||
}
|
||||
|
||||
public virtual bool GetLastPostTime( Mobile poster, bool onlyCheckRoot, ref DateTime lastPostTime )
|
||||
{
|
||||
List<Item> items = this.Items;
|
||||
bool wasSet = false;
|
||||
|
||||
for ( int i = 0; i < items.Count; ++i )
|
||||
{
|
||||
BulletinMessage msg = items[i] as BulletinMessage;
|
||||
|
||||
if ( msg == null || msg.Poster != poster )
|
||||
continue;
|
||||
|
||||
if ( onlyCheckRoot && msg.Thread != null )
|
||||
continue;
|
||||
|
||||
if ( msg.Time > lastPostTime )
|
||||
{
|
||||
wasSet = true;
|
||||
lastPostTime = msg.Time;
|
||||
}
|
||||
}
|
||||
|
||||
return wasSet;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( CheckRange( from ) )
|
||||
{
|
||||
Cleanup();
|
||||
|
||||
NetState state = from.NetState;
|
||||
|
||||
state.Send( new BBDisplayBoard( this ) );
|
||||
if ( state.ContainerGridLines )
|
||||
state.Send( new ContainerContent6017( from, this ) );
|
||||
else
|
||||
state.Send( new ContainerContent( from, this ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool CheckRange( Mobile from )
|
||||
{
|
||||
if ( from.AccessLevel >= AccessLevel.GameMaster )
|
||||
return true;
|
||||
|
||||
return ( from.Map == this.Map && from.InRange( GetWorldLocation(), 2 ) );
|
||||
}
|
||||
|
||||
public void PostMessage( Mobile from, BulletinMessage thread, string subject, string[] lines )
|
||||
{
|
||||
if ( thread != null )
|
||||
thread.LastPostTime = DateTime.Now;
|
||||
|
||||
AddItem( new BulletinMessage( from, thread, subject, lines ) );
|
||||
}
|
||||
|
||||
public BaseBulletinBoard( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
|
||||
writer.Write( (string) m_BoardName );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_BoardName = reader.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
PacketHandlers.Register( 0x71, 0, true, new OnPacketReceive( BBClientRequest ) );
|
||||
}
|
||||
|
||||
public static void BBClientRequest( NetState state, PacketReader pvSrc )
|
||||
{
|
||||
Mobile from = state.Mobile;
|
||||
|
||||
int packetID = pvSrc.ReadByte();
|
||||
BaseBulletinBoard board = World.FindItem( pvSrc.ReadInt32() ) as BaseBulletinBoard;
|
||||
|
||||
if ( board == null || !board.CheckRange( from ) )
|
||||
return;
|
||||
|
||||
switch ( packetID )
|
||||
{
|
||||
case 3: BBRequestContent( from, board, pvSrc ); break;
|
||||
case 4: BBRequestHeader( from, board, pvSrc ); break;
|
||||
case 5: BBPostMessage( from, board, pvSrc ); break;
|
||||
case 6: BBRemoveMessage( from, board, pvSrc ); break;
|
||||
}
|
||||
}
|
||||
|
||||
public static void BBRequestContent( Mobile from, BaseBulletinBoard board, PacketReader pvSrc )
|
||||
{
|
||||
BulletinMessage msg = World.FindItem( pvSrc.ReadInt32() ) as BulletinMessage;
|
||||
|
||||
if ( msg == null || msg.Parent != board )
|
||||
return;
|
||||
|
||||
from.Send( new BBMessageContent( board, msg ) );
|
||||
}
|
||||
|
||||
public static void BBRequestHeader( Mobile from, BaseBulletinBoard board, PacketReader pvSrc )
|
||||
{
|
||||
BulletinMessage msg = World.FindItem( pvSrc.ReadInt32() ) as BulletinMessage;
|
||||
|
||||
if ( msg == null || msg.Parent != board )
|
||||
return;
|
||||
|
||||
from.Send( new BBMessageHeader( board, msg ) );
|
||||
}
|
||||
|
||||
public static void BBPostMessage( Mobile from, BaseBulletinBoard board, PacketReader pvSrc )
|
||||
{
|
||||
BulletinMessage thread = World.FindItem( pvSrc.ReadInt32() ) as BulletinMessage;
|
||||
|
||||
if ( thread != null && thread.Parent != board )
|
||||
thread = null;
|
||||
|
||||
int breakout = 0;
|
||||
|
||||
while ( thread != null && thread.Thread != null && breakout++ < 10 )
|
||||
thread = thread.Thread;
|
||||
|
||||
DateTime lastPostTime = DateTime.MinValue;
|
||||
|
||||
if ( board.GetLastPostTime( from, ( thread == null ), ref lastPostTime ) )
|
||||
{
|
||||
if ( !CheckTime( lastPostTime, (thread == null ? ThreadCreateTime : ThreadReplyTime) ) )
|
||||
{
|
||||
if ( thread == null )
|
||||
from.SendMessage( "You must wait {0} before creating a new thread.", FormatTS( ThreadCreateTime ) );
|
||||
else
|
||||
from.SendMessage( "You must wait {0} before replying to another thread.", FormatTS( ThreadReplyTime ) );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
string subject = pvSrc.ReadUTF8StringSafe( pvSrc.ReadByte() );
|
||||
|
||||
if ( subject.Length == 0 )
|
||||
return;
|
||||
|
||||
string[] lines = new string[pvSrc.ReadByte()];
|
||||
|
||||
if ( lines.Length == 0 )
|
||||
return;
|
||||
|
||||
for ( int i = 0; i < lines.Length; ++i )
|
||||
lines[i] = pvSrc.ReadUTF8StringSafe( pvSrc.ReadByte() );
|
||||
|
||||
board.PostMessage( from, thread, subject, lines );
|
||||
}
|
||||
|
||||
public static void BBRemoveMessage( Mobile from, BaseBulletinBoard board, PacketReader pvSrc )
|
||||
{
|
||||
BulletinMessage msg = World.FindItem( pvSrc.ReadInt32() ) as BulletinMessage;
|
||||
|
||||
if ( msg == null || msg.Parent != board )
|
||||
return;
|
||||
|
||||
if ( from.AccessLevel < AccessLevel.GameMaster && msg.Poster != from )
|
||||
return;
|
||||
|
||||
msg.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public struct BulletinEquip
|
||||
{
|
||||
public int itemID;
|
||||
public int hue;
|
||||
|
||||
public BulletinEquip( int itemID, int hue )
|
||||
{
|
||||
this.itemID = itemID;
|
||||
this.hue = hue;
|
||||
}
|
||||
}
|
||||
|
||||
public class BulletinMessage : Item
|
||||
{
|
||||
private Mobile m_Poster;
|
||||
private string m_Subject;
|
||||
private DateTime m_Time, m_LastPostTime;
|
||||
private BulletinMessage m_Thread;
|
||||
private string m_PostedName;
|
||||
private int m_PostedBody;
|
||||
private int m_PostedHue;
|
||||
private BulletinEquip[] m_PostedEquip;
|
||||
private string[] m_Lines;
|
||||
|
||||
public string GetTimeAsString()
|
||||
{
|
||||
return m_Time.ToString( "MMM dd, yyyy" );
|
||||
}
|
||||
|
||||
public override bool CheckTarget( Mobile from, Server.Targeting.Target targ, object targeted )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool IsAccessibleTo( Mobile check )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public BulletinMessage( Mobile poster, BulletinMessage thread, string subject, string[] lines ) : base( 0xEB0 )
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
m_Poster = poster;
|
||||
m_Subject = subject;
|
||||
m_Time = DateTime.Now;
|
||||
m_LastPostTime = m_Time;
|
||||
m_Thread = thread;
|
||||
m_PostedName = m_Poster.Name;
|
||||
m_PostedBody = m_Poster.Body;
|
||||
m_PostedHue = m_Poster.Hue;
|
||||
m_Lines = lines;
|
||||
|
||||
List<BulletinEquip> list = new List<BulletinEquip>();
|
||||
|
||||
for ( int i = 0; i < poster.Items.Count; ++i )
|
||||
{
|
||||
Item item = poster.Items[i];
|
||||
|
||||
if ( item.Layer >= Layer.OneHanded && item.Layer <= Layer.Mount )
|
||||
list.Add( new BulletinEquip( item.ItemID, item.Hue ) );
|
||||
}
|
||||
|
||||
m_PostedEquip = list.ToArray();
|
||||
}
|
||||
|
||||
public Mobile Poster{ get{ return m_Poster; } }
|
||||
public BulletinMessage Thread{ get{ return m_Thread; } }
|
||||
public string Subject{ get{ return m_Subject; } }
|
||||
public DateTime Time{ get{ return m_Time; } }
|
||||
public DateTime LastPostTime{ get{ return m_LastPostTime; } set{ m_LastPostTime = value; } }
|
||||
public string PostedName{ get{ return m_PostedName; } }
|
||||
public int PostedBody{ get{ return m_PostedBody; } }
|
||||
public int PostedHue{ get{ return m_PostedHue; } }
|
||||
public BulletinEquip[] PostedEquip{ get{ return m_PostedEquip; } }
|
||||
public string[] Lines{ get{ return m_Lines; } }
|
||||
|
||||
public BulletinMessage( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
|
||||
writer.Write( (Mobile) m_Poster );
|
||||
writer.Write( (string) m_Subject );
|
||||
writer.Write( (DateTime) m_Time );
|
||||
writer.Write( (DateTime) m_LastPostTime );
|
||||
writer.Write( (bool) (m_Thread != null) );
|
||||
writer.Write( (Item) m_Thread );
|
||||
writer.Write( (string) m_PostedName );
|
||||
writer.Write( (int) m_PostedBody );
|
||||
writer.Write( (int) m_PostedHue );
|
||||
|
||||
writer.Write( (int) m_PostedEquip.Length );
|
||||
|
||||
for ( int i = 0; i < m_PostedEquip.Length; ++i )
|
||||
{
|
||||
writer.Write( (int) m_PostedEquip[i].itemID );
|
||||
writer.Write( (int) m_PostedEquip[i].hue );
|
||||
}
|
||||
|
||||
writer.Write( (int) m_Lines.Length );
|
||||
|
||||
for ( int i = 0; i < m_Lines.Length; ++i )
|
||||
writer.Write( (string) m_Lines[i] );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Poster = reader.ReadMobile();
|
||||
m_Subject = reader.ReadString();
|
||||
m_Time = reader.ReadDateTime();
|
||||
m_LastPostTime = reader.ReadDateTime();
|
||||
bool hasThread = reader.ReadBool();
|
||||
m_Thread = reader.ReadItem() as BulletinMessage;
|
||||
m_PostedName = reader.ReadString();
|
||||
m_PostedBody = reader.ReadInt();
|
||||
m_PostedHue = reader.ReadInt();
|
||||
|
||||
m_PostedEquip = new BulletinEquip[reader.ReadInt()];
|
||||
|
||||
for ( int i = 0; i < m_PostedEquip.Length; ++i )
|
||||
{
|
||||
m_PostedEquip[i].itemID = reader.ReadInt();
|
||||
m_PostedEquip[i].hue = reader.ReadInt();
|
||||
}
|
||||
|
||||
m_Lines = new string[reader.ReadInt()];
|
||||
|
||||
for ( int i = 0; i < m_Lines.Length; ++i )
|
||||
m_Lines[i] = reader.ReadString();
|
||||
|
||||
if ( hasThread && m_Thread == null )
|
||||
Delete();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BBDisplayBoard : Packet
|
||||
{
|
||||
public BBDisplayBoard( BaseBulletinBoard board ) : base( 0x71 )
|
||||
{
|
||||
string name = board.BoardName;
|
||||
|
||||
if ( name == null )
|
||||
name = "";
|
||||
|
||||
EnsureCapacity( 38 );
|
||||
|
||||
byte[] buffer = Utility.UTF8.GetBytes( name );
|
||||
|
||||
m_Stream.Write( (byte) 0x00 ); // PacketID
|
||||
m_Stream.Write( (int) board.Serial ); // Bulletin board serial
|
||||
|
||||
// Bulletin board name
|
||||
if ( buffer.Length >= 29 )
|
||||
{
|
||||
m_Stream.Write( buffer, 0, 29 );
|
||||
m_Stream.Write( (byte) 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Stream.Write( buffer, 0, buffer.Length );
|
||||
m_Stream.Fill( 30 - buffer.Length );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BBMessageHeader : Packet
|
||||
{
|
||||
public BBMessageHeader( BaseBulletinBoard board, BulletinMessage msg ) : base( 0x71 )
|
||||
{
|
||||
string poster = SafeString( msg.PostedName );
|
||||
string subject = SafeString( msg.Subject );
|
||||
string time = SafeString( msg.GetTimeAsString() );
|
||||
|
||||
EnsureCapacity( 22 + poster.Length + subject.Length + time.Length );
|
||||
|
||||
m_Stream.Write( (byte) 0x01 ); // PacketID
|
||||
m_Stream.Write( (int) board.Serial ); // Bulletin board serial
|
||||
m_Stream.Write( (int) msg.Serial ); // Message serial
|
||||
|
||||
BulletinMessage thread = msg.Thread;
|
||||
|
||||
if ( thread == null )
|
||||
m_Stream.Write( (int) 0 ); // Thread serial--root
|
||||
else
|
||||
m_Stream.Write( (int) thread.Serial ); // Thread serial--parent
|
||||
|
||||
WriteString( poster );
|
||||
WriteString( subject );
|
||||
WriteString( time );
|
||||
}
|
||||
|
||||
public void WriteString( string v )
|
||||
{
|
||||
byte[] buffer = Utility.UTF8.GetBytes( v );
|
||||
int len = buffer.Length + 1;
|
||||
|
||||
if ( len > 255 )
|
||||
len = 255;
|
||||
|
||||
m_Stream.Write( (byte) len );
|
||||
m_Stream.Write( buffer, 0, len-1 );
|
||||
m_Stream.Write( (byte) 0 );
|
||||
}
|
||||
|
||||
public string SafeString( string v )
|
||||
{
|
||||
if ( v == null )
|
||||
return String.Empty;
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
public class BBMessageContent : Packet
|
||||
{
|
||||
public BBMessageContent( BaseBulletinBoard board, BulletinMessage msg ) : base( 0x71 )
|
||||
{
|
||||
string poster = SafeString( msg.PostedName );
|
||||
string subject = SafeString( msg.Subject );
|
||||
string time = SafeString( msg.GetTimeAsString() );
|
||||
|
||||
EnsureCapacity( 22 + poster.Length + subject.Length + time.Length );
|
||||
|
||||
m_Stream.Write( (byte) 0x02 ); // PacketID
|
||||
m_Stream.Write( (int) board.Serial ); // Bulletin board serial
|
||||
m_Stream.Write( (int) msg.Serial ); // Message serial
|
||||
|
||||
WriteString( poster );
|
||||
WriteString( subject );
|
||||
WriteString( time );
|
||||
|
||||
m_Stream.Write( (short) msg.PostedBody );
|
||||
m_Stream.Write( (short) msg.PostedHue );
|
||||
|
||||
int len = msg.PostedEquip.Length;
|
||||
|
||||
if ( len > 255 )
|
||||
len = 255;
|
||||
|
||||
m_Stream.Write( (byte) len );
|
||||
|
||||
for ( int i = 0; i < len; ++i )
|
||||
{
|
||||
BulletinEquip eq = msg.PostedEquip[i];
|
||||
|
||||
m_Stream.Write( (short) eq.itemID );
|
||||
m_Stream.Write( (short) eq.hue );
|
||||
}
|
||||
|
||||
len = msg.Lines.Length;
|
||||
|
||||
if ( len > 255 )
|
||||
len = 255;
|
||||
|
||||
m_Stream.Write( (byte) len );
|
||||
|
||||
for ( int i = 0; i < len; ++i )
|
||||
WriteString( msg.Lines[i] );
|
||||
}
|
||||
|
||||
public void WriteString( string v )
|
||||
{
|
||||
byte[] buffer = Utility.UTF8.GetBytes( v );
|
||||
int len = buffer.Length + 1;
|
||||
|
||||
if ( len > 255 )
|
||||
len = 255;
|
||||
|
||||
m_Stream.Write( (byte) len );
|
||||
m_Stream.Write( buffer, 0, len-1 );
|
||||
m_Stream.Write( (byte) 0 );
|
||||
}
|
||||
|
||||
public string SafeString( string v )
|
||||
{
|
||||
if ( v == null )
|
||||
return String.Empty;
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
}
|
||||
904
Scripts/Items/Misc/Corpses/Corpse.cs
Normal file
904
Scripts/Items/Misc/Corpses/Corpse.cs
Normal file
|
|
@ -0,0 +1,904 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.PartySystem;
|
||||
using Server.Guilds;
|
||||
using Server.Misc;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public interface IDevourer
|
||||
{
|
||||
bool Devour( Corpse corpse );
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum CorpseFlag
|
||||
{
|
||||
None = 0x00000000,
|
||||
|
||||
/// <summary>
|
||||
/// Has this corpse been carved?
|
||||
/// </summary>
|
||||
Carved = 0x00000001,
|
||||
|
||||
/// <summary>
|
||||
/// If true, this corpse will not turn into bones
|
||||
/// </summary>
|
||||
NoBones = 0x00000002,
|
||||
|
||||
/// <summary>
|
||||
/// If true, the corpse has turned into bones
|
||||
/// </summary>
|
||||
IsBones = 0x00000004,
|
||||
|
||||
/// <summary>
|
||||
/// Has this corpse yet been visited by a taxidermist?
|
||||
/// </summary>
|
||||
VisitedByTaxidermist = 0x00000008,
|
||||
|
||||
/// <summary>
|
||||
/// Was the owner criminal when he died?
|
||||
/// </summary>
|
||||
Criminal = 0x00000010,
|
||||
|
||||
/// <summary>
|
||||
/// Has this corpse been animated?
|
||||
/// </summary>
|
||||
Animated = 0x00000020,
|
||||
}
|
||||
|
||||
public class Corpse : Container, ICarvable
|
||||
{
|
||||
private Mobile m_Owner; // Whos corpse is this?
|
||||
private Mobile m_Killer; // Who killed the owner?
|
||||
private CorpseFlag m_Flags; // @see CorpseFlag
|
||||
|
||||
private List<Mobile> m_Looters; // Who's looted this corpse?
|
||||
private List<Item> m_EquipItems; // List of items equiped when the owner died. Ingame, these items display /on/ the corpse, not just inside
|
||||
private List<Mobile> m_Aggressors; // Anyone from this list will be able to loot this corpse; we attacked them, or they attacked us when we were freely attackable
|
||||
|
||||
private string m_CorpseName; // Value of the CorpseNameAttribute attached to the owner when he died -or- null if the owner had no CorpseNameAttribute; use "the remains of ~name~"
|
||||
private IDevourer m_Devourer; // The creature that devoured this corpse
|
||||
|
||||
// For notoriety:
|
||||
private AccessLevel m_AccessLevel; // Which AccessLevel the owner had when he died
|
||||
private Guild m_Guild; // Which Guild the owner was in when he died
|
||||
private int m_Kills; // How many kills the owner had when he died
|
||||
|
||||
private DateTime m_TimeOfDeath; // What time was this corpse created?
|
||||
|
||||
private HairInfo m_Hair; // This contains the hair of the owner
|
||||
private FacialHairInfo m_FacialHair; // This contains the facial hair of the owner
|
||||
|
||||
public static readonly TimeSpan MonsterLootRightSacrifice = TimeSpan.FromMinutes( 2.0 );
|
||||
|
||||
public override bool IsChildVisibleTo( Mobile m, Item child )
|
||||
{
|
||||
if ( !m.Player || m.AccessLevel > AccessLevel.Player ) //Staff and creatures not subject to instancing.
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool IsDecoContainer
|
||||
{
|
||||
get{ return false; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public DateTime TimeOfDeath
|
||||
{
|
||||
get{ return m_TimeOfDeath; }
|
||||
set{ m_TimeOfDeath = value; }
|
||||
}
|
||||
|
||||
public override bool DisplayWeight { get { return false; } }
|
||||
|
||||
public HairInfo Hair { get { return m_Hair; } }
|
||||
public FacialHairInfo FacialHair { get { return m_FacialHair; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool IsBones
|
||||
{
|
||||
get { return GetFlag( CorpseFlag.IsBones ); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool Devoured
|
||||
{
|
||||
get { return (m_Devourer != null); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool Carved
|
||||
{
|
||||
get{ return GetFlag( CorpseFlag.Carved ); }
|
||||
set { SetFlag( CorpseFlag.Carved, value ); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool VisitedByTaxidermist
|
||||
{
|
||||
get { return GetFlag( CorpseFlag.VisitedByTaxidermist ); }
|
||||
set { SetFlag( CorpseFlag.VisitedByTaxidermist, value ); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool Animated
|
||||
{
|
||||
get { return GetFlag( CorpseFlag.Animated ); }
|
||||
set { SetFlag( CorpseFlag.Animated, value ); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public AccessLevel AccessLevel
|
||||
{
|
||||
get{ return m_AccessLevel; }
|
||||
}
|
||||
|
||||
public List<Mobile> Aggressors
|
||||
{
|
||||
get{ return m_Aggressors; }
|
||||
}
|
||||
|
||||
public List<Mobile> Looters
|
||||
{
|
||||
get{ return m_Looters; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Mobile Killer
|
||||
{
|
||||
get{ return m_Killer; }
|
||||
}
|
||||
|
||||
public List<Item> EquipItems
|
||||
{
|
||||
get{ return m_EquipItems; }
|
||||
}
|
||||
|
||||
public Guild Guild
|
||||
{
|
||||
get{ return m_Guild; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Kills
|
||||
{
|
||||
get{ return m_Kills; }
|
||||
set{ m_Kills = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool Criminal
|
||||
{
|
||||
get { return GetFlag( CorpseFlag.Criminal ); }
|
||||
set { SetFlag( CorpseFlag.Criminal, value ); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Mobile Owner
|
||||
{
|
||||
get{ return m_Owner; }
|
||||
}
|
||||
|
||||
public void TurnToBones()
|
||||
{
|
||||
if ( Deleted )
|
||||
return;
|
||||
|
||||
ProcessDelta();
|
||||
SendRemovePacket();
|
||||
ItemID = Utility.Random( 0xECA, 9 ); // bone graphic
|
||||
Hue = 0;
|
||||
ProcessDelta();
|
||||
|
||||
SetFlag( CorpseFlag.NoBones, true );
|
||||
SetFlag( CorpseFlag.IsBones, true );
|
||||
|
||||
BeginDecay( m_BoneDecayTime );
|
||||
}
|
||||
|
||||
private static TimeSpan m_DefaultDecayTime = TimeSpan.FromMinutes( 7.0 );
|
||||
private static TimeSpan m_BoneDecayTime = TimeSpan.FromMinutes( 7.0 );
|
||||
|
||||
private Timer m_DecayTimer;
|
||||
private DateTime m_DecayTime;
|
||||
|
||||
public void BeginDecay( TimeSpan delay )
|
||||
{
|
||||
if ( m_DecayTimer != null )
|
||||
m_DecayTimer.Stop();
|
||||
|
||||
m_DecayTime = DateTime.Now + delay;
|
||||
|
||||
m_DecayTimer = new InternalTimer( this, delay );
|
||||
m_DecayTimer.Start();
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
if ( m_DecayTimer != null )
|
||||
m_DecayTimer.Stop();
|
||||
|
||||
m_DecayTimer = null;
|
||||
}
|
||||
|
||||
private class InternalTimer : Timer
|
||||
{
|
||||
private Corpse m_Corpse;
|
||||
|
||||
public InternalTimer( Corpse c, TimeSpan delay ) : base( delay )
|
||||
{
|
||||
m_Corpse = c;
|
||||
Priority = TimerPriority.FiveSeconds;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
if ( !m_Corpse.GetFlag( CorpseFlag.NoBones ) )
|
||||
m_Corpse.TurnToBones();
|
||||
else
|
||||
m_Corpse.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetCorpseName( Mobile m )
|
||||
{
|
||||
Type t = m.GetType();
|
||||
|
||||
object[] attrs = t.GetCustomAttributes( typeof( CorpseNameAttribute ), true );
|
||||
|
||||
if ( attrs != null && attrs.Length > 0 )
|
||||
{
|
||||
CorpseNameAttribute attr = attrs[0] as CorpseNameAttribute;
|
||||
|
||||
if ( attr != null )
|
||||
return attr.Name;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
Mobile.CreateCorpseHandler += new CreateCorpseHandler( Mobile_CreateCorpseHandler );
|
||||
}
|
||||
|
||||
public static Container Mobile_CreateCorpseHandler( Mobile owner, HairInfo hair, FacialHairInfo facialhair, List<Item> initialContent, List<Item> equipItems )
|
||||
{
|
||||
bool shouldFillCorpse = true;
|
||||
|
||||
//if ( owner is BaseCreature )
|
||||
// shouldFillCorpse = !((BaseCreature)owner).IsBonded;
|
||||
|
||||
Corpse c = new Corpse( owner, hair, facialhair, shouldFillCorpse ? equipItems : new List<Item>() );
|
||||
|
||||
owner.Corpse = c;
|
||||
|
||||
if ( shouldFillCorpse )
|
||||
{
|
||||
for ( int i = 0; i < initialContent.Count; ++i )
|
||||
{
|
||||
Item item = initialContent[i];
|
||||
|
||||
c.DropItem( item );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c.Carved = true; // TODO: Is it needed?
|
||||
}
|
||||
|
||||
Point3D loc = owner.Location;
|
||||
Map map = owner.Map;
|
||||
|
||||
if ( map == null || map == Map.Internal )
|
||||
{
|
||||
loc = owner.LogoutLocation;
|
||||
map = owner.LogoutMap;
|
||||
}
|
||||
|
||||
c.MoveToWorld( loc, map );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
public override bool IsPublicContainer{ get{ return true; } }
|
||||
|
||||
public Corpse( Mobile owner, List<Item> equipItems ) : this( owner, null, null, equipItems )
|
||||
{
|
||||
}
|
||||
|
||||
public Corpse( Mobile owner, HairInfo hair, FacialHairInfo facialhair, List<Item> equipItems )
|
||||
: base( 0x2006 )
|
||||
{
|
||||
// To supress console warnings, stackable must be true
|
||||
Stackable = true;
|
||||
Amount = owner.Body; // protocol defines that for itemid 0x2006, amount=body
|
||||
Stackable = false;
|
||||
|
||||
Movable = false;
|
||||
Hue = owner.Hue;
|
||||
Direction = owner.Direction;
|
||||
Name = owner.Name;
|
||||
|
||||
m_Owner = owner;
|
||||
|
||||
m_CorpseName = GetCorpseName( owner );
|
||||
|
||||
m_TimeOfDeath = DateTime.Now;
|
||||
|
||||
m_AccessLevel = owner.AccessLevel;
|
||||
m_Guild = owner.Guild as Guild;
|
||||
m_Kills = owner.Kills;
|
||||
SetFlag( CorpseFlag.Criminal, owner.Criminal );
|
||||
|
||||
m_Hair = hair;
|
||||
m_FacialHair = facialhair;
|
||||
|
||||
|
||||
// This corpse does not turn to bones if: the owner is not a player
|
||||
SetFlag( CorpseFlag.NoBones, !owner.Player );
|
||||
|
||||
m_Looters = new List<Mobile>();
|
||||
m_EquipItems = equipItems;
|
||||
|
||||
m_Aggressors = new List<Mobile>( owner.Aggressors.Count + owner.Aggressed.Count );
|
||||
//bool addToAggressors = !( owner is BaseCreature );
|
||||
|
||||
bool isBaseCreature = (owner is BaseCreature);
|
||||
|
||||
TimeSpan lastTime = TimeSpan.MaxValue;
|
||||
|
||||
for ( int i = 0; i < owner.Aggressors.Count; ++i )
|
||||
{
|
||||
AggressorInfo info = owner.Aggressors[i];
|
||||
|
||||
if ( (DateTime.Now - info.LastCombatTime) < lastTime )
|
||||
{
|
||||
m_Killer = info.Attacker;
|
||||
lastTime = (DateTime.Now - info.LastCombatTime);
|
||||
}
|
||||
|
||||
if ( !isBaseCreature && !info.CriminalAggression )
|
||||
m_Aggressors.Add( info.Attacker );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < owner.Aggressed.Count; ++i )
|
||||
{
|
||||
AggressorInfo info = owner.Aggressed[i];
|
||||
|
||||
if ( (DateTime.Now - info.LastCombatTime) < lastTime )
|
||||
{
|
||||
m_Killer = info.Defender;
|
||||
lastTime = (DateTime.Now - info.LastCombatTime);
|
||||
}
|
||||
|
||||
if ( !isBaseCreature )
|
||||
m_Aggressors.Add( info.Defender );
|
||||
}
|
||||
|
||||
if ( isBaseCreature )
|
||||
{
|
||||
BaseCreature bc = (BaseCreature)owner;
|
||||
|
||||
Mobile master = bc.GetMaster();
|
||||
if( master != null )
|
||||
m_Aggressors.Add( master );
|
||||
|
||||
List<DamageStore> rights = BaseCreature.GetLootingRights( bc.DamageEntries, bc.HitsMax );
|
||||
for ( int i = 0; i < rights.Count; ++i )
|
||||
{
|
||||
DamageStore ds = rights[i];
|
||||
|
||||
if ( ds.m_HasRight )
|
||||
m_Aggressors.Add( ds.m_Mobile );
|
||||
}
|
||||
}
|
||||
|
||||
BeginDecay( m_DefaultDecayTime );
|
||||
|
||||
DevourCorpse();
|
||||
}
|
||||
|
||||
public Corpse( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
protected bool GetFlag( CorpseFlag flag )
|
||||
{
|
||||
return ((m_Flags & flag) != 0);
|
||||
}
|
||||
|
||||
protected void SetFlag( CorpseFlag flag, bool on )
|
||||
{
|
||||
m_Flags = (on ? m_Flags | flag : m_Flags & ~flag);
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 11 ); // version
|
||||
|
||||
writer.Write( (int)m_Flags );
|
||||
|
||||
writer.WriteDeltaTime( m_TimeOfDeath );
|
||||
|
||||
List<KeyValuePair<Item, Point3D>> list = ( m_RestoreTable == null ? null : new List<KeyValuePair<Item, Point3D>>( m_RestoreTable ) );
|
||||
int count = ( list == null ? 0 : list.Count );
|
||||
|
||||
writer.Write( count );
|
||||
|
||||
for ( int i = 0; i < count; ++i )
|
||||
{
|
||||
KeyValuePair<Item, Point3D> kvp = list[i];
|
||||
Item item = kvp.Key;
|
||||
Point3D loc = kvp.Value;
|
||||
|
||||
writer.Write( item );
|
||||
|
||||
if ( item.Location == loc )
|
||||
{
|
||||
writer.Write( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write( true );
|
||||
writer.Write( loc );
|
||||
}
|
||||
}
|
||||
|
||||
writer.Write( m_DecayTimer != null );
|
||||
|
||||
if ( m_DecayTimer != null )
|
||||
writer.WriteDeltaTime( m_DecayTime );
|
||||
|
||||
writer.Write( m_Looters );
|
||||
writer.Write( m_Killer );
|
||||
|
||||
writer.Write( m_Aggressors );
|
||||
|
||||
writer.Write( m_Owner );
|
||||
|
||||
writer.Write( (string) m_CorpseName );
|
||||
|
||||
writer.Write( (int) m_AccessLevel );
|
||||
writer.Write( (Guild) m_Guild );
|
||||
writer.Write( (int) m_Kills );
|
||||
|
||||
writer.Write( m_EquipItems );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 11:
|
||||
{
|
||||
// Version 11, we move all bools to a CorpseFlag
|
||||
m_Flags = (CorpseFlag)reader.ReadInt();
|
||||
|
||||
m_TimeOfDeath = reader.ReadDeltaTime();
|
||||
|
||||
int count = reader.ReadInt();
|
||||
|
||||
for( int i = 0; i < count; ++i )
|
||||
{
|
||||
Item item = reader.ReadItem();
|
||||
|
||||
if( reader.ReadBool() )
|
||||
SetRestoreInfo( item, reader.ReadPoint3D() );
|
||||
else if( item != null )
|
||||
SetRestoreInfo( item, item.Location );
|
||||
}
|
||||
|
||||
if( reader.ReadBool() )
|
||||
BeginDecay( reader.ReadDeltaTime() - DateTime.Now );
|
||||
|
||||
m_Looters = reader.ReadStrongMobileList();
|
||||
m_Killer = reader.ReadMobile();
|
||||
|
||||
m_Aggressors = reader.ReadStrongMobileList();
|
||||
m_Owner = reader.ReadMobile();
|
||||
|
||||
m_CorpseName = reader.ReadString();
|
||||
|
||||
m_AccessLevel = (AccessLevel)reader.ReadInt();
|
||||
reader.ReadInt(); // guild reserve
|
||||
m_Kills = reader.ReadInt();
|
||||
|
||||
m_EquipItems = reader.ReadStrongItemList();
|
||||
break;
|
||||
}
|
||||
case 10:
|
||||
{
|
||||
m_TimeOfDeath = reader.ReadDeltaTime();
|
||||
|
||||
goto case 9;
|
||||
}
|
||||
case 9:
|
||||
{
|
||||
int count = reader.ReadInt();
|
||||
|
||||
for ( int i = 0; i < count; ++i )
|
||||
{
|
||||
Item item = reader.ReadItem();
|
||||
|
||||
if ( reader.ReadBool() )
|
||||
SetRestoreInfo( item, reader.ReadPoint3D() );
|
||||
else if ( item != null )
|
||||
SetRestoreInfo( item, item.Location );
|
||||
}
|
||||
|
||||
goto case 8;
|
||||
}
|
||||
case 8:
|
||||
{
|
||||
SetFlag( CorpseFlag.VisitedByTaxidermist, reader.ReadBool() );
|
||||
|
||||
goto case 7;
|
||||
}
|
||||
case 7:
|
||||
{
|
||||
if ( reader.ReadBool() )
|
||||
BeginDecay( reader.ReadDeltaTime() - DateTime.Now );
|
||||
|
||||
goto case 6;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
m_Looters = reader.ReadStrongMobileList();
|
||||
m_Killer = reader.ReadMobile();
|
||||
|
||||
goto case 5;
|
||||
}
|
||||
case 5:
|
||||
{
|
||||
SetFlag( CorpseFlag.Carved, reader.ReadBool() );
|
||||
|
||||
goto case 4;
|
||||
}
|
||||
case 4:
|
||||
{
|
||||
m_Aggressors = reader.ReadStrongMobileList();
|
||||
|
||||
goto case 3;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
m_Owner = reader.ReadMobile();
|
||||
|
||||
goto case 2;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
SetFlag( CorpseFlag.NoBones, reader.ReadBool() );
|
||||
|
||||
goto case 1;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
m_CorpseName = reader.ReadString();
|
||||
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
if ( version < 10 )
|
||||
m_TimeOfDeath = DateTime.Now;
|
||||
|
||||
if ( version < 7 )
|
||||
BeginDecay( m_DefaultDecayTime );
|
||||
|
||||
if ( version < 6 )
|
||||
m_Looters = new List<Mobile>();
|
||||
|
||||
if ( version < 4 )
|
||||
m_Aggressors = new List<Mobile>();
|
||||
|
||||
m_AccessLevel = (AccessLevel)reader.ReadInt();
|
||||
reader.ReadInt(); // guild reserve
|
||||
m_Kills = reader.ReadInt();
|
||||
SetFlag( CorpseFlag.Criminal, reader.ReadBool() );
|
||||
|
||||
m_EquipItems = reader.ReadStrongItemList();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool DevourCorpse()
|
||||
{
|
||||
if( Devoured || Deleted || m_Killer == null || m_Killer.Deleted || !m_Killer.Alive || !(m_Killer is IDevourer) || m_Owner == null || m_Owner.Deleted )
|
||||
return false;
|
||||
|
||||
m_Devourer = (IDevourer)m_Killer; // Set the devourer the killer
|
||||
return m_Devourer.Devour( this ); // Devour the corpse if it hasn't
|
||||
}
|
||||
|
||||
public override void SendInfoTo( NetState state, bool sendOplPacket )
|
||||
{
|
||||
base.SendInfoTo( state, sendOplPacket );
|
||||
|
||||
if ( ItemID == 0x2006 )
|
||||
{
|
||||
state.Send( new CorpseContent( state.Mobile, this ) );
|
||||
state.Send( new CorpseEquip( state.Mobile, this ) );
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCriminalAction( Mobile from )
|
||||
{
|
||||
if ( from == m_Owner || from.AccessLevel >= AccessLevel.GameMaster )
|
||||
return false;
|
||||
|
||||
Party p = Party.Get( m_Owner );
|
||||
|
||||
if ( p != null && p.Contains( from ) )
|
||||
{
|
||||
PartyMemberInfo pmi = p[m_Owner];
|
||||
|
||||
if ( pmi != null && pmi.CanLoot )
|
||||
return false;
|
||||
}
|
||||
|
||||
return ( NotorietyHandlers.CorpseNotoriety( from, this ) == Notoriety.Innocent );
|
||||
}
|
||||
|
||||
public override bool CheckItemUse( Mobile from, Item item )
|
||||
{
|
||||
if ( !base.CheckItemUse( from, item ) )
|
||||
return false;
|
||||
|
||||
if ( item != this )
|
||||
return CanLoot( from, item );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool CheckLift( Mobile from, Item item, ref LRReason reject )
|
||||
{
|
||||
if ( !base.CheckLift( from, item, ref reject ) )
|
||||
return false;
|
||||
|
||||
return CanLoot( from,item );
|
||||
}
|
||||
|
||||
public override void OnItemUsed( Mobile from, Item item )
|
||||
{
|
||||
base.OnItemUsed( from, item );
|
||||
|
||||
if ( item is Food )
|
||||
from.RevealingAction();
|
||||
|
||||
if ( item != this && IsCriminalAction( from ) )
|
||||
from.CriminalAction( true );
|
||||
|
||||
if ( !m_Looters.Contains( from ) )
|
||||
m_Looters.Add( from );
|
||||
}
|
||||
|
||||
public override void OnItemLifted( Mobile from, Item item )
|
||||
{
|
||||
base.OnItemLifted( from, item );
|
||||
|
||||
if ( item != this && from != m_Owner )
|
||||
from.RevealingAction();
|
||||
|
||||
if ( item != this && IsCriminalAction( from ) )
|
||||
from.CriminalAction( true );
|
||||
|
||||
if ( !m_Looters.Contains( from ) )
|
||||
m_Looters.Add( from );
|
||||
}
|
||||
|
||||
private class OpenCorpseEntry : ContextMenuEntry
|
||||
{
|
||||
public OpenCorpseEntry() : base( 6215, 2 )
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
Corpse corpse = Owner.Target as Corpse;
|
||||
|
||||
if ( corpse != null && Owner.From.CheckAlive() )
|
||||
corpse.Open( Owner.From );
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
|
||||
{
|
||||
base.GetContextMenuEntries( from, list );
|
||||
}
|
||||
|
||||
private Dictionary<Item, Point3D> m_RestoreTable;
|
||||
|
||||
public bool GetRestoreInfo( Item item, ref Point3D loc )
|
||||
{
|
||||
if ( m_RestoreTable == null || item == null )
|
||||
return false;
|
||||
|
||||
return m_RestoreTable.TryGetValue( item, out loc );
|
||||
}
|
||||
|
||||
public void SetRestoreInfo( Item item, Point3D loc )
|
||||
{
|
||||
if ( item == null )
|
||||
return;
|
||||
|
||||
if ( m_RestoreTable == null )
|
||||
m_RestoreTable = new Dictionary<Item, Point3D>();
|
||||
|
||||
m_RestoreTable[item] = loc;
|
||||
}
|
||||
|
||||
public void ClearRestoreInfo( Item item )
|
||||
{
|
||||
if ( m_RestoreTable == null || item == null )
|
||||
return;
|
||||
|
||||
m_RestoreTable.Remove( item );
|
||||
|
||||
if ( m_RestoreTable.Count == 0 )
|
||||
m_RestoreTable = null;
|
||||
}
|
||||
|
||||
public bool CanLoot( Mobile from, Item item )
|
||||
{
|
||||
if ( !IsCriminalAction( from ) )
|
||||
return true;
|
||||
|
||||
Map map = this.Map;
|
||||
|
||||
if ( map == null || (map.Rules & MapRules.HarmfulRestrictions) != 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool CheckLoot( Mobile from, Item item )
|
||||
{
|
||||
if ( !CanLoot( from, item ) )
|
||||
{
|
||||
if ( m_Owner == null || !m_Owner.Player )
|
||||
from.SendLocalizedMessage( 1005035 ); // You did not earn the right to loot this creature!
|
||||
else
|
||||
from.SendLocalizedMessage( 1010049 ); // You may not loot this corpse.
|
||||
|
||||
return false;
|
||||
}
|
||||
else if ( IsCriminalAction( from ) )
|
||||
{
|
||||
if ( m_Owner == null || !m_Owner.Player )
|
||||
from.SendLocalizedMessage( 1005036 ); // Looting this monster corpse will be a criminal act!
|
||||
else
|
||||
from.SendLocalizedMessage( 1005038 ); // Looting this corpse will be a criminal act!
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public virtual void Open( Mobile from )
|
||||
{
|
||||
if ( from.AccessLevel > AccessLevel.Player || from.InRange( this.GetWorldLocation(), 2 ) )
|
||||
{
|
||||
if ( !CheckLoot( from, null ) )
|
||||
return;
|
||||
|
||||
base.OnDoubleClick( from );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 500446 ); // That is too far away.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
Open( from );
|
||||
}
|
||||
|
||||
public override bool CheckContentDisplay( Mobile from )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool DisplaysContent{ get{ return false; } }
|
||||
|
||||
public override void AddNameProperty( ObjectPropertyList list )
|
||||
{
|
||||
if ( ItemID == 0x2006 ) // Corpse form
|
||||
{
|
||||
if ( m_CorpseName != null )
|
||||
list.Add( m_CorpseName );
|
||||
else
|
||||
list.Add( 1046414, this.Name ); // the remains of ~1_NAME~
|
||||
}
|
||||
else // Bone form
|
||||
{
|
||||
list.Add( 1046414, this.Name ); // the remains of ~1_NAME~
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnSingleClick( Mobile from )
|
||||
{
|
||||
int hue = Notoriety.GetHue( NotorietyHandlers.CorpseNotoriety( from, this ) );
|
||||
|
||||
if ( ItemID == 0x2006 ) // Corpse form
|
||||
{
|
||||
if ( m_CorpseName != null )
|
||||
from.Send( new AsciiMessage( Serial, ItemID, MessageType.Label, hue, 3, "", m_CorpseName ) );
|
||||
else
|
||||
from.Send( new MessageLocalized( Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name ) );
|
||||
}
|
||||
else // Bone form
|
||||
{
|
||||
from.Send( new MessageLocalized( Serial, ItemID, MessageType.Label, hue, 3, 1046414, "", Name ) );
|
||||
}
|
||||
}
|
||||
|
||||
public void Carve( Mobile from, Item item )
|
||||
{
|
||||
if ( IsCriminalAction( from ) && this.Map != null && (this.Map.Rules & MapRules.HarmfulRestrictions) != 0 )
|
||||
{
|
||||
if ( m_Owner == null || !m_Owner.Player )
|
||||
from.SendLocalizedMessage( 1005035 ); // You did not earn the right to loot this creature!
|
||||
else
|
||||
from.SendLocalizedMessage( 1010049 ); // You may not loot this corpse.
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Mobile dead = m_Owner;
|
||||
|
||||
if ( GetFlag( CorpseFlag.Carved ) || dead == null )
|
||||
{
|
||||
from.SendLocalizedMessage( 500485 ); // You see nothing useful to carve from the corpse.
|
||||
}
|
||||
else if ( ((Body)Amount).IsHuman && ItemID == 0x2006 )
|
||||
{
|
||||
new Blood( 0x122D ).MoveToWorld( Location, Map );
|
||||
|
||||
new Torso().MoveToWorld( Location, Map );
|
||||
new LeftLeg().MoveToWorld( Location, Map );
|
||||
new LeftArm().MoveToWorld( Location, Map );
|
||||
new RightLeg().MoveToWorld( Location, Map );
|
||||
new RightArm().MoveToWorld( Location, Map );
|
||||
new Head( dead.Name ).MoveToWorld( Location, Map );
|
||||
|
||||
SetFlag( CorpseFlag.Carved, true );
|
||||
|
||||
ProcessDelta();
|
||||
SendRemovePacket();
|
||||
ItemID = Utility.Random( 0xECA, 9 ); // bone graphic
|
||||
Hue = 0;
|
||||
ProcessDelta();
|
||||
|
||||
if ( IsCriminalAction( from ) )
|
||||
from.CriminalAction( true );
|
||||
}
|
||||
else if ( dead is BaseCreature )
|
||||
{
|
||||
((BaseCreature)dead).OnCarve( from, this, item );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 500485 ); // You see nothing useful to carve from the corpse.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Scripts/Items/Misc/Corpses/CorpseNameAttribute.cs
Normal file
20
Scripts/Items/Misc/Corpses/CorpseNameAttribute.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
115
Scripts/Items/Misc/Corpses/DecayedCorpse.cs
Normal file
115
Scripts/Items/Misc/Corpses/DecayedCorpse.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
125
Scripts/Items/Misc/Corpses/Packets.cs
Normal file
125
Scripts/Items/Misc/Corpses/Packets.cs
Normal 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
339
Scripts/Items/Misc/EffectController.cs
Normal file
339
Scripts/Items/Misc/EffectController.cs
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum ECEffectType
|
||||
{
|
||||
None,
|
||||
Moving,
|
||||
Location,
|
||||
Target,
|
||||
Lightning
|
||||
}
|
||||
|
||||
public enum EffectTriggerType
|
||||
{
|
||||
None,
|
||||
Sequenced,
|
||||
DoubleClick,
|
||||
InRange
|
||||
}
|
||||
|
||||
public class EffectController : Item
|
||||
{
|
||||
private TimeSpan m_EffectDelay;
|
||||
|
||||
private ECEffectType m_EffectType;
|
||||
private EffectTriggerType m_TriggerType;
|
||||
|
||||
private IEntity m_Source;
|
||||
private IEntity m_Target;
|
||||
|
||||
private TimeSpan m_TriggerDelay;
|
||||
private EffectController m_Trigger;
|
||||
|
||||
private int m_ItemID;
|
||||
private int m_Hue;
|
||||
private int m_RenderMode;
|
||||
|
||||
private int m_Speed;
|
||||
private int m_Duration;
|
||||
|
||||
private bool m_FixedDirection;
|
||||
private bool m_Explodes;
|
||||
|
||||
private int m_ParticleEffect;
|
||||
private int m_ExplodeParticleEffect;
|
||||
private int m_ExplodeSound;
|
||||
|
||||
private EffectLayer m_EffectLayer;
|
||||
private int m_Unknown;
|
||||
|
||||
private TimeSpan m_SoundDelay;
|
||||
private int m_SoundID;
|
||||
private bool m_PlaySoundAtTrigger;
|
||||
|
||||
private int m_TriggerRange;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public ECEffectType EffectType{ get{ return m_EffectType; } set{ m_EffectType = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public EffectTriggerType TriggerType{ get{ return m_TriggerType; } set{ m_TriggerType = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public EffectLayer EffectLayer{ get{ return m_EffectLayer; } set{ m_EffectLayer = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan EffectDelay{ get{ return m_EffectDelay; } set{ m_EffectDelay = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan TriggerDelay{ get{ return m_TriggerDelay; } set{ m_TriggerDelay = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan SoundDelay{ get{ return m_SoundDelay; } set{ m_SoundDelay = value; } }
|
||||
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Item SourceItem{ get{ return m_Source as Item; } set{ m_Source = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Mobile SourceMobile{ get{ return m_Source as Mobile; } set{ m_Source = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool SourceNull{ get{ return ( m_Source == null ); } set{ if ( value ) m_Source = null; } }
|
||||
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Item TargetItem{ get{ return m_Target as Item; } set{ m_Target = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Mobile TargetMobile{ get{ return m_Target as Mobile; } set{ m_Target = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool TargetNull{ get{ return ( m_Target == null ); } set{ if ( value ) m_Target = null; } }
|
||||
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public EffectController Sequence{ get{ return m_Trigger; } set{ m_Trigger = value; } }
|
||||
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
private bool FixedDirection{ get{ return m_FixedDirection; } set{ m_FixedDirection = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
private bool Explodes{ get{ return m_Explodes; } set{ m_Explodes = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
private bool PlaySoundAtTrigger{ get{ return m_PlaySoundAtTrigger; } set{ m_PlaySoundAtTrigger = value; } }
|
||||
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int EffectItemID{ get{ return m_ItemID; } set{ m_ItemID = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int EffectHue{ get{ return m_Hue; } set{ m_Hue = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int RenderMode{ get{ return m_RenderMode; } set{ m_RenderMode = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Speed{ get{ return m_Speed; } set{ m_Speed = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Duration{ get{ return m_Duration; } set{ m_Duration = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int ParticleEffect{ get{ return m_ParticleEffect; } set{ m_ParticleEffect = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int ExplodeParticleEffect{ get{ return m_ExplodeParticleEffect; } set{ m_ExplodeParticleEffect = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int ExplodeSound{ get{ return m_ExplodeSound; } set{ m_ExplodeSound = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Unknown{ get{ return m_Unknown; } set{ m_Unknown = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int SoundID{ get{ return m_SoundID; } set{ m_SoundID = value; } }
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int TriggerRange{ get{ return m_TriggerRange; } set{ m_TriggerRange = value; } }
|
||||
|
||||
public override string DefaultName
|
||||
{
|
||||
get { return "Effect Controller"; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public EffectController() : base( 0x1B72 )
|
||||
{
|
||||
Movable = false;
|
||||
Visible = false;
|
||||
m_TriggerType = EffectTriggerType.Sequenced;
|
||||
m_EffectLayer = (EffectLayer)255;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( m_TriggerType == EffectTriggerType.DoubleClick )
|
||||
DoEffect( from );
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement{ get{ return ( m_TriggerType == EffectTriggerType.InRange ); } }
|
||||
|
||||
public override void OnMovement( Mobile m, Point3D oldLocation )
|
||||
{
|
||||
if ( m.Location != oldLocation && m_TriggerType == EffectTriggerType.InRange && Utility.InRange( GetWorldLocation(), m.Location, m_TriggerRange ) && !Utility.InRange( GetWorldLocation(), oldLocation, m_TriggerRange ) )
|
||||
DoEffect( m );
|
||||
}
|
||||
|
||||
public EffectController( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
|
||||
writer.Write( m_EffectDelay );
|
||||
writer.Write( m_TriggerDelay );
|
||||
writer.Write( m_SoundDelay );
|
||||
|
||||
if ( m_Source is Item )
|
||||
writer.Write( m_Source as Item );
|
||||
else
|
||||
writer.Write( m_Source as Mobile );
|
||||
|
||||
if ( m_Target is Item )
|
||||
writer.Write( m_Target as Item );
|
||||
else
|
||||
writer.Write( m_Target as Mobile );
|
||||
|
||||
writer.Write( m_Trigger as Item );
|
||||
|
||||
writer.Write( m_FixedDirection );
|
||||
writer.Write( m_Explodes );
|
||||
writer.Write( m_PlaySoundAtTrigger );
|
||||
|
||||
writer.WriteEncodedInt( (int) m_EffectType );
|
||||
writer.WriteEncodedInt( (int) m_EffectLayer );
|
||||
writer.WriteEncodedInt( (int) m_TriggerType );
|
||||
|
||||
writer.WriteEncodedInt( m_ItemID );
|
||||
writer.WriteEncodedInt( m_Hue );
|
||||
writer.WriteEncodedInt( m_RenderMode );
|
||||
writer.WriteEncodedInt( m_Speed );
|
||||
writer.WriteEncodedInt( m_Duration );
|
||||
writer.WriteEncodedInt( m_ParticleEffect );
|
||||
writer.WriteEncodedInt( m_ExplodeParticleEffect );
|
||||
writer.WriteEncodedInt( m_ExplodeSound );
|
||||
writer.WriteEncodedInt( m_Unknown );
|
||||
writer.WriteEncodedInt( m_SoundID );
|
||||
writer.WriteEncodedInt( m_TriggerRange );
|
||||
}
|
||||
|
||||
private IEntity ReadEntity( GenericReader reader )
|
||||
{
|
||||
return World.FindEntity( reader.ReadInt() );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_EffectDelay = reader.ReadTimeSpan();
|
||||
m_TriggerDelay = reader.ReadTimeSpan();
|
||||
m_SoundDelay = reader.ReadTimeSpan();
|
||||
|
||||
m_Source = ReadEntity( reader );
|
||||
m_Target = ReadEntity( reader );
|
||||
m_Trigger = reader.ReadItem() as EffectController;
|
||||
|
||||
m_FixedDirection = reader.ReadBool();
|
||||
m_Explodes = reader.ReadBool();
|
||||
m_PlaySoundAtTrigger = reader.ReadBool();
|
||||
|
||||
m_EffectType = (ECEffectType)reader.ReadEncodedInt();
|
||||
m_EffectLayer = (EffectLayer)reader.ReadEncodedInt();
|
||||
m_TriggerType = (EffectTriggerType)reader.ReadEncodedInt();
|
||||
|
||||
m_ItemID = reader.ReadEncodedInt();
|
||||
m_Hue = reader.ReadEncodedInt();
|
||||
m_RenderMode = reader.ReadEncodedInt();
|
||||
m_Speed = reader.ReadEncodedInt();
|
||||
m_Duration = reader.ReadEncodedInt();
|
||||
m_ParticleEffect = reader.ReadEncodedInt();
|
||||
m_ExplodeParticleEffect = reader.ReadEncodedInt();
|
||||
m_ExplodeSound = reader.ReadEncodedInt();
|
||||
m_Unknown = reader.ReadEncodedInt();
|
||||
m_SoundID = reader.ReadEncodedInt();
|
||||
m_TriggerRange = reader.ReadEncodedInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PlaySound( object trigger )
|
||||
{
|
||||
IEntity ent = null;
|
||||
|
||||
if ( m_PlaySoundAtTrigger )
|
||||
ent = trigger as IEntity;
|
||||
|
||||
if ( ent == null )
|
||||
ent = this;
|
||||
|
||||
Effects.PlaySound( (ent is Item) ? ((Item)ent).GetWorldLocation() : ent.Location, ent.Map, m_SoundID );
|
||||
}
|
||||
|
||||
public void DoEffect( object trigger )
|
||||
{
|
||||
if ( Deleted || m_TriggerType == EffectTriggerType.None )
|
||||
return;
|
||||
|
||||
if( trigger is Mobile && ((Mobile)trigger).Hidden && ((Mobile)trigger).AccessLevel > AccessLevel.Player )
|
||||
return;
|
||||
|
||||
if ( m_SoundID > 0 )
|
||||
Timer.DelayCall( m_SoundDelay, new TimerStateCallback( PlaySound ), trigger );
|
||||
|
||||
if ( m_Trigger != null )
|
||||
Timer.DelayCall( m_TriggerDelay, new TimerStateCallback( m_Trigger.DoEffect ), trigger );
|
||||
|
||||
if ( m_EffectType != ECEffectType.None )
|
||||
Timer.DelayCall( m_EffectDelay, new TimerStateCallback( InternalDoEffect ), trigger );
|
||||
}
|
||||
|
||||
public void InternalDoEffect( object trigger )
|
||||
{
|
||||
IEntity from = m_Source, to = m_Target;
|
||||
|
||||
if ( from == null )
|
||||
from = (IEntity)trigger;
|
||||
|
||||
if ( to == null )
|
||||
to = (IEntity)trigger;
|
||||
|
||||
switch ( m_EffectType )
|
||||
{
|
||||
case ECEffectType.Lightning:
|
||||
{
|
||||
Effects.SendBoltEffect( from, false, m_Hue );
|
||||
break;
|
||||
}
|
||||
case ECEffectType.Location:
|
||||
{
|
||||
Effects.SendLocationParticles( EffectItem.Create( from.Location, from.Map, EffectItem.DefaultDuration ), m_ItemID, m_Speed, m_Duration, m_Hue, m_RenderMode, m_ParticleEffect, m_Unknown );
|
||||
break;
|
||||
}
|
||||
case ECEffectType.Moving:
|
||||
{
|
||||
if ( from == this )
|
||||
from = EffectItem.Create( from.Location, from.Map, EffectItem.DefaultDuration );
|
||||
|
||||
if ( to == this )
|
||||
to = EffectItem.Create( to.Location, to.Map, EffectItem.DefaultDuration );
|
||||
|
||||
Effects.SendMovingParticles( from, to, m_ItemID, m_Speed, m_Duration, m_FixedDirection, m_Explodes, m_Hue, m_RenderMode, m_ParticleEffect, m_ExplodeParticleEffect, m_ExplodeSound, m_EffectLayer, m_Unknown );
|
||||
break;
|
||||
}
|
||||
case ECEffectType.Target:
|
||||
{
|
||||
Effects.SendTargetParticles( from, m_ItemID, m_Speed, m_Duration, m_Hue, m_RenderMode, m_ParticleEffect, m_EffectLayer, m_Unknown );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
95
Scripts/Items/Misc/EffectItem.cs
Normal file
95
Scripts/Items/Misc/EffectItem.cs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class EffectItem : Item
|
||||
{
|
||||
private static List<EffectItem> m_Free = new List<EffectItem>(); // List of available EffectItems
|
||||
|
||||
public static readonly TimeSpan DefaultDuration = TimeSpan.FromSeconds( 5.0 );
|
||||
|
||||
public static EffectItem Create( Point3D p, Map map, TimeSpan duration )
|
||||
{
|
||||
EffectItem item = null;
|
||||
|
||||
for ( int i = m_Free.Count - 1; item == null && i >= 0; --i ) // We reuse new entries first so decay works better
|
||||
{
|
||||
EffectItem free = m_Free[i];
|
||||
|
||||
m_Free.RemoveAt( i );
|
||||
|
||||
if ( !free.Deleted && free.Map == Map.Internal )
|
||||
item = free;
|
||||
}
|
||||
|
||||
if ( item == null )
|
||||
item = new EffectItem();
|
||||
else
|
||||
item.ItemID = 1;
|
||||
|
||||
item.MoveToWorld( p, map );
|
||||
item.BeginFree( duration );
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
private EffectItem() : base( 1 ) // nodraw
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public void BeginFree( TimeSpan duration )
|
||||
{
|
||||
new FreeTimer( this, duration ).Start();
|
||||
}
|
||||
|
||||
public override bool Decays
|
||||
{
|
||||
get
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public EffectItem( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
private class FreeTimer : Timer
|
||||
{
|
||||
private EffectItem m_Item;
|
||||
|
||||
public FreeTimer( EffectItem item, TimeSpan delay ) : base( delay )
|
||||
{
|
||||
m_Item = item;
|
||||
Priority = TimerPriority.OneSecond;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Item.Internalize();
|
||||
|
||||
m_Free.Add( m_Item );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
130
Scripts/Items/Misc/FlipableAddonAttribute.cs
Normal file
130
Scripts/Items/Misc/FlipableAddonAttribute.cs
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[AttributeUsage( AttributeTargets.Class )]
|
||||
public class FlipableAddonAttribute : Attribute
|
||||
{
|
||||
private static string m_MethodName = "Flip";
|
||||
|
||||
private static Type[] m_Params = new Type[]
|
||||
{
|
||||
typeof( Mobile ), typeof( Direction )
|
||||
};
|
||||
|
||||
private Direction[] m_Directions;
|
||||
|
||||
public Direction[] Directions
|
||||
{
|
||||
get { return m_Directions; }
|
||||
}
|
||||
|
||||
public FlipableAddonAttribute( params Direction[] directions )
|
||||
{
|
||||
m_Directions = directions;
|
||||
}
|
||||
|
||||
public virtual void Flip( Mobile from, Item addon )
|
||||
{
|
||||
if ( m_Directions != null && m_Directions.Length > 1 )
|
||||
{
|
||||
try
|
||||
{
|
||||
MethodInfo flipMethod = addon.GetType().GetMethod( m_MethodName, m_Params );
|
||||
|
||||
if ( flipMethod != null )
|
||||
{
|
||||
int index = 0;
|
||||
|
||||
for ( int i = 0; i < m_Directions.Length; i++ )
|
||||
{
|
||||
if ( addon.Direction == m_Directions[ i ] )
|
||||
{
|
||||
index = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( index >= m_Directions.Length )
|
||||
index = 0;
|
||||
|
||||
ClearComponents( addon );
|
||||
|
||||
flipMethod.Invoke( addon, new object[ 2 ] { from, m_Directions[ index ] } );
|
||||
|
||||
BaseHouse house = null;
|
||||
AddonFitResult result = AddonFitResult.Valid;
|
||||
|
||||
addon.Map = Map.Internal;
|
||||
|
||||
if ( addon is BaseAddon )
|
||||
result = ( (BaseAddon) addon ).CouldFit( addon.Location, from.Map, from, ref house );
|
||||
else if ( addon is BaseAddonContainer )
|
||||
result = ( (BaseAddonContainer) addon ).CouldFit( addon.Location, from.Map, from, ref house );
|
||||
|
||||
addon.Map = from.Map;
|
||||
|
||||
if ( result != AddonFitResult.Valid )
|
||||
{
|
||||
if ( index == 0 )
|
||||
index = m_Directions.Length - 1;
|
||||
else
|
||||
index -= 1;
|
||||
|
||||
ClearComponents( addon );
|
||||
|
||||
flipMethod.Invoke( addon, new object[ 2 ] { from, m_Directions[ index ] } );
|
||||
|
||||
if ( result == AddonFitResult.Blocked )
|
||||
from.SendLocalizedMessage( 500269 ); // You cannot build that there.
|
||||
else if ( result == AddonFitResult.NotInHouse )
|
||||
from.SendLocalizedMessage( 500274 ); // You can only place this in a house that you own!
|
||||
else if ( result == AddonFitResult.DoorsNotClosed )
|
||||
from.SendMessage( "You must close all house doors before placing this." );
|
||||
else if ( result == AddonFitResult.DoorTooClose )
|
||||
from.SendLocalizedMessage( 500271 ); // You cannot build near the door.
|
||||
else if ( result == AddonFitResult.NoWall )
|
||||
from.SendLocalizedMessage( 500268 ); // This object needs to be mounted on something.
|
||||
}
|
||||
|
||||
addon.Direction = m_Directions[ index ];
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ClearComponents( Item item )
|
||||
{
|
||||
if ( item is BaseAddon )
|
||||
{
|
||||
BaseAddon addon = (BaseAddon) item;
|
||||
|
||||
foreach ( AddonComponent c in addon.Components )
|
||||
{
|
||||
c.Addon = null;
|
||||
c.Delete();
|
||||
}
|
||||
|
||||
addon.Components.Clear();
|
||||
}
|
||||
else if ( item is BaseAddonContainer )
|
||||
{
|
||||
BaseAddonContainer addon = (BaseAddonContainer) item;
|
||||
|
||||
foreach ( AddonContainerComponent c in addon.Components )
|
||||
{
|
||||
c.Addon = null;
|
||||
c.Delete();
|
||||
}
|
||||
|
||||
addon.Components.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
118
Scripts/Items/Misc/FlipableAttribute.cs
Normal file
118
Scripts/Items/Misc/FlipableAttribute.cs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
using System;
|
||||
using Server;
|
||||
using System.Reflection;
|
||||
using Server.Targeting;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class FlipCommandHandlers
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "Flip", AccessLevel.GameMaster, new CommandEventHandler( Flip_OnCommand ) );
|
||||
}
|
||||
|
||||
[Usage( "Flip" )]
|
||||
[Description( "Turns an item." )]
|
||||
public static void Flip_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
e.Mobile.Target = new FlipTarget();
|
||||
}
|
||||
|
||||
private class FlipTarget : Target
|
||||
{
|
||||
public FlipTarget()
|
||||
: base( -1, false, TargetFlags.None )
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object targeted )
|
||||
{
|
||||
if( targeted is Item )
|
||||
{
|
||||
Item item = (Item)targeted;
|
||||
|
||||
if( item.Movable == false && from.AccessLevel == AccessLevel.Player )
|
||||
return;
|
||||
|
||||
Type type = targeted.GetType();
|
||||
|
||||
FlipableAttribute[] AttributeArray = (FlipableAttribute[])type.GetCustomAttributes( typeof( FlipableAttribute ), false );
|
||||
|
||||
if( AttributeArray.Length == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FlipableAttribute fa = AttributeArray[0];
|
||||
|
||||
fa.Flip( (Item)targeted );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage( AttributeTargets.Class )]
|
||||
public class DynamicFlipingAttribute : Attribute
|
||||
{
|
||||
public DynamicFlipingAttribute()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage( AttributeTargets.Class )]
|
||||
public class FlipableAttribute : Attribute
|
||||
{
|
||||
private int[] m_ItemIDs;
|
||||
|
||||
public int[] ItemIDs
|
||||
{
|
||||
get { return m_ItemIDs; }
|
||||
}
|
||||
|
||||
public FlipableAttribute()
|
||||
: this( null )
|
||||
{
|
||||
}
|
||||
|
||||
public FlipableAttribute( params int[] itemIDs )
|
||||
{
|
||||
m_ItemIDs = itemIDs;
|
||||
}
|
||||
|
||||
public virtual void Flip( Item item )
|
||||
{
|
||||
if( m_ItemIDs == null )
|
||||
{
|
||||
try
|
||||
{
|
||||
MethodInfo flipMethod = item.GetType().GetMethod( "Flip", Type.EmptyTypes );
|
||||
if( flipMethod != null )
|
||||
flipMethod.Invoke( item, new object[0] );
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
int index = 0;
|
||||
for( int i = 0; i < m_ItemIDs.Length; i++ )
|
||||
{
|
||||
if( item.ItemID == m_ItemIDs[i] )
|
||||
{
|
||||
index = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( index > m_ItemIDs.Length - 1 )
|
||||
index = 0;
|
||||
|
||||
item.ItemID = m_ItemIDs[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1218
Scripts/Items/Misc/GlassItems.cs
Normal file
1218
Scripts/Items/Misc/GlassItems.cs
Normal file
File diff suppressed because it is too large
Load diff
74
Scripts/Items/Misc/Gold.cs
Normal file
74
Scripts/Items/Misc/Gold.cs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Gold : Item
|
||||
{
|
||||
public override double DefaultWeight
|
||||
{
|
||||
get { return ( 0.02 ); }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Gold() : this( 1 )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Gold( int amountFrom, int amountTo ) : this( Utility.RandomMinMax( amountFrom, amountTo ) )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Gold( int amount ) : base( 0xEED )
|
||||
{
|
||||
Stackable = true;
|
||||
Amount = amount;
|
||||
}
|
||||
|
||||
public Gold( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override int GetDropSound()
|
||||
{
|
||||
if ( Amount <= 1 )
|
||||
return 0x2E4;
|
||||
else if ( Amount <= 5 )
|
||||
return 0x2E5;
|
||||
else
|
||||
return 0x2E6;
|
||||
}
|
||||
|
||||
protected override void OnAmountChange( int oldValue )
|
||||
{
|
||||
int newValue = this.Amount;
|
||||
|
||||
UpdateTotal( this, TotalType.Gold, newValue - oldValue );
|
||||
}
|
||||
|
||||
public override int GetTotal( TotalType type )
|
||||
{
|
||||
int baseTotal = base.GetTotal( type );
|
||||
|
||||
if ( type == TotalType.Gold )
|
||||
baseTotal += this.Amount;
|
||||
|
||||
return baseTotal;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
134
Scripts/Items/Misc/GoldDeed.cs
Normal file
134
Scripts/Items/Misc/GoldDeed.cs
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class GoldDeed : Item
|
||||
{
|
||||
private int m_Worth;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Worth
|
||||
{
|
||||
get{ return m_Worth; }
|
||||
set{ m_Worth = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
public GoldDeed( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
|
||||
writer.Write( (int) m_Worth );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Worth = reader.ReadInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public GoldDeed( int worth ) : base( 0x14F0 )
|
||||
{
|
||||
Weight = 1.0;
|
||||
Hue = 0x34;
|
||||
Name = "gold deed";
|
||||
m_Worth = worth;
|
||||
}
|
||||
|
||||
public override int LabelNumber{ get{ return 1041361; } } // A gold deed
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
string worth = m_Worth.ToString();
|
||||
|
||||
list.Add( 1060738, worth ); // value: ~1_val~
|
||||
}
|
||||
|
||||
public override void OnSingleClick( Mobile from )
|
||||
{
|
||||
from.Send( new MessageLocalizedAffix( Serial, ItemID, MessageType.Label, 0x3B2, 3, 1041361, "", AffixType.Append, String.Concat( " ", m_Worth.ToString() ), "" ) ); // A bank check:
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
InnBox box = from.FindInnNoCreate();
|
||||
|
||||
if ( box != null && IsChildOf( box ) )
|
||||
{
|
||||
Delete();
|
||||
|
||||
int deposited = 0;
|
||||
|
||||
int toAdd = m_Worth;
|
||||
|
||||
Gold gold;
|
||||
|
||||
while ( toAdd > 60000 )
|
||||
{
|
||||
gold = new Gold( 60000 );
|
||||
|
||||
if ( box.TryDropItem( from, gold, false ) )
|
||||
{
|
||||
toAdd -= 60000;
|
||||
deposited += 60000;
|
||||
}
|
||||
else
|
||||
{
|
||||
gold.Delete();
|
||||
|
||||
from.AddToBackpack( new GoldDeed( toAdd ) );
|
||||
toAdd = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( toAdd > 0 )
|
||||
{
|
||||
gold = new Gold( toAdd );
|
||||
|
||||
if ( box.TryDropItem( from, gold, false ) )
|
||||
{
|
||||
deposited += toAdd;
|
||||
}
|
||||
else
|
||||
{
|
||||
gold.Delete();
|
||||
|
||||
from.AddToBackpack( new GoldDeed( toAdd ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Gold was deposited in your account:
|
||||
from.SendLocalizedMessage( 1042672, true, " " + deposited.ToString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1047026 ); // That must be in your inn chest to use it.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
115
Scripts/Items/Misc/Guillotine.cs
Normal file
115
Scripts/Items/Misc/Guillotine.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
193
Scripts/Items/Misc/HairDye.cs
Normal file
193
Scripts/Items/Misc/HairDye.cs
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
Scripts/Items/Misc/IDurability.cs
Normal file
22
Scripts/Items/Misc/IDurability.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
interface IDurability
|
||||
{
|
||||
int InitMinHits { get; }
|
||||
int InitMaxHits { get; }
|
||||
|
||||
int HitPoints { get; set; }
|
||||
int MaxHitPoints { get; set; }
|
||||
|
||||
void ScaleDurability();
|
||||
void UnscaleDurability();
|
||||
}
|
||||
|
||||
interface IWearableDurability : IDurability
|
||||
{
|
||||
int OnHit( BaseWeapon weapon, int damageTaken );
|
||||
}
|
||||
}
|
||||
469
Scripts/Items/Misc/Key.cs
Normal file
469
Scripts/Items/Misc/Key.cs
Normal file
|
|
@ -0,0 +1,469 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Server.Network;
|
||||
using Server.Targeting;
|
||||
using Server.Prompts;
|
||||
using Server.Misc;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public enum KeyType
|
||||
{
|
||||
Copper = 0x100E,
|
||||
Gold = 0x100F,
|
||||
Iron = 0x1010,
|
||||
Rusty = 0x1013
|
||||
}
|
||||
|
||||
public interface ILockable
|
||||
{
|
||||
bool Locked{ get; set; }
|
||||
uint KeyValue{ get; set; }
|
||||
}
|
||||
|
||||
public class Key : Item
|
||||
{
|
||||
private string m_Description;
|
||||
private uint m_KeyVal;
|
||||
private Item m_Link;
|
||||
private int m_MaxRange;
|
||||
|
||||
public static uint RandomValue()
|
||||
{
|
||||
return (uint)(0xFFFFFFFE * Utility.RandomDouble()) + 1;
|
||||
}
|
||||
|
||||
public static void RemoveKeys( Mobile m, uint keyValue )
|
||||
{
|
||||
if ( keyValue == 0 )
|
||||
return;
|
||||
|
||||
RemoveKeys( m.Backpack, keyValue );
|
||||
RemoveKeys( m.InnBox, keyValue );
|
||||
}
|
||||
|
||||
public static void RemoveKeys( Container cont, uint keyValue )
|
||||
{
|
||||
if ( cont == null || keyValue == 0 )
|
||||
return;
|
||||
|
||||
Item[] items = cont.FindItemsByType( new Type[] { typeof( Key ), typeof( KeyRing ) } );
|
||||
|
||||
foreach ( Item item in items )
|
||||
{
|
||||
if ( item is Key )
|
||||
{
|
||||
Key key = (Key) item;
|
||||
|
||||
if ( key.KeyValue == keyValue )
|
||||
key.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyRing keyRing = (KeyRing) item;
|
||||
|
||||
keyRing.RemoveKeys( keyValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ContainsKey( Container cont, uint keyValue )
|
||||
{
|
||||
if ( cont == null )
|
||||
return false;
|
||||
|
||||
Item[] items = cont.FindItemsByType( new Type[] { typeof( Key ), typeof( KeyRing ) } );
|
||||
|
||||
foreach ( Item item in items )
|
||||
{
|
||||
if ( item is Key )
|
||||
{
|
||||
Key key = (Key) item;
|
||||
|
||||
if ( key.KeyValue == keyValue )
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
KeyRing keyRing = (KeyRing) item;
|
||||
|
||||
if ( keyRing.ContainsKey( keyValue ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Description
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Description;
|
||||
}
|
||||
set
|
||||
{
|
||||
m_Description = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int MaxRange
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_MaxRange;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
m_MaxRange = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public uint KeyValue
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_KeyVal;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
m_KeyVal = value;
|
||||
InvalidateProperties();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Item Link
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Link;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
m_Link = value;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 2 ); // version
|
||||
|
||||
writer.Write( (int) m_MaxRange );
|
||||
|
||||
writer.Write( (Item) m_Link );
|
||||
|
||||
writer.Write( (string) m_Description );
|
||||
writer.Write( (uint) m_KeyVal );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
m_MaxRange = reader.ReadInt();
|
||||
|
||||
goto case 1;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
m_Link = reader.ReadItem();
|
||||
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
if ( version < 2 || m_MaxRange == 0 )
|
||||
m_MaxRange = 3;
|
||||
|
||||
m_Description = reader.ReadString();
|
||||
|
||||
m_KeyVal = reader.ReadUInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Key() : this( KeyType.Iron, 0 )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Key( KeyType type ) : this( type, 0 )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Key( uint val ) : this ( KeyType.Iron, val )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Key( KeyType type, uint LockVal ) : this( type, LockVal, null )
|
||||
{
|
||||
m_KeyVal = LockVal;
|
||||
}
|
||||
|
||||
public Key( KeyType type, uint LockVal, Item link ) : base( (int)type )
|
||||
{
|
||||
Weight = 1.0;
|
||||
|
||||
m_MaxRange = 3;
|
||||
m_KeyVal = LockVal;
|
||||
m_Link = link;
|
||||
}
|
||||
|
||||
public Key( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( !this.IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 501661 ); // That key is unreachable.
|
||||
return;
|
||||
}
|
||||
|
||||
Target t;
|
||||
int number;
|
||||
|
||||
if ( m_KeyVal != 0 )
|
||||
{
|
||||
number = 501662; // What shall I use this key on?
|
||||
t = new UnlockTarget( this );
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 501663; // This key is a key blank. Which key would you like to make a copy of?
|
||||
t = new CopyTarget( this );
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage( number );
|
||||
from.Target = t;
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
string desc;
|
||||
|
||||
if ( m_KeyVal == 0 )
|
||||
desc = "(blank)";
|
||||
else if ( (desc = m_Description) == null || (desc = desc.Trim()).Length <= 0 )
|
||||
desc = null;
|
||||
|
||||
if ( desc != null )
|
||||
list.Add( desc );
|
||||
}
|
||||
|
||||
public override void OnSingleClick( Mobile from )
|
||||
{
|
||||
base.OnSingleClick( from );
|
||||
|
||||
string desc;
|
||||
|
||||
if ( m_KeyVal == 0 )
|
||||
desc = "(blank)";
|
||||
else if ( (desc = m_Description) == null || (desc = desc.Trim()).Length <= 0 )
|
||||
desc = "";
|
||||
|
||||
if ( desc.Length > 0 )
|
||||
from.Send( new UnicodeMessage( Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", "", desc ) );
|
||||
}
|
||||
|
||||
public bool UseOn( Mobile from, ILockable o )
|
||||
{
|
||||
if ( o.KeyValue == this.KeyValue )
|
||||
{
|
||||
if ( o is BaseDoor && !((BaseDoor)o).UseLocks() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
o.Locked = !o.Locked;
|
||||
|
||||
if ( o is LockableContainer )
|
||||
{
|
||||
LockableContainer cont = (LockableContainer)o;
|
||||
|
||||
if ( cont.LockLevel == -255 )
|
||||
cont.LockLevel = cont.RequiredSkill - 10;
|
||||
}
|
||||
|
||||
if ( o is Item )
|
||||
{
|
||||
Item item = (Item) o;
|
||||
|
||||
if ( o.Locked )
|
||||
item.SendLocalizedMessageTo( from, 1048000 ); // You lock it.
|
||||
else
|
||||
item.SendLocalizedMessageTo( from, 1048001 ); // You unlock it.
|
||||
|
||||
if ( item is LockableContainer )
|
||||
{
|
||||
LockableContainer cont = (LockableContainer) item;
|
||||
|
||||
if ( cont.TrapType != TrapType.None && cont.TrapOnLockpick )
|
||||
{
|
||||
if ( o.Locked )
|
||||
item.SendLocalizedMessageTo( from, 501673 ); // You re-enable the trap.
|
||||
else
|
||||
item.SendLocalizedMessageTo( from, 501672 ); // You disable the trap temporarily. Lock it again to re-enable it.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class RenamePrompt : Prompt
|
||||
{
|
||||
private Key m_Key;
|
||||
|
||||
public RenamePrompt( Key key )
|
||||
{
|
||||
m_Key = key;
|
||||
}
|
||||
|
||||
public override void OnResponse( Mobile from, string text )
|
||||
{
|
||||
if ( m_Key.Deleted || !m_Key.IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 501661 ); // That key is unreachable.
|
||||
return;
|
||||
}
|
||||
|
||||
m_Key.Description = Utility.FixHtml( text );
|
||||
}
|
||||
}
|
||||
|
||||
private class UnlockTarget : Target
|
||||
{
|
||||
private Key m_Key;
|
||||
|
||||
public UnlockTarget( Key key ) : base( key.MaxRange, false, TargetFlags.None )
|
||||
{
|
||||
m_Key = key;
|
||||
CheckLOS = false;
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object targeted )
|
||||
{
|
||||
if ( m_Key.Deleted || !m_Key.IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 501661 ); // That key is unreachable.
|
||||
return;
|
||||
}
|
||||
|
||||
int number;
|
||||
|
||||
if ( targeted == m_Key )
|
||||
{
|
||||
number = 501665; // Enter a description for this key.
|
||||
|
||||
from.Prompt = new RenamePrompt( m_Key );
|
||||
}
|
||||
else if ( targeted is ILockable )
|
||||
{
|
||||
if ( m_Key.UseOn( from, (ILockable) targeted ) )
|
||||
number = -1;
|
||||
else
|
||||
number = 501668; // This key doesn't seem to unlock that.
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 501666; // You can't unlock that!
|
||||
}
|
||||
|
||||
if ( number != -1 )
|
||||
{
|
||||
from.SendLocalizedMessage( number );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CopyTarget : Target
|
||||
{
|
||||
private Key m_Key;
|
||||
|
||||
public CopyTarget( Key key ) : base( 3, false, TargetFlags.None )
|
||||
{
|
||||
m_Key = key;
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object targeted )
|
||||
{
|
||||
if ( m_Key.Deleted || !m_Key.IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 501661 ); // That key is unreachable.
|
||||
return;
|
||||
}
|
||||
|
||||
int number;
|
||||
|
||||
if ( targeted is Key )
|
||||
{
|
||||
Key k = (Key)targeted;
|
||||
|
||||
if ( k.m_KeyVal == 0 )
|
||||
{
|
||||
number = 501675; // This key is also blank.
|
||||
}
|
||||
else if ( SkillCheck.TestTrade( from, Trades.Tinkering, 0, 75.0 ) )
|
||||
{
|
||||
number = 501676; // You make a copy of the key.
|
||||
|
||||
m_Key.Description = k.Description;
|
||||
m_Key.KeyValue = k.KeyValue;
|
||||
m_Key.Link = k.Link;
|
||||
m_Key.MaxRange = k.MaxRange;
|
||||
}
|
||||
else if ( Utility.RandomDouble() <= 0.1 ) // 10% chance to destroy the key
|
||||
{
|
||||
from.SendLocalizedMessage( 501677 ); // You fail to make a copy of the key.
|
||||
|
||||
number = 501678; // The key was destroyed in the attempt.
|
||||
|
||||
m_Key.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 501677; // You fail to make a copy of the key.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
number = 501688; // Not a key.
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage( number );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
207
Scripts/Items/Misc/KeyRing.cs
Normal file
207
Scripts/Items/Misc/KeyRing.cs
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class KeyRing : Item
|
||||
{
|
||||
public static readonly int MaxKeys = 20;
|
||||
|
||||
private List<Key> m_Keys;
|
||||
|
||||
public List<Key> Keys { get { return m_Keys; } }
|
||||
|
||||
[Constructable]
|
||||
public KeyRing() : base( 0x1011 )
|
||||
{
|
||||
Weight = 1.0; // They seem to have no weight on OSI ?!
|
||||
|
||||
m_Keys = new List<Key>();
|
||||
}
|
||||
|
||||
public override bool OnDragDrop( Mobile from, Item dropped )
|
||||
{
|
||||
if ( !this.IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1060640 ); // The item must be in your backpack to use it.
|
||||
return false;
|
||||
}
|
||||
|
||||
Key key = dropped as Key;
|
||||
|
||||
if ( key == null || key.KeyValue == 0 )
|
||||
{
|
||||
from.SendLocalizedMessage( 501689 ); // Only non-blank keys can be put on a keyring.
|
||||
return false;
|
||||
}
|
||||
else if ( this.Keys.Count >= MaxKeys )
|
||||
{
|
||||
from.SendLocalizedMessage( 1008138 ); // This keyring is full.
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Add( key );
|
||||
from.SendLocalizedMessage( 501691 ); // You put the key on the keyring.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( !this.IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1060640 ); // The item must be in your backpack to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage( 501680 ); // What do you want to unlock?
|
||||
from.Target = new InternalTarget( this );
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
private KeyRing m_KeyRing;
|
||||
|
||||
public InternalTarget( KeyRing keyRing ) : base( -1, false, TargetFlags.None )
|
||||
{
|
||||
m_KeyRing = keyRing;
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object targeted )
|
||||
{
|
||||
if ( m_KeyRing.Deleted || !m_KeyRing.IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1060640 ); // The item must be in your backpack to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_KeyRing == targeted )
|
||||
{
|
||||
m_KeyRing.Open( from );
|
||||
from.SendLocalizedMessage( 501685 ); // You open the keyring.
|
||||
}
|
||||
else if ( targeted is ILockable )
|
||||
{
|
||||
ILockable o = (ILockable) targeted;
|
||||
|
||||
foreach ( Key key in m_KeyRing.Keys )
|
||||
{
|
||||
if ( key.UseOn( from, o ) )
|
||||
return;
|
||||
}
|
||||
|
||||
from.SendLocalizedMessage( 1008140 ); // You do not have a key for that.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 501666 ); // You can't unlock that!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
base.OnDelete();
|
||||
|
||||
foreach ( Key key in m_Keys )
|
||||
{
|
||||
key.Delete();
|
||||
}
|
||||
|
||||
m_Keys.Clear();
|
||||
}
|
||||
|
||||
public void Add( Key key )
|
||||
{
|
||||
key.Internalize();
|
||||
m_Keys.Add( key );
|
||||
|
||||
UpdateItemID();
|
||||
}
|
||||
|
||||
public void Open( Mobile from )
|
||||
{
|
||||
Container cont = this.Parent as Container;
|
||||
|
||||
if ( cont == null )
|
||||
return;
|
||||
|
||||
for ( int i = m_Keys.Count - 1; i >= 0; i-- )
|
||||
{
|
||||
Key key = m_Keys[i];
|
||||
|
||||
if ( !key.Deleted && !cont.TryDropItem( from, key, true ) )
|
||||
break;
|
||||
|
||||
m_Keys.RemoveAt( i );
|
||||
}
|
||||
|
||||
UpdateItemID();
|
||||
}
|
||||
|
||||
public void RemoveKeys( uint keyValue )
|
||||
{
|
||||
for ( int i = m_Keys.Count - 1; i >= 0; i-- )
|
||||
{
|
||||
Key key = m_Keys[i];
|
||||
|
||||
if ( key.KeyValue == keyValue )
|
||||
{
|
||||
key.Delete();
|
||||
m_Keys.RemoveAt( i );
|
||||
}
|
||||
}
|
||||
|
||||
UpdateItemID();
|
||||
}
|
||||
|
||||
public bool ContainsKey( uint keyValue )
|
||||
{
|
||||
foreach ( Key key in m_Keys )
|
||||
{
|
||||
if ( key.KeyValue == keyValue )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void UpdateItemID()
|
||||
{
|
||||
if ( this.Keys.Count < 1 )
|
||||
this.ItemID = 0x1011;
|
||||
else if ( this.Keys.Count < 3 )
|
||||
this.ItemID = 0x1769;
|
||||
else if ( this.Keys.Count < 5 )
|
||||
this.ItemID = 0x176A;
|
||||
else
|
||||
this.ItemID = 0x176B;
|
||||
}
|
||||
|
||||
public KeyRing( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.WriteEncodedInt( 0 ); // version
|
||||
|
||||
writer.WriteItemList<Key>( m_Keys );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
m_Keys = reader.ReadStrongItemList<Key>();
|
||||
}
|
||||
}
|
||||
}
|
||||
119
Scripts/Items/Misc/LOSBlocker.cs
Normal file
119
Scripts/Items/Misc/LOSBlocker.cs
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class LOSBlocker : Item
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
TileData.ItemTable[0x21A2].Flags = TileFlag.Wall | TileFlag.NoShoot;
|
||||
TileData.ItemTable[0x21A2].Height = 20;
|
||||
}
|
||||
|
||||
public override string DefaultName
|
||||
{
|
||||
get { return "no line of sight"; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public LOSBlocker() : base( 0x21A2 )
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public LOSBlocker( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
protected override Packet GetWorldPacketFor( NetState state ) {
|
||||
Mobile mob = state.Mobile;
|
||||
|
||||
if ( mob != null && mob.AccessLevel >= AccessLevel.GameMaster ) {
|
||||
return new GMItemPacket( this );
|
||||
}
|
||||
|
||||
return base.GetWorldPacketFor( state );
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 1 );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if ( version < 1 && ItemID == 0x2199 )
|
||||
this.ItemID = 0x21A2;
|
||||
}
|
||||
|
||||
public sealed class GMItemPacket : Packet
|
||||
{
|
||||
public GMItemPacket( Item item ) : base( 0x1A )
|
||||
{
|
||||
this.EnsureCapacity( 20 );
|
||||
|
||||
// 14 base length
|
||||
// +2 - Amount
|
||||
// +2 - Hue
|
||||
// +1 - Flags
|
||||
|
||||
uint serial = (uint)item.Serial.Value;
|
||||
int itemID = 0x36FF;
|
||||
int amount = item.Amount;
|
||||
Point3D loc = item.Location;
|
||||
int x = loc.X;
|
||||
int y = loc.Y;
|
||||
int hue = item.Hue;
|
||||
int flags = item.GetPacketFlags();
|
||||
int direction = (int)item.Direction;
|
||||
|
||||
if ( amount != 0 )
|
||||
serial |= 0x80000000;
|
||||
else
|
||||
serial &= 0x7FFFFFFF;
|
||||
|
||||
m_Stream.Write( (uint) serial );
|
||||
m_Stream.Write( (short) (itemID & 0x7FFF) );
|
||||
|
||||
if ( amount != 0 )
|
||||
m_Stream.Write( (short) amount );
|
||||
|
||||
x &= 0x7FFF;
|
||||
|
||||
if ( direction != 0 )
|
||||
x |= 0x8000;
|
||||
|
||||
m_Stream.Write( (short) x );
|
||||
|
||||
y &= 0x3FFF;
|
||||
|
||||
if ( hue != 0 )
|
||||
y |= 0x8000;
|
||||
|
||||
if ( flags != 0 )
|
||||
y |= 0x4000;
|
||||
|
||||
m_Stream.Write( (short) y );
|
||||
|
||||
if ( direction != 0 )
|
||||
m_Stream.Write( (byte) direction );
|
||||
|
||||
m_Stream.Write( (sbyte) loc.Z );
|
||||
|
||||
if ( hue != 0 )
|
||||
m_Stream.Write( (ushort) hue );
|
||||
|
||||
if ( flags != 0 )
|
||||
m_Stream.Write( (byte) flags );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
Scripts/Items/Misc/Moongate.cs
Normal file
63
Scripts/Items/Misc/Moongate.cs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Misc;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Moongate : Item
|
||||
{
|
||||
[Constructable]
|
||||
public Moongate() : base(0x0F6C)
|
||||
{
|
||||
Movable = false;
|
||||
Name = "moongate";
|
||||
Light = LightType.Circle300;
|
||||
}
|
||||
|
||||
public Moongate(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override bool OnMoveOver( Mobile m )
|
||||
{
|
||||
Point3D loc = new Point3D( 2030, 1631, 8 );
|
||||
|
||||
if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.NewMoon ) // MOONGLOW
|
||||
loc = new Point3D( 3958, 2034, 2 );
|
||||
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.WaxingCrescentMoon ) // BRITAIN
|
||||
loc = new Point3D( 2030, 1631, 8 );
|
||||
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.FirstQuarter ) // JHELOM
|
||||
loc = new Point3D( 1173, 3251, 3 );
|
||||
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.WaxingGibbous ) // YEW
|
||||
loc = new Point3D( 1322, 743, 2 );
|
||||
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.FullMoon ) // MINOC
|
||||
loc = new Point3D( 3031, 462, 2 );
|
||||
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.WaningGibbous ) // TRINSIC
|
||||
loc = new Point3D( 2065, 2828, 2 );
|
||||
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.LastQuarter ) // SKARA BRAE
|
||||
loc = new Point3D( 790, 1949, 2 );
|
||||
else if ( Clock.GetMoonPhase( Map.Britannia, 3584, 2048 ) == MoonPhase.WaningCrescent ) // MAGINCIA
|
||||
loc = new Point3D( 3354, 2551, 12 );
|
||||
|
||||
BaseCreature.TeleportPets( m, loc, Map.Britannia, false );
|
||||
m.MoveToWorld ( loc, Map.Britannia );
|
||||
m.PlaySound( 0x1FE );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
146
Scripts/Items/Misc/MorphItem.cs
Normal file
146
Scripts/Items/Misc/MorphItem.cs
Normal 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 ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
111
Scripts/Items/Misc/OilCloth.cs
Normal file
111
Scripts/Items/Misc/OilCloth.cs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class OilCloth : Item, IScissorable, IDyable
|
||||
{
|
||||
public override int LabelNumber{ get{ return 1041498; } } // oil cloth
|
||||
|
||||
public override double DefaultWeight
|
||||
{
|
||||
get { return 1.0; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public OilCloth() : base( 0x175D )
|
||||
{
|
||||
Hue = 2001;
|
||||
}
|
||||
|
||||
public bool Dye( Mobile from, DyeTub sender )
|
||||
{
|
||||
if ( Deleted )
|
||||
return false;
|
||||
|
||||
Hue = sender.DyedHue;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Scissor( Mobile from, Scissors scissors )
|
||||
{
|
||||
if ( Deleted || !from.CanSee( this ) )
|
||||
return false;
|
||||
|
||||
base.ScissorHelper( from, new Bandage(), 1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.BeginTarget( -1, false, TargetFlags.None, new TargetCallback( OnTarget ) );
|
||||
from.SendLocalizedMessage( 1005424 ); // Select the weapon or armor you wish to use the cloth on.
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
|
||||
}
|
||||
}
|
||||
|
||||
public void OnTarget( Mobile from, object obj )
|
||||
{
|
||||
if ( !IsChildOf( from.Backpack ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
|
||||
}
|
||||
else if ( obj is BaseWeapon )
|
||||
{
|
||||
BaseWeapon weapon = (BaseWeapon)obj;
|
||||
|
||||
if ( weapon.RootParent != from )
|
||||
{
|
||||
from.SendLocalizedMessage( 1005425 ); // You may only wipe down items you are holding or carrying.
|
||||
}
|
||||
else if ( weapon.Poison == null || weapon.PoisonCharges <= 0 )
|
||||
{
|
||||
from.LocalOverheadMessage( Network.MessageType.Regular, 0x3B2, 1005422 ); // Hmmmm... this does not need to be cleaned.
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( weapon.PoisonCharges < 2 )
|
||||
weapon.PoisonCharges = 0;
|
||||
else
|
||||
weapon.PoisonCharges -= 2;
|
||||
|
||||
if ( weapon.PoisonCharges > 0 )
|
||||
from.SendLocalizedMessage( 1005423 ); // You have removed some of the caustic substance, but not all.
|
||||
else
|
||||
from.SendLocalizedMessage( 1010497 ); // You have cleaned the item.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1005426 ); // The cloth will not work on that.
|
||||
}
|
||||
}
|
||||
|
||||
public OilCloth( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
437
Scripts/Items/Misc/Plants.cs
Normal file
437
Scripts/Items/Misc/Plants.cs
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
[Furniture]
|
||||
public class HousePlantA : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantA() : base( 0x18B8 )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantA( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantB : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantB() : base( 0x18B9 )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantB( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantC : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantC() : base( 0x18BA )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantC( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantD : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantD() : base( 0x18BB )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantD( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantE : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantE() : base( 0x18BC )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantE( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantF : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantF() : base( 0x18BD )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantF( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantG : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantG() : base( 0x18BE )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantG( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantH : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantH() : base( 0x18BF )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantH( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantI : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantI() : base( 0x18C0 )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantI( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantJ : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantJ() : base( 0x18C1 )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantJ( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantK : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantK() : base( 0x18C2 )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantK( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantL : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantL() : base( 0x18C3 )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantL( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantM : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantM() : base( 0x18C4 )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantM( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantN : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantN() : base( 0x18C5 )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantN( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantO : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantO() : base( 0x18C6 )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantO( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
[Furniture]
|
||||
public class HousePlantP : Item
|
||||
{
|
||||
[Constructable]
|
||||
public HousePlantP() : base( 0x18C7 )
|
||||
{
|
||||
Name = "plant";
|
||||
Weight = 10.0;
|
||||
}
|
||||
|
||||
public HousePlantP( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
640
Scripts/Items/Misc/PlayerBulletinBoards.cs
Normal file
640
Scripts/Items/Misc/PlayerBulletinBoards.cs
Normal file
|
|
@ -0,0 +1,640 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Gumps;
|
||||
using Server.Multis;
|
||||
using Server.Prompts;
|
||||
using Server.Mobiles;
|
||||
using Server.Network;
|
||||
using Server.ContextMenus;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PlayerBBSouth : BasePlayerBB
|
||||
{
|
||||
public override int LabelNumber{ get{ return 1062421; } } // bulletin board (south)
|
||||
|
||||
[Constructable]
|
||||
public PlayerBBSouth() : base( 0x2311 )
|
||||
{
|
||||
Weight = 15.0;
|
||||
}
|
||||
|
||||
public PlayerBBSouth( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerBBEast : BasePlayerBB
|
||||
{
|
||||
public override int LabelNumber{ get{ return 1062420; } } // bulletin board (east)
|
||||
|
||||
[Constructable]
|
||||
public PlayerBBEast() : base( 0x2312 )
|
||||
{
|
||||
Weight = 15.0;
|
||||
}
|
||||
|
||||
public PlayerBBEast( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BasePlayerBB : Item, ISecurable
|
||||
{
|
||||
private PlayerBBMessage m_Greeting;
|
||||
private List<PlayerBBMessage> m_Messages;
|
||||
private string m_Title;
|
||||
private SecureLevel m_Level;
|
||||
|
||||
public List<PlayerBBMessage> Messages
|
||||
{
|
||||
get{ return m_Messages; }
|
||||
}
|
||||
|
||||
public PlayerBBMessage Greeting
|
||||
{
|
||||
get{ return m_Greeting; }
|
||||
set{ m_Greeting = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Title
|
||||
{
|
||||
get{ return m_Title; }
|
||||
set{ m_Title = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public SecureLevel Level
|
||||
{
|
||||
get{ return m_Level; }
|
||||
set{ m_Level = value; }
|
||||
}
|
||||
|
||||
public BasePlayerBB( int itemID ) : base( itemID )
|
||||
{
|
||||
m_Messages = new List<PlayerBBMessage>();
|
||||
m_Level = SecureLevel.Anyone;
|
||||
}
|
||||
|
||||
public BasePlayerBB( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
|
||||
{
|
||||
base.GetContextMenuEntries( from, list );
|
||||
SetSecureLevelEntry.AddTo( from, this, list );
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 1 );
|
||||
|
||||
writer.Write( (int) m_Level );
|
||||
|
||||
writer.Write( m_Title );
|
||||
|
||||
if ( m_Greeting != null )
|
||||
{
|
||||
writer.Write( true );
|
||||
m_Greeting.Serialize( writer );
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.Write( false );
|
||||
}
|
||||
|
||||
writer.WriteEncodedInt( m_Messages.Count );
|
||||
|
||||
for ( int i = 0; i < m_Messages.Count; ++i )
|
||||
m_Messages[i].Serialize( writer );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
m_Level = (SecureLevel)reader.ReadInt();
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
if ( version < 1 )
|
||||
m_Level = SecureLevel.Anyone;
|
||||
|
||||
m_Title = reader.ReadString();
|
||||
|
||||
if ( reader.ReadBool() )
|
||||
m_Greeting = new PlayerBBMessage( reader );
|
||||
|
||||
int count = reader.ReadEncodedInt();
|
||||
|
||||
m_Messages = new List<PlayerBBMessage>( count );
|
||||
|
||||
for ( int i = 0; i < count; ++i )
|
||||
m_Messages.Add( new PlayerBBMessage( reader ) );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool CheckAccess( BaseHouse house, Mobile from )
|
||||
{
|
||||
if ( house.Public || !house.IsAosRules )
|
||||
return !house.IsBanned( from );
|
||||
|
||||
return house.HasAccess( from );
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt( this );
|
||||
|
||||
if ( house == null || !house.IsLockedDown( this ) )
|
||||
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
|
||||
else if ( !from.InRange( this.GetWorldLocation(), 2 ) || !from.InLOS( this ) )
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
|
||||
else if ( CheckAccess( house, from ) )
|
||||
from.SendGump( new PlayerBBGump( from, house, this, 0 ) );
|
||||
}
|
||||
|
||||
public class PostPrompt : Prompt
|
||||
{
|
||||
private int m_Page;
|
||||
private BaseHouse m_House;
|
||||
private BasePlayerBB m_Board;
|
||||
private bool m_Greeting;
|
||||
|
||||
public PostPrompt( int page, BaseHouse house, BasePlayerBB board, bool greeting )
|
||||
{
|
||||
m_Page = page;
|
||||
m_House = house;
|
||||
m_Board = board;
|
||||
m_Greeting = greeting;
|
||||
}
|
||||
|
||||
public override void OnCancel( Mobile from )
|
||||
{
|
||||
OnResponse( from, "" );
|
||||
}
|
||||
|
||||
public override void OnResponse( Mobile from, string text )
|
||||
{
|
||||
int page = m_Page;
|
||||
BaseHouse house = m_House;
|
||||
BasePlayerBB board = m_Board;
|
||||
|
||||
if ( house == null || !house.IsLockedDown( board ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
|
||||
return;
|
||||
}
|
||||
else if ( !from.InRange( board.GetWorldLocation(), 2 ) || !from.InLOS( board ) )
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
else if ( !CheckAccess( house, from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062398 ); // You are not allowed to post to this bulletin board.
|
||||
return;
|
||||
}
|
||||
else if ( m_Greeting && !house.IsOwner( from ) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
text = text.Trim();
|
||||
|
||||
if ( text.Length > 255 )
|
||||
text = text.Substring( 0, 255 );
|
||||
|
||||
if ( text.Length > 0 )
|
||||
{
|
||||
PlayerBBMessage message = new PlayerBBMessage( DateTime.Now, from, text );
|
||||
|
||||
if ( m_Greeting )
|
||||
{
|
||||
board.Greeting = message;
|
||||
}
|
||||
else
|
||||
{
|
||||
board.Messages.Add( message );
|
||||
|
||||
if ( board.Messages.Count > 50 )
|
||||
{
|
||||
board.Messages.RemoveAt( 0 );
|
||||
|
||||
if ( page > 0 )
|
||||
--page;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class SetTitlePrompt : Prompt
|
||||
{
|
||||
private int m_Page;
|
||||
private BaseHouse m_House;
|
||||
private BasePlayerBB m_Board;
|
||||
|
||||
public SetTitlePrompt( int page, BaseHouse house, BasePlayerBB board )
|
||||
{
|
||||
m_Page = page;
|
||||
m_House = house;
|
||||
m_Board = board;
|
||||
}
|
||||
|
||||
public override void OnCancel( Mobile from )
|
||||
{
|
||||
OnResponse( from, "" );
|
||||
}
|
||||
|
||||
public override void OnResponse( Mobile from, string text )
|
||||
{
|
||||
int page = m_Page;
|
||||
BaseHouse house = m_House;
|
||||
BasePlayerBB board = m_Board;
|
||||
|
||||
if ( house == null || !house.IsLockedDown( board ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
|
||||
return;
|
||||
}
|
||||
else if ( !from.InRange( board.GetWorldLocation(), 2 ) || !from.InLOS( board ) )
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
else if ( !CheckAccess( house, from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062398 ); // You are not allowed to post to this bulletin board.
|
||||
return;
|
||||
}
|
||||
|
||||
text = text.Trim();
|
||||
|
||||
if ( text.Length > 255 )
|
||||
text = text.Substring( 0, 255 );
|
||||
|
||||
if ( text.Length > 0 )
|
||||
board.Title = text;
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerBBMessage
|
||||
{
|
||||
private DateTime m_Time;
|
||||
private Mobile m_Poster;
|
||||
private string m_Message;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public DateTime Time
|
||||
{
|
||||
get{ return m_Time; }
|
||||
set{ m_Time = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Mobile Poster
|
||||
{
|
||||
get{ return m_Poster; }
|
||||
set{ m_Poster = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Message
|
||||
{
|
||||
get{ return m_Message; }
|
||||
set{ m_Message = value; }
|
||||
}
|
||||
|
||||
public PlayerBBMessage( DateTime time, Mobile poster, string message )
|
||||
{
|
||||
m_Time = time;
|
||||
m_Poster = poster;
|
||||
m_Message = message;
|
||||
}
|
||||
|
||||
public PlayerBBMessage( GenericReader reader )
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Time = reader.ReadDateTime();
|
||||
m_Poster = reader.ReadMobile();
|
||||
m_Message = reader.ReadString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize( GenericWriter writer )
|
||||
{
|
||||
writer.WriteEncodedInt( 0 ); // version
|
||||
|
||||
writer.Write( m_Time );
|
||||
writer.Write( m_Poster );
|
||||
writer.Write( m_Message );
|
||||
}
|
||||
}
|
||||
|
||||
public class PlayerBBGump : Gump
|
||||
{
|
||||
private int m_Page;
|
||||
private Mobile m_From;
|
||||
private BaseHouse m_House;
|
||||
private BasePlayerBB m_Board;
|
||||
|
||||
private const int LabelColor = 0x7FFF;
|
||||
private const int LabelHue = 1153;
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
int page = m_Page;
|
||||
Mobile from = m_From;
|
||||
BaseHouse house = m_House;
|
||||
BasePlayerBB board = m_Board;
|
||||
|
||||
if ( house == null || !house.IsLockedDown( board ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062396 ); // This bulletin board must be locked down in a house to be usable.
|
||||
return;
|
||||
}
|
||||
else if ( !from.InRange( board.GetWorldLocation(), 2 ) || !from.InLOS( board ) )
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 1019045 ); // I can't reach that.
|
||||
return;
|
||||
}
|
||||
else if ( !BasePlayerBB.CheckAccess( house, from ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062398 ); // You are not allowed to post to this bulletin board.
|
||||
return;
|
||||
}
|
||||
|
||||
switch ( info.ButtonID )
|
||||
{
|
||||
case 1: // Post message
|
||||
{
|
||||
from.Prompt = new BasePlayerBB.PostPrompt( page, house, board, false );
|
||||
from.SendLocalizedMessage( 1062397 ); // Please enter your message:
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: // Set title
|
||||
{
|
||||
if ( house.IsOwner( from ) )
|
||||
{
|
||||
from.Prompt = new BasePlayerBB.SetTitlePrompt( page, house, board );
|
||||
from.SendLocalizedMessage( 1062402 ); // Enter new title:
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 3: // Post greeting
|
||||
{
|
||||
if ( house.IsOwner( from ) )
|
||||
{
|
||||
from.Prompt = new BasePlayerBB.PostPrompt( page, house, board, true );
|
||||
from.SendLocalizedMessage( 1062404 ); // Enter new greeting (this will always be the first post):
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 4: // Scroll up
|
||||
{
|
||||
if ( page == 0 )
|
||||
page = board.Messages.Count;
|
||||
else
|
||||
page -= 1;
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
|
||||
break;
|
||||
}
|
||||
case 5: // Scroll down
|
||||
{
|
||||
page += 1;
|
||||
page %= board.Messages.Count + 1;
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
|
||||
break;
|
||||
}
|
||||
case 6: // Banish poster
|
||||
{
|
||||
if ( house.IsOwner( from ) )
|
||||
{
|
||||
if ( page >= 1 && page <= board.Messages.Count )
|
||||
{
|
||||
PlayerBBMessage message = (PlayerBBMessage)board.Messages[page - 1];
|
||||
Mobile poster = message.Poster;
|
||||
|
||||
if ( poster == null )
|
||||
{
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( poster.AccessLevel > AccessLevel.Player && from.AccessLevel <= poster.AccessLevel )
|
||||
{
|
||||
from.SendLocalizedMessage( 501354 ); // Uh oh...a bigger boot may be required.
|
||||
}
|
||||
else if ( house.IsFriend( poster ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 1060750 ); // That person is a friend, co-owner, or owner of this house, and therefore cannot be banished!
|
||||
}
|
||||
else if ( poster is PlayerVendor )
|
||||
{
|
||||
from.SendLocalizedMessage( 501351 ); // You cannot eject a vendor.
|
||||
}
|
||||
else if ( house.Bans.Count >= BaseHouse.MaxBans )
|
||||
{
|
||||
from.SendLocalizedMessage( 501355 ); // The ban limit for this house has been reached!
|
||||
}
|
||||
else if ( house.IsBanned( poster ) )
|
||||
{
|
||||
from.SendLocalizedMessage( 501356 ); // This person is already banned!
|
||||
}
|
||||
else if ( poster is BaseCreature && ((BaseCreature)poster).NoHouseRestrictions )
|
||||
{
|
||||
from.SendLocalizedMessage( 1062040 ); // You cannot ban that.
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !house.Bans.Contains( poster ) )
|
||||
house.Bans.Add( poster );
|
||||
|
||||
from.SendLocalizedMessage( 1062417 ); // That person has been banned from this house.
|
||||
|
||||
if ( house.IsInside( poster ) && !BasePlayerBB.CheckAccess( house, poster ) )
|
||||
poster.MoveToWorld( house.BanLocation, house.Map );
|
||||
}
|
||||
}
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 7: // Delete message
|
||||
{
|
||||
if ( house.IsOwner( from ) )
|
||||
{
|
||||
if ( page >= 1 && page <= board.Messages.Count )
|
||||
board.Messages.RemoveAt( page - 1 );
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, 0 ) );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 8: // Post props
|
||||
{
|
||||
if ( from.AccessLevel >= AccessLevel.GameMaster )
|
||||
{
|
||||
PlayerBBMessage message = board.Greeting;
|
||||
|
||||
if ( page >= 1 && page <= board.Messages.Count )
|
||||
message = (PlayerBBMessage)board.Messages[page - 1];
|
||||
|
||||
from.SendGump( new PlayerBBGump( from, house, board, page ) );
|
||||
from.SendGump( new PropertiesGump( from, message ) );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerBBGump( Mobile from, BaseHouse house, BasePlayerBB board, int page ) : base( 50, 10 )
|
||||
{
|
||||
from.CloseGump( typeof( PlayerBBGump ) );
|
||||
|
||||
m_Page = page;
|
||||
m_From = from;
|
||||
m_House = house;
|
||||
m_Board = board;
|
||||
|
||||
AddPage( 0 );
|
||||
|
||||
AddImage( 30, 30, 5400 );
|
||||
|
||||
AddButton( 393, 145, 2084, 2084, 4, GumpButtonType.Reply, 0 ); // Scroll up
|
||||
AddButton( 390, 371, 2085, 2085, 5, GumpButtonType.Reply, 0 ); // Scroll down
|
||||
|
||||
AddButton( 32, 183, 5412, 5413, 1, GumpButtonType.Reply, 0 ); // Post message
|
||||
|
||||
if ( house.IsOwner( from ) )
|
||||
{
|
||||
AddButton( 63, 90, 5601, 5605, 2, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 81, 89, 230, 20, 1062400, LabelColor, false, false ); // Set title
|
||||
|
||||
AddButton( 63, 109, 5601, 5605, 3, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 81, 108, 230, 20, 1062401, LabelColor, false, false ); // Post greeting
|
||||
}
|
||||
|
||||
string title = board.Title;
|
||||
|
||||
if ( title != null )
|
||||
AddHtml( 183, 68, 180, 23, title, false, false );
|
||||
|
||||
AddHtmlLocalized( 385, 89, 60, 20, 1062409, LabelColor, false, false ); // Post
|
||||
|
||||
AddLabel( 440, 89, LabelHue, page.ToString() );
|
||||
AddLabel( 455, 89, LabelHue, "/" );
|
||||
AddLabel( 470, 89, LabelHue, board.Messages.Count.ToString() );
|
||||
|
||||
PlayerBBMessage message = board.Greeting;
|
||||
|
||||
if ( page >= 1 && page <= board.Messages.Count )
|
||||
message = (PlayerBBMessage)board.Messages[page - 1];
|
||||
|
||||
AddImageTiled( 150, 220, 240, 1, 2700 ); // Separator
|
||||
|
||||
AddHtmlLocalized( 150, 180, 100, 20, 1062405, 16715, false, false ); // Posted On:
|
||||
AddHtmlLocalized( 150, 200, 100, 20, 1062406, 16715, false, false ); // Posted By:
|
||||
|
||||
if ( message != null )
|
||||
{
|
||||
AddHtml( 255, 180, 150, 20, message.Time.ToString( "yyyy-MM-dd HH:mm:ss" ), false, false );
|
||||
|
||||
Mobile poster = message.Poster;
|
||||
string name = ( poster == null ? null : poster.Name );
|
||||
|
||||
if ( name == null || (name = name.Trim()).Length == 0 )
|
||||
name = "Someone";
|
||||
|
||||
AddHtml( 255, 200, 150, 20, name, false, false );
|
||||
|
||||
string body = message.Message;
|
||||
|
||||
if ( body == null )
|
||||
body = "";
|
||||
|
||||
AddHtml( 150, 240, 250, 100, body, false, false );
|
||||
|
||||
if ( message != board.Greeting && house.IsOwner( from ) )
|
||||
{
|
||||
AddButton( 130, 395, 1209, 1210, 6, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 150, 393, 150, 20, 1062410, LabelColor, false, false ); // Banish Poster
|
||||
|
||||
AddButton( 310, 395, 1209, 1210, 7, GumpButtonType.Reply, 0 );
|
||||
AddHtmlLocalized( 330, 393, 150, 20, 1062411, LabelColor, false, false ); // Delete Message
|
||||
}
|
||||
|
||||
if ( from.AccessLevel >= AccessLevel.GameMaster )
|
||||
AddButton( 135, 242, 1209, 1210, 8, GumpButtonType.Reply, 0 ); // Post props
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
101
Scripts/Items/Misc/PoolOfAcid.cs
Normal file
101
Scripts/Items/Misc/PoolOfAcid.cs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Spells;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class PoolOfAcid : Item
|
||||
{
|
||||
private TimeSpan m_Duration;
|
||||
private int m_MinDamage;
|
||||
private int m_MaxDamage;
|
||||
private DateTime m_Created;
|
||||
private bool m_Drying;
|
||||
private Timer m_Timer;
|
||||
|
||||
[Constructable]
|
||||
public PoolOfAcid() : this( TimeSpan.FromSeconds( 10.0 ), 2, 5 )
|
||||
{
|
||||
}
|
||||
|
||||
public override string DefaultName { get { return "a pool of acid"; } }
|
||||
|
||||
[Constructable]
|
||||
public PoolOfAcid( TimeSpan duration, int minDamage, int maxDamage )
|
||||
: base( 0x122A )
|
||||
{
|
||||
Hue = 0x3F;
|
||||
Movable = false;
|
||||
|
||||
m_MinDamage = minDamage;
|
||||
m_MaxDamage = maxDamage;
|
||||
m_Created = DateTime.Now;
|
||||
m_Duration = duration;
|
||||
|
||||
m_Timer = Timer.DelayCall( TimeSpan.Zero, TimeSpan.FromSeconds( 1 ), new TimerCallback( OnTick ) );
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
if( m_Timer != null )
|
||||
m_Timer.Stop();
|
||||
}
|
||||
|
||||
private void OnTick()
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
TimeSpan age = now - m_Created;
|
||||
|
||||
if( age > m_Duration ) {
|
||||
Delete();
|
||||
} else {
|
||||
if( !m_Drying && age > (m_Duration - age) )
|
||||
{
|
||||
m_Drying = true;
|
||||
ItemID = 0x122B;
|
||||
}
|
||||
|
||||
List<Mobile> toDamage = new List<Mobile>();
|
||||
|
||||
foreach( Mobile m in GetMobilesInRange( 0 ) )
|
||||
{
|
||||
BaseCreature bc = m as BaseCreature;
|
||||
|
||||
if( m.Alive && !m.IsDeadBondedPet && (bc == null || bc.Controlled || bc.Summoned) )
|
||||
{
|
||||
toDamage.Add( m );
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < toDamage.Count; i++ )
|
||||
Damage( toDamage[i] );
|
||||
}
|
||||
}
|
||||
public override bool OnMoveOver( Mobile m )
|
||||
{
|
||||
Damage( m );
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Damage ( Mobile m )
|
||||
{
|
||||
m.Damage( Utility.RandomMinMax( m_MinDamage, m_MaxDamage ) );
|
||||
}
|
||||
|
||||
public PoolOfAcid( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
//Don't serialize these
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
93
Scripts/Items/Misc/Scales.cs
Normal file
93
Scripts/Items/Misc/Scales.cs
Normal 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
185
Scripts/Items/Misc/SpecialBeardDye.cs
Normal file
185
Scripts/Items/Misc/SpecialBeardDye.cs
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SpecialBeardDye : Item
|
||||
{
|
||||
public override int LabelNumber{ get{ return 1041087; } } // Special Beard Dye
|
||||
|
||||
[Constructable]
|
||||
public SpecialBeardDye() : base( 0xE26 )
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public SpecialBeardDye( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( from.InRange( this.GetWorldLocation(), 1 ) )
|
||||
{
|
||||
from.CloseGump( typeof( SpecialBeardDyeGump ) );
|
||||
from.SendGump( new SpecialBeardDyeGump( this ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 906, 1019045 ); // I can't reach that.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SpecialBeardDyeGump : Gump
|
||||
{
|
||||
private SpecialBeardDye m_SpecialBeardDye;
|
||||
|
||||
private class SpecialBeardDyeEntry
|
||||
{
|
||||
private string m_Name;
|
||||
private int m_HueStart;
|
||||
private int m_HueCount;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
}
|
||||
|
||||
public int HueStart
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HueStart;
|
||||
}
|
||||
}
|
||||
|
||||
public int HueCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HueCount;
|
||||
}
|
||||
}
|
||||
|
||||
public SpecialBeardDyeEntry( string name, int hueStart, int hueCount )
|
||||
{
|
||||
m_Name = name;
|
||||
m_HueStart = hueStart;
|
||||
m_HueCount = hueCount;
|
||||
}
|
||||
}
|
||||
|
||||
private static SpecialBeardDyeEntry[] m_Entries = new SpecialBeardDyeEntry[]
|
||||
{
|
||||
new SpecialBeardDyeEntry( "*****", 12, 10 ),
|
||||
new SpecialBeardDyeEntry( "*****", 32, 5 ),
|
||||
new SpecialBeardDyeEntry( "*****", 38, 8 ),
|
||||
new SpecialBeardDyeEntry( "*****", 54, 3 ),
|
||||
new SpecialBeardDyeEntry( "*****", 62, 10 ),
|
||||
new SpecialBeardDyeEntry( "*****", 81, 2 ),
|
||||
new SpecialBeardDyeEntry( "*****", 89, 2 ),
|
||||
new SpecialBeardDyeEntry( "*****", 1153, 2 )
|
||||
};
|
||||
|
||||
public SpecialBeardDyeGump( SpecialBeardDye dye ) : base( 0, 0 )
|
||||
{
|
||||
m_SpecialBeardDye = dye;
|
||||
|
||||
AddPage( 0 );
|
||||
AddBackground( 150, 60, 350, 358, 2600 );
|
||||
AddBackground( 170, 104, 110, 270, 5100 );
|
||||
AddHtmlLocalized( 230, 75, 200, 20, 1011013, false, false ); // Hair Color Selection Menu
|
||||
AddHtmlLocalized( 235, 380, 300, 20, 1013007, false, false ); // Dye my beard this color!
|
||||
AddButton( 200, 380, 0xFA5, 0xFA7, 1, GumpButtonType.Reply, 0 ); // DYE HAIR
|
||||
|
||||
for ( int i = 0; i < m_Entries.Length; ++i )
|
||||
{
|
||||
AddLabel( 180, 109 + (i * 22), m_Entries[i].HueStart - 1, m_Entries[i].Name );
|
||||
AddButton( 257, 110 + (i * 22), 5224, 5224, 0, GumpButtonType.Page, i + 1 );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < m_Entries.Length; ++i )
|
||||
{
|
||||
SpecialBeardDyeEntry e = m_Entries[i];
|
||||
|
||||
AddPage( i + 1 );
|
||||
|
||||
for ( int j = 0; j < e.HueCount; ++j )
|
||||
{
|
||||
AddLabel( 328 + ((j / 16) * 80), 102 + ((j % 16) * 17), e.HueStart + j - 1, "*****" );
|
||||
AddRadio( 310 + ((j / 16) * 80), 102 + ((j % 16) * 17), 210, 211, false, (i * 100) + j );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState from, RelayInfo info )
|
||||
{
|
||||
if ( m_SpecialBeardDye.Deleted )
|
||||
return;
|
||||
|
||||
Mobile m = from.Mobile;
|
||||
int[] switches = info.Switches;
|
||||
|
||||
if ( !m_SpecialBeardDye.IsChildOf( m.Backpack ) )
|
||||
{
|
||||
m.SendLocalizedMessage( 1042010 ); //You must have the objectin your backpack to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if ( info.ButtonID != 0 && switches.Length > 0 )
|
||||
{
|
||||
if( m.FacialHairItemID == 0 )
|
||||
{
|
||||
m.SendLocalizedMessage( 502623 ); // You have no hair to dye and cannot use this
|
||||
}
|
||||
else
|
||||
{
|
||||
// To prevent this from being exploited, the hue is abstracted into an internal list
|
||||
|
||||
int entryIndex = switches[0] / 100;
|
||||
int hueOffset = switches[0] % 100;
|
||||
|
||||
if ( entryIndex >= 0 && entryIndex < m_Entries.Length )
|
||||
{
|
||||
SpecialBeardDyeEntry e = m_Entries[entryIndex];
|
||||
|
||||
if ( hueOffset >= 0 && hueOffset < e.HueCount )
|
||||
{
|
||||
int hue = e.HueStart + hueOffset;
|
||||
|
||||
m.FacialHairHue = hue;
|
||||
|
||||
m.SendLocalizedMessage( 501199 ); // You dye your hair
|
||||
m_SpecialBeardDye.Delete();
|
||||
m.PlaySound( 0x4E );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendLocalizedMessage( 501200 ); // You decide not to dye your hair
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
190
Scripts/Items/Misc/SpecialHairDye.cs
Normal file
190
Scripts/Items/Misc/SpecialHairDye.cs
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SpecialHairDye : Item
|
||||
{
|
||||
public override string DefaultName
|
||||
{
|
||||
get { return "Special Hair Dye"; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public SpecialHairDye() : base( 0xE26 )
|
||||
{
|
||||
Weight = 1.0;
|
||||
}
|
||||
|
||||
public SpecialHairDye( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( from.InRange( this.GetWorldLocation(), 1 ) )
|
||||
{
|
||||
from.CloseGump( typeof( SpecialHairDyeGump ) );
|
||||
from.SendGump( new SpecialHairDyeGump( this ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
from.LocalOverheadMessage( MessageType.Regular, 906, 1019045 ); // I can't reach that.
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class SpecialHairDyeGump : Gump
|
||||
{
|
||||
private SpecialHairDye m_SpecialHairDye;
|
||||
|
||||
private class SpecialHairDyeEntry
|
||||
{
|
||||
private string m_Name;
|
||||
private int m_HueStart;
|
||||
private int m_HueCount;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_Name;
|
||||
}
|
||||
}
|
||||
|
||||
public int HueStart
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HueStart;
|
||||
}
|
||||
}
|
||||
|
||||
public int HueCount
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_HueCount;
|
||||
}
|
||||
}
|
||||
|
||||
public SpecialHairDyeEntry( string name, int hueStart, int hueCount )
|
||||
{
|
||||
m_Name = name;
|
||||
m_HueStart = hueStart;
|
||||
m_HueCount = hueCount;
|
||||
}
|
||||
}
|
||||
|
||||
private static SpecialHairDyeEntry[] m_Entries = new SpecialHairDyeEntry[]
|
||||
{
|
||||
new SpecialHairDyeEntry( "*****", 12, 10 ),
|
||||
new SpecialHairDyeEntry( "*****", 32, 5 ),
|
||||
new SpecialHairDyeEntry( "*****", 38, 8 ),
|
||||
new SpecialHairDyeEntry( "*****", 54, 3 ),
|
||||
new SpecialHairDyeEntry( "*****", 62, 10 ),
|
||||
new SpecialHairDyeEntry( "*****", 81, 2 ),
|
||||
new SpecialHairDyeEntry( "*****", 89, 2 ),
|
||||
new SpecialHairDyeEntry( "*****", 1153, 2 )
|
||||
};
|
||||
|
||||
public SpecialHairDyeGump( SpecialHairDye dye ) : base( 0, 0 )
|
||||
{
|
||||
m_SpecialHairDye = dye;
|
||||
|
||||
AddPage( 0 );
|
||||
AddBackground( 150, 60, 350, 358, 2600 );
|
||||
AddBackground( 170, 104, 110, 270, 5100 );
|
||||
AddHtmlLocalized( 230, 75, 200, 20, 1011013, false, false ); // Hair Color Selection Menu
|
||||
AddHtmlLocalized( 235, 380, 300, 20, 1011014, false, false ); // Dye my hair this color!
|
||||
AddButton( 200, 380, 0xFA5, 0xFA7, 1, GumpButtonType.Reply, 0 ); // DYE HAIR
|
||||
|
||||
for ( int i = 0; i < m_Entries.Length; ++i )
|
||||
{
|
||||
AddLabel( 180, 109 + (i * 22), m_Entries[i].HueStart - 1, m_Entries[i].Name );
|
||||
AddButton( 257, 110 + (i * 22), 5224, 5224, 0, GumpButtonType.Page, i + 1 );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < m_Entries.Length; ++i )
|
||||
{
|
||||
SpecialHairDyeEntry e = m_Entries[i];
|
||||
|
||||
AddPage( i + 1 );
|
||||
|
||||
for ( int j = 0; j < e.HueCount; ++j )
|
||||
{
|
||||
AddLabel( 328 + ((j / 16) * 80), 102 + ((j % 16) * 17), e.HueStart + j - 1, "*****" );
|
||||
AddRadio( 310 + ((j / 16) * 80), 102 + ((j % 16) * 17), 210, 211, false, (i * 100) + j );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse( NetState from, RelayInfo info )
|
||||
{
|
||||
if ( m_SpecialHairDye.Deleted )
|
||||
return;
|
||||
|
||||
Mobile m = from.Mobile;
|
||||
int[] switches = info.Switches;
|
||||
|
||||
if ( !m_SpecialHairDye.IsChildOf( m.Backpack ) )
|
||||
{
|
||||
m.SendLocalizedMessage( 1042010 ); //You must have the objectin your backpack to use it.
|
||||
return;
|
||||
}
|
||||
|
||||
if ( info.ButtonID != 0 && switches.Length > 0 )
|
||||
{
|
||||
if( m.HairItemID == 0 )
|
||||
{
|
||||
m.SendLocalizedMessage( 502623 ); // You have no hair to dye and cannot use this
|
||||
}
|
||||
else
|
||||
{
|
||||
// To prevent this from being exploited, the hue is abstracted into an internal list
|
||||
|
||||
int entryIndex = switches[0] / 100;
|
||||
int hueOffset = switches[0] % 100;
|
||||
|
||||
if ( entryIndex >= 0 && entryIndex < m_Entries.Length )
|
||||
{
|
||||
SpecialHairDyeEntry e = m_Entries[entryIndex];
|
||||
|
||||
if ( hueOffset >= 0 && hueOffset < e.HueCount )
|
||||
{
|
||||
m_SpecialHairDye.Delete();
|
||||
|
||||
int hue = e.HueStart + hueOffset;
|
||||
|
||||
m.HairHue = hue;
|
||||
|
||||
m.SendLocalizedMessage( 501199 ); // You dye your hair
|
||||
m.PlaySound( 0x4E );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m.SendLocalizedMessage( 501200 ); // You decide not to dye your hair
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
98
Scripts/Items/Misc/Static.cs
Normal file
98
Scripts/Items/Misc/Static.cs
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
using System;
|
||||
using Server;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Static : Item
|
||||
{
|
||||
public Static() : base( 0x80 )
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Static( int itemID ) : base( itemID )
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Static( int itemID, int count ) : this( Utility.Random( itemID, count ) )
|
||||
{
|
||||
}
|
||||
|
||||
public Static( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 1 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if ( version == 0 && Weight == 0 )
|
||||
Weight = -1;
|
||||
}
|
||||
}
|
||||
|
||||
public class LocalizedStatic : Static
|
||||
{
|
||||
private int m_LabelNumber;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Number
|
||||
{
|
||||
get{ return m_LabelNumber; }
|
||||
set{ m_LabelNumber = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
public override int LabelNumber{ get{ return m_LabelNumber; } }
|
||||
|
||||
[Constructable]
|
||||
public LocalizedStatic( int itemID ) : this( itemID, itemID < 0x4000 ? 1020000 + itemID : 1078872 + itemID )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public LocalizedStatic( int itemID, int labelNumber ) : base( itemID )
|
||||
{
|
||||
m_LabelNumber = labelNumber;
|
||||
}
|
||||
|
||||
public LocalizedStatic( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (byte) 0 ); // version
|
||||
writer.WriteEncodedInt( (int) m_LabelNumber );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadByte();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_LabelNumber = reader.ReadEncodedInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
517
Scripts/Items/Misc/Teleporter.cs
Normal file
517
Scripts/Items/Misc/Teleporter.cs
Normal file
|
|
@ -0,0 +1,517 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Spells;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class Teleporter : Item
|
||||
{
|
||||
private bool m_Active, m_Creatures, m_CombatCheck;
|
||||
private Point3D m_PointDest;
|
||||
private Map m_MapDest;
|
||||
private bool m_SourceEffect;
|
||||
private bool m_DestEffect;
|
||||
private int m_SoundID;
|
||||
private TimeSpan m_Delay;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool SourceEffect
|
||||
{
|
||||
get{ return m_SourceEffect; }
|
||||
set{ m_SourceEffect = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool DestEffect
|
||||
{
|
||||
get{ return m_DestEffect; }
|
||||
set{ m_DestEffect = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int SoundID
|
||||
{
|
||||
get{ return m_SoundID; }
|
||||
set{ m_SoundID = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan Delay
|
||||
{
|
||||
get{ return m_Delay; }
|
||||
set{ m_Delay = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool Active
|
||||
{
|
||||
get { return m_Active; }
|
||||
set { m_Active = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Point3D PointDest
|
||||
{
|
||||
get { return m_PointDest; }
|
||||
set { m_PointDest = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public Map MapDest
|
||||
{
|
||||
get { return m_MapDest; }
|
||||
set { m_MapDest = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool Creatures
|
||||
{
|
||||
get { return m_Creatures; }
|
||||
set { m_Creatures = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public bool CombatCheck
|
||||
{
|
||||
get { return m_CombatCheck; }
|
||||
set { m_CombatCheck = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
public override int LabelNumber{ get{ return 1026095; } } // teleporter
|
||||
|
||||
[Constructable]
|
||||
public Teleporter() : this( new Point3D( 0, 0, 0 ), null, false )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Teleporter( Point3D pointDest, Map mapDest ) : this( pointDest, mapDest, false )
|
||||
{
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public Teleporter( Point3D pointDest, Map mapDest, bool creatures ) : base( 0x1BC3 )
|
||||
{
|
||||
Movable = false;
|
||||
Visible = false;
|
||||
|
||||
m_Active = true;
|
||||
m_PointDest = pointDest;
|
||||
m_MapDest = mapDest;
|
||||
m_Creatures = creatures;
|
||||
|
||||
m_CombatCheck = false;
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
if ( m_Active )
|
||||
list.Add( 1060742 ); // active
|
||||
else
|
||||
list.Add( 1060743 ); // inactive
|
||||
|
||||
if ( m_MapDest != null )
|
||||
list.Add( 1060658, "Map\t{0}", m_MapDest );
|
||||
|
||||
if ( m_PointDest != Point3D.Zero )
|
||||
list.Add( 1060659, "Coords\t{0}", m_PointDest );
|
||||
|
||||
list.Add( 1060660, "Creatures\t{0}", m_Creatures ? "Yes" : "No" );
|
||||
}
|
||||
|
||||
public override void OnSingleClick( Mobile from )
|
||||
{
|
||||
base.OnSingleClick( from );
|
||||
|
||||
if ( m_Active )
|
||||
{
|
||||
if ( m_MapDest != null && m_PointDest != Point3D.Zero )
|
||||
LabelTo( from, "{0} [{1}]", m_PointDest, m_MapDest );
|
||||
else if ( m_MapDest != null )
|
||||
LabelTo( from, "[{0}]", m_MapDest );
|
||||
else if ( m_PointDest != Point3D.Zero )
|
||||
LabelTo( from, m_PointDest.ToString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
LabelTo( from, "(inactive)" );
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void StartTeleport( Mobile m )
|
||||
{
|
||||
if ( m_Delay == TimeSpan.Zero )
|
||||
DoTeleport( m );
|
||||
else
|
||||
Timer.DelayCall( m_Delay, new TimerStateCallback( DoTeleport_Callback ), m );
|
||||
}
|
||||
|
||||
private void DoTeleport_Callback( object state )
|
||||
{
|
||||
DoTeleport( (Mobile) state );
|
||||
}
|
||||
|
||||
public virtual void DoTeleport( Mobile m )
|
||||
{
|
||||
Map map = m_MapDest;
|
||||
|
||||
if ( map == null || map == Map.Internal )
|
||||
map = m.Map;
|
||||
|
||||
Point3D p = m_PointDest;
|
||||
|
||||
if ( p == Point3D.Zero )
|
||||
p = m.Location;
|
||||
|
||||
Server.Mobiles.BaseCreature.TeleportPets( m, p, map );
|
||||
|
||||
bool sendEffect = ( !m.Hidden || m.AccessLevel == AccessLevel.Player );
|
||||
|
||||
if ( m_SourceEffect && sendEffect )
|
||||
Effects.SendLocationEffect( m.Location, m.Map, 0x3728, 10, 10 );
|
||||
|
||||
m.MoveToWorld( p, map );
|
||||
|
||||
if ( m_DestEffect && sendEffect )
|
||||
Effects.SendLocationEffect( m.Location, m.Map, 0x3728, 10, 10 );
|
||||
|
||||
if ( m_SoundID > 0 && sendEffect )
|
||||
Effects.PlaySound( m.Location, m.Map, m_SoundID );
|
||||
}
|
||||
|
||||
public override bool OnMoveOver( Mobile m )
|
||||
{
|
||||
if ( m_Active )
|
||||
{
|
||||
if ( !m_Creatures && !m.Player )
|
||||
return true;
|
||||
else if ( m_CombatCheck && SpellHelper.CheckCombat( m ) )
|
||||
{
|
||||
m.SendLocalizedMessage( 1005564, "", 0x22 ); // Wouldst thou flee during the heat of battle??
|
||||
return true;
|
||||
}
|
||||
|
||||
StartTeleport( m );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public Teleporter( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 3 ); // version
|
||||
|
||||
writer.Write( (bool) m_CombatCheck );
|
||||
|
||||
writer.Write( (bool) m_SourceEffect );
|
||||
writer.Write( (bool) m_DestEffect );
|
||||
writer.Write( (TimeSpan) m_Delay );
|
||||
writer.WriteEncodedInt( (int) m_SoundID );
|
||||
|
||||
writer.Write( m_Creatures );
|
||||
|
||||
writer.Write( m_Active );
|
||||
writer.Write( m_PointDest );
|
||||
writer.Write( m_MapDest );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 3:
|
||||
{
|
||||
m_CombatCheck = reader.ReadBool();
|
||||
goto case 2;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
m_SourceEffect = reader.ReadBool();
|
||||
m_DestEffect = reader.ReadBool();
|
||||
m_Delay = reader.ReadTimeSpan();
|
||||
m_SoundID = reader.ReadEncodedInt();
|
||||
|
||||
goto case 1;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
m_Creatures = reader.ReadBool();
|
||||
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
m_Active = reader.ReadBool();
|
||||
m_PointDest = reader.ReadPoint3D();
|
||||
m_MapDest = reader.ReadMap();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SkillTeleporter : Teleporter
|
||||
{
|
||||
private SkillName m_Skill;
|
||||
private double m_Required;
|
||||
private string m_MessageString;
|
||||
private int m_MessageNumber;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public SkillName Skill
|
||||
{
|
||||
get{ return m_Skill; }
|
||||
set{ m_Skill = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public double Required
|
||||
{
|
||||
get{ return m_Required; }
|
||||
set{ m_Required = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string MessageString
|
||||
{
|
||||
get{ return m_MessageString; }
|
||||
set{ m_MessageString = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int MessageNumber
|
||||
{
|
||||
get{ return m_MessageNumber; }
|
||||
set{ m_MessageNumber = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
private void EndMessageLock( object state )
|
||||
{
|
||||
((Mobile)state).EndAction( this );
|
||||
}
|
||||
|
||||
public override bool OnMoveOver( Mobile m )
|
||||
{
|
||||
if ( Active )
|
||||
{
|
||||
if ( !Creatures && !m.Player )
|
||||
return true;
|
||||
|
||||
Skill sk = m.Skills[m_Skill];
|
||||
|
||||
if ( sk == null || sk.Base < m_Required )
|
||||
{
|
||||
if ( m.BeginAction( this ) )
|
||||
{
|
||||
if ( m_MessageString != null )
|
||||
m.Send( new UnicodeMessage( Serial, ItemID, MessageType.Regular, 0x3B2, 3, "ENU", null, m_MessageString ) );
|
||||
else if ( m_MessageNumber != 0 )
|
||||
m.Send( new MessageLocalized( Serial, ItemID, MessageType.Regular, 0x3B2, 3, m_MessageNumber, null, "" ) );
|
||||
|
||||
Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), new TimerStateCallback( EndMessageLock ), m );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
StartTeleport( m );
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
int skillIndex = (int)m_Skill;
|
||||
string skillName;
|
||||
|
||||
if ( skillIndex >= 0 && skillIndex < SkillInfo.Table.Length )
|
||||
skillName = SkillInfo.Table[skillIndex].Name;
|
||||
else
|
||||
skillName = "(Invalid)";
|
||||
|
||||
list.Add( 1060661, "{0}\t{1:F1}", skillName, m_Required );
|
||||
|
||||
if ( m_MessageString != null )
|
||||
list.Add( 1060662, "Message\t{0}", m_MessageString );
|
||||
else if ( m_MessageNumber != 0 )
|
||||
list.Add( 1060662, "Message\t#{0}", m_MessageNumber );
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public SkillTeleporter()
|
||||
{
|
||||
}
|
||||
|
||||
public SkillTeleporter( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
|
||||
writer.Write( (int) m_Skill );
|
||||
writer.Write( (double) m_Required );
|
||||
writer.Write( (string) m_MessageString );
|
||||
writer.Write( (int) m_MessageNumber );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Skill = (SkillName)reader.ReadInt();
|
||||
m_Required = reader.ReadDouble();
|
||||
m_MessageString = reader.ReadString();
|
||||
m_MessageNumber = reader.ReadInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class KeywordTeleporter : Teleporter
|
||||
{
|
||||
private string m_Substring;
|
||||
private int m_Keyword;
|
||||
private int m_Range;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string Substring
|
||||
{
|
||||
get{ return m_Substring; }
|
||||
set{ m_Substring = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Keyword
|
||||
{
|
||||
get{ return m_Keyword; }
|
||||
set{ m_Keyword = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Range
|
||||
{
|
||||
get{ return m_Range; }
|
||||
set{ m_Range = value; InvalidateProperties(); }
|
||||
}
|
||||
|
||||
public override bool HandlesOnSpeech{ get{ return true; } }
|
||||
|
||||
public override void OnSpeech( SpeechEventArgs e )
|
||||
{
|
||||
if ( !e.Handled && Active )
|
||||
{
|
||||
Mobile m = e.Mobile;
|
||||
|
||||
if ( !Creatures && !m.Player )
|
||||
return;
|
||||
|
||||
if ( !m.InRange( GetWorldLocation(), m_Range ) )
|
||||
return;
|
||||
|
||||
bool isMatch = false;
|
||||
|
||||
if ( m_Keyword >= 0 && e.HasKeyword( m_Keyword ) )
|
||||
isMatch = true;
|
||||
else if ( m_Substring != null && e.Speech.ToLower().IndexOf( m_Substring.ToLower() ) >= 0 )
|
||||
isMatch = true;
|
||||
|
||||
if ( !isMatch )
|
||||
return;
|
||||
|
||||
e.Handled = true;
|
||||
StartTeleport( m );
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnMoveOver( Mobile m )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void GetProperties( ObjectPropertyList list )
|
||||
{
|
||||
base.GetProperties( list );
|
||||
|
||||
list.Add( 1060661, "Range\t{0}", m_Range );
|
||||
|
||||
if ( m_Keyword >= 0 )
|
||||
list.Add( 1060662, "Keyword\t{0}", m_Keyword );
|
||||
|
||||
if ( m_Substring != null )
|
||||
list.Add( 1060663, "Substring\t{0}", m_Substring );
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public KeywordTeleporter()
|
||||
{
|
||||
m_Keyword = -1;
|
||||
m_Substring = null;
|
||||
}
|
||||
|
||||
public KeywordTeleporter( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
|
||||
writer.Write( m_Substring );
|
||||
writer.Write( m_Keyword );
|
||||
writer.Write( m_Range );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Substring = reader.ReadString();
|
||||
m_Keyword = reader.ReadInt();
|
||||
m_Range = reader.ReadInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
150
Scripts/Items/Misc/TrashBarrel.cs
Normal file
150
Scripts/Items/Misc/TrashBarrel.cs
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class TrashBarrel : Container, IChopable
|
||||
{
|
||||
public override int LabelNumber{ get{ return 1041064; } } // a trash barrel
|
||||
|
||||
public override int DefaultMaxWeight{ get{ return 0; } } // A value of 0 signals unlimited weight
|
||||
|
||||
public override bool IsDecoContainer
|
||||
{
|
||||
get{ return false; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public TrashBarrel() : base( 0xE77 )
|
||||
{
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public TrashBarrel( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if ( Items.Count > 0 )
|
||||
{
|
||||
m_Timer = new EmptyTimer( this );
|
||||
m_Timer.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnDragDrop( Mobile from, Item dropped )
|
||||
{
|
||||
if ( !base.OnDragDrop( from, dropped ) )
|
||||
return false;
|
||||
|
||||
if ( TotalItems >= 50 )
|
||||
{
|
||||
Empty( 501478 ); // The trash is full! Emptying!
|
||||
}
|
||||
else
|
||||
{
|
||||
SendLocalizedMessageTo( from, 1010442 ); // The item will be deleted in three minutes
|
||||
|
||||
if ( m_Timer != null )
|
||||
m_Timer.Stop();
|
||||
else
|
||||
m_Timer = new EmptyTimer( this );
|
||||
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnDragDropInto( Mobile from, Item item, Point3D p )
|
||||
{
|
||||
if ( !base.OnDragDropInto( from, item, p ) )
|
||||
return false;
|
||||
|
||||
if ( TotalItems >= 50 )
|
||||
{
|
||||
Empty( 501478 ); // The trash is full! Emptying!
|
||||
}
|
||||
else
|
||||
{
|
||||
SendLocalizedMessageTo( from, 1010442 ); // The item will be deleted in three minutes
|
||||
|
||||
if ( m_Timer != null )
|
||||
m_Timer.Stop();
|
||||
else
|
||||
m_Timer = new EmptyTimer( this );
|
||||
|
||||
m_Timer.Start();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void OnChop( Mobile from )
|
||||
{
|
||||
BaseHouse house = BaseHouse.FindHouseAt( from );
|
||||
|
||||
if ( house != null && house.IsCoOwner( from ) )
|
||||
{
|
||||
Effects.PlaySound( Location, Map, 0x3B3 );
|
||||
from.SendLocalizedMessage( 500461 ); // You destroy the item.
|
||||
Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
public void Empty( int message )
|
||||
{
|
||||
List<Item> items = this.Items;
|
||||
|
||||
if ( items.Count > 0 )
|
||||
{
|
||||
PublicOverheadMessage( Network.MessageType.Regular, 0x3B2, message, "" );
|
||||
|
||||
for ( int i = items.Count - 1; i >= 0; --i )
|
||||
{
|
||||
if ( i >= items.Count )
|
||||
continue;
|
||||
|
||||
items[i].Delete();
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_Timer != null )
|
||||
m_Timer.Stop();
|
||||
|
||||
m_Timer = null;
|
||||
}
|
||||
|
||||
private Timer m_Timer;
|
||||
|
||||
private class EmptyTimer : Timer
|
||||
{
|
||||
private TrashBarrel m_Barrel;
|
||||
|
||||
public EmptyTimer( TrashBarrel barrel ) : base( TimeSpan.FromMinutes( 3.0 ) )
|
||||
{
|
||||
m_Barrel = barrel;
|
||||
Priority = TimerPriority.FiveSeconds;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Barrel.Empty( 501479 ); // Emptying the trashcan!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
242
Scripts/Items/Misc/WarningItem.cs
Normal file
242
Scripts/Items/Misc/WarningItem.cs
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class WarningItem : Item
|
||||
{
|
||||
private string m_WarningString;
|
||||
private int m_WarningNumber;
|
||||
private int m_Range;
|
||||
private TimeSpan m_ResetDelay;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string WarningString
|
||||
{
|
||||
get{ return m_WarningString; }
|
||||
set{ m_WarningString = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int WarningNumber
|
||||
{
|
||||
get{ return m_WarningNumber; }
|
||||
set{ m_WarningNumber = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int Range
|
||||
{
|
||||
get{ return m_Range; }
|
||||
set{ if ( value > 18 ) value = 18; m_Range = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public TimeSpan ResetDelay
|
||||
{
|
||||
get{ return m_ResetDelay; }
|
||||
set{ m_ResetDelay = value; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public WarningItem( int itemID, int range, int warning ) : base( itemID )
|
||||
{
|
||||
if ( range > 18 )
|
||||
range = 18;
|
||||
|
||||
Movable = false;
|
||||
|
||||
m_WarningNumber = warning;
|
||||
m_Range = range;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public WarningItem( int itemID, int range, string warning ) : base( itemID )
|
||||
{
|
||||
if ( range > 18 )
|
||||
range = 18;
|
||||
|
||||
Movable = false;
|
||||
|
||||
m_WarningString = warning;
|
||||
m_Range = range;
|
||||
}
|
||||
|
||||
public WarningItem( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
private bool m_Broadcasting;
|
||||
|
||||
private DateTime m_LastBroadcast;
|
||||
|
||||
public virtual void SendMessage( Mobile triggerer, bool onlyToTriggerer, string messageString, int messageNumber )
|
||||
{
|
||||
if ( onlyToTriggerer )
|
||||
{
|
||||
if ( messageString != null )
|
||||
triggerer.SendMessage( messageString );
|
||||
else
|
||||
triggerer.SendLocalizedMessage( messageNumber );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( messageString != null )
|
||||
PublicOverheadMessage( MessageType.Regular, 0x3B2, false, messageString );
|
||||
else
|
||||
PublicOverheadMessage( MessageType.Regular, 0x3B2, messageNumber );
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool OnlyToTriggerer{ get{ return false; } }
|
||||
public virtual int NeighborRange { get { return 5; } }
|
||||
|
||||
public virtual void Broadcast( Mobile triggerer )
|
||||
{
|
||||
if ( m_Broadcasting || (DateTime.Now < (m_LastBroadcast + m_ResetDelay)) )
|
||||
return;
|
||||
|
||||
m_LastBroadcast = DateTime.Now;
|
||||
|
||||
m_Broadcasting = true;
|
||||
|
||||
SendMessage( triggerer, this.OnlyToTriggerer, m_WarningString, m_WarningNumber );
|
||||
|
||||
if ( NeighborRange >= 0 )
|
||||
{
|
||||
List<WarningItem> list = new List<WarningItem>();
|
||||
|
||||
foreach ( Item item in GetItemsInRange( NeighborRange ) )
|
||||
{
|
||||
if ( item != this && item is WarningItem )
|
||||
list.Add( (WarningItem)item );
|
||||
}
|
||||
|
||||
for ( int i = 0; i < list.Count; i++ )
|
||||
list[i].Broadcast( triggerer );
|
||||
}
|
||||
|
||||
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( InternalCallback ) );
|
||||
}
|
||||
|
||||
private void InternalCallback()
|
||||
{
|
||||
m_Broadcasting = false;
|
||||
}
|
||||
|
||||
public override bool HandlesOnMovement{ get{ return true; } }
|
||||
|
||||
public override void OnMovement( Mobile m, Point3D oldLocation )
|
||||
{
|
||||
if ( m.Player && Utility.InRange( m.Location, Location, m_Range ) && !Utility.InRange( oldLocation, Location, m_Range ) )
|
||||
Broadcast( m );
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
|
||||
writer.Write( (string) m_WarningString );
|
||||
writer.Write( (int) m_WarningNumber );
|
||||
writer.Write( (int) m_Range );
|
||||
|
||||
writer.Write( (TimeSpan) m_ResetDelay );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_WarningString = reader.ReadString();
|
||||
m_WarningNumber = reader.ReadInt();
|
||||
m_Range = reader.ReadInt();
|
||||
m_ResetDelay = reader.ReadTimeSpan();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class HintItem : WarningItem
|
||||
{
|
||||
private string m_HintString;
|
||||
private int m_HintNumber;
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public string HintString
|
||||
{
|
||||
get{ return m_HintString; }
|
||||
set{ m_HintString = value; }
|
||||
}
|
||||
|
||||
[CommandProperty( AccessLevel.GameMaster )]
|
||||
public int HintNumber
|
||||
{
|
||||
get{ return m_HintNumber; }
|
||||
set{ m_HintNumber = value; }
|
||||
}
|
||||
|
||||
public override bool OnlyToTriggerer{ get{ return true; } }
|
||||
|
||||
[Constructable]
|
||||
public HintItem( int itemID, int range, int warning, int hint ) : base( itemID, range, warning )
|
||||
{
|
||||
m_HintNumber = hint;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public HintItem( int itemID, int range, string warning, string hint ) : base( itemID, range, warning )
|
||||
{
|
||||
m_HintString = hint;
|
||||
}
|
||||
|
||||
public HintItem( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
SendMessage( from, true, m_HintString, m_HintNumber );
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 );
|
||||
|
||||
writer.Write( (string) m_HintString );
|
||||
writer.Write( (int) m_HintNumber );
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_HintString = reader.ReadString();
|
||||
m_HintNumber = reader.ReadInt();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
161
Scripts/Items/Misc/Waypoint.cs
Normal file
161
Scripts/Items/Misc/Waypoint.cs
Normal 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." );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue