469 lines
No EOL
9.1 KiB
C#
469 lines
No EOL
9.1 KiB
C#
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 );
|
|
}
|
|
}
|
|
}
|
|
} |