View Full Version: Porte-clef

RunUO.FR Support > Items > Porte-clef


Title: Porte-clef


Dorkiwan Scriptobi - July 26, 2004 11:11 AM (GMT)
CODE
// created on 01/06/2004 at 18:40
// by DorkiWan Scriptobi
// for UO Shard Hyel
// KeyRing v1.0

using System;
using System.Collections;
using Server;
using Server.ContextMenus;
using Server.Mobiles;
using Server.Prompts;
using Server.Targeting;

namespace Server.Items
{
public class DwsKeyRing : Item
{
 private string m_Description;
 private int m_MaxKeyNb;
 private string m_KeyRingName;
 
 private ArrayList m_KeyEntries;
 
 [CommandProperty ( AccessLevel.GameMaster ) ]
 public string Description
 {
  get{ return m_Description; }
  set{ m_Description = value; InvalidateProperties(); }
 }
 
 [CommandProperty ( AccessLevel.GameMaster ) ]
 public int MaxKeyNb
 {
  get{ return m_MaxKeyNb; }
  set{ m_MaxKeyNb = value; }
 }
 
 [CommandProperty ( AccessLevel.GameMaster ) ]
 public int CurrentKeyNb
 {
  get { return m_KeyEntries.Count; }
 }
 
 [CommandProperty( AccessLevel.GameMaster ) ]
 public string KeyRingName
 {
  get{ return m_KeyRingName; }
  set{ m_KeyRingName = value; InvalidateProperties(); }
 }

 public ArrayList KeyEntries
 {
  get{ return m_KeyEntries; }
 }
 
 [Constructable]
 public DwsKeyRing() : base ( 0x1011 )
 {
  Weight = 0.1;
  LootType = LootType.Blessed;
  m_MaxKeyNb = 20;
  m_KeyEntries = new ArrayList();
 }
 
 public override void GetProperties( ObjectPropertyList list )
 {
  base.GetProperties( list );
 
  string desc;
 
  if ( m_KeyEntries.Count == 0 )
  {
   desc = "Pas de clefs.";
  }
  else if ( m_KeyEntries.Count > 1 )
  {
   desc = m_KeyEntries.Count.ToString()+" clefs";
  }
  else
  {
   desc = "1 clef";
  }
  list.Add( desc );
 
  if ( m_KeyRingName != null && m_KeyRingName.Length > 0 )
   list.Add( m_KeyRingName );
 }
 
 public DwsKeyRing( Serial serial ) : base( serial )
 {
 }
 
 public override void Serialize( GenericWriter writer )
 {
  base.Serialize( writer );
 
  writer.Write( (int) 1 ); // version
 
  writer.WriteEncodedInt( (int) m_KeyEntries.Count );
 
  for ( int i = 0; i < m_KeyEntries.Count; ++i )
  {
   ((KeyRingEntry)m_KeyEntries[i]).Serialize( writer );
  }
 
  writer.Write( m_Description );
  writer.Write( m_MaxKeyNb );
  writer.Write( m_KeyRingName );
 }
 
 public override void Deserialize( GenericReader reader )
 {
  base.Deserialize( reader );
 
  int version = reader.ReadInt();
 
  switch ( version )
  {
   case 1:
   {
    int keycount = reader.ReadEncodedInt();
    m_KeyEntries = new ArrayList( keycount );
    for ( int i = 0; i < keycount; ++i )
    {
     m_KeyEntries.Add( new KeyRingEntry( reader ) );
    }
    goto case 0;
   }
   case 0:
   {
    m_Description = reader.ReadString();
    m_MaxKeyNb = reader.ReadInt();
    m_KeyRingName = reader.ReadString();
    break;
   }
  }
 }
 
 public override bool OnDragDrop( Mobile from, Item dropped )
 {
  if ( dropped is Key )
  {
   Key k = (Key)dropped;
   if( !IsChildOf( from.Backpack ) )
   {
    from.SendMessage( "Le porte-clef doit être dans votre sac à dos." );
    return false;
   }
   else if ( SearchForKey( k.KeyValue, m_KeyEntries ) )
   {
    from.SendMessage( "Cette clef est déjà sur votre porte-clef." );
    return false;
   }
   else if ( m_KeyEntries.Count < m_MaxKeyNb )
   {
    if ( k.KeyValue != 0 )
    {
     from.SendMessage( "Clef ajoutée au porte-clef." );
     m_KeyEntries.Add( new KeyRingEntry( k.Description, k.KeyValue, k.Link, k.MaxRange, k.ItemID, k.Hue ) );
     InvalidateProperties();
     this.ChangeKeyRingSkin( m_KeyEntries.Count );
     return true;
    }
    from.SendMessage( "Vous ne pouvez ajouter une clef vierge." );
    return false;
   }
   else
   {
    from.SendMessage( "La porte-clef est plein." );
    return false;
   }
  }
  from.SendMessage( "Ce n'est pas une clef." );
  return false;
 }
 
 public override void OnDoubleClick( Mobile from )
 {
  if ( !IsChildOf( from.Backpack ) )
  {
   from.SendMessage( "Le porte-clef doit être dans votre sac à dos pour être utilisé." );
  }
  else
  {
   from.SendMessage( "Target an Item..." );
   from.BeginTarget( 3, false, TargetFlags.None, new TargetCallback( OnTarget ) );
  }
 }
 
 public void OnTarget ( Mobile from, object obj )
 {
  if ( obj is Key )
  {
   Key k = (Key)obj;
   if ( !IsChildOf( from.Backpack ) )
   {
    from.SendMessage( "Le porte-clef doit être dans votre sac à dos pour être utilisé." );
   }
   else if ( k.KeyValue == 0 )
   {
    from.SendMessage( "Cette clef est vierge." );
   }
   else
   {
    if ( SearchForKey ( k.KeyValue, m_KeyEntries ) )
    {
     from.SendMessage( "Cette clef est déjà sur votre porte-clef." );
    }
    else if ( m_KeyEntries.Count < m_MaxKeyNb )
    {
     from.SendMessage( "Vous rajoutez cette clef à votre porte-clef." );
     m_KeyEntries.Add( new KeyRingEntry( k.Description, k.KeyValue, k.Link, k.MaxRange, k.ItemID, k.Hue ) );
     InvalidateProperties();
     k.Delete();
     
     this.ChangeKeyRingSkin( m_KeyEntries.Count );
    }
    else
    {
     from.SendMessage( "Votre porte-clef est plein." );
    }
   }
  }
  else if ( obj is ILockable )
  {
   ILockable ilock = (ILockable)obj;
   if ( m_KeyEntries.Count == 0 )
   {
    from.SendMessage( "Votre porte-clef est vide !" );
   }
   else if ( ilock is BaseDoor && !((BaseDoor)ilock).UseLocks() )
   {
    from.SendMessage( "Cette porte n'a pas de serrures." );
   }
   else if ( ilock.KeyValue == 0 )
   {
    from.SendMessage( "Il n'y a pas de serrures ici." );
   }
   else
   {
    ArrayList list = m_KeyEntries;
    if ( SearchForKey ( ilock.KeyValue, list ) )
    {
     from.SendMessage( "Vous utilisez une clef de votre porte-clef." );
     if ( ilock.Locked )
     {
      from.SendMessage( "Vous dévérouillez la serrure." );
     }
     else
     {
      from.SendMessage( "Vous vérouillez la serrure." );
     }
     ilock.Locked = !ilock.Locked;
    }
    else
    {
     from.SendMessage( "Aucune clef de votre porte-clef n'ouvre cette serrure." );
    }
   }
  }
  else if ( obj == this )
  {
   ArrayList list = m_KeyEntries;
   if ( m_KeyEntries.Count == 0 )
   {
    from.SendMessage( "Votre porte-clef est déjà vide !" );
   }
   else
   {
    while ( m_KeyEntries.Count != 0 )
    {
     int i = m_KeyEntries.Count - 1;
     KeyRingEntry k = (KeyRingEntry)list[i];
     this.DropKey( from, k, i );
    }
    this.ChangeKeyRingSkin( m_KeyEntries.Count );
   }
  }
  else
  {
   from.SendMessage( "Cet objet ne possède pas de serrure  !" );
  }
 }
 
 public bool SearchForKey ( uint keyval, ArrayList list )
 {
  for ( int i = 0; i < list.Count; ++i )
  {
   KeyRingEntry k = (KeyRingEntry)list[i];
   if ( k.KeyVal == keyval )
   {
    return true;
   }
  }
  return false;
 }
 
 public void DropKey( Mobile from, KeyRingEntry k, int index )
 {
  m_KeyEntries.RemoveAt( index );
 
  Key key = new Key();
  key.ItemID = k.KeyType;
  key.KeyValue = k.KeyVal;
  key.Link = k.KeyLink;
  key.Description = k.KeyDesc;
  key.MaxRange = k.KeyMaxRange;
  key.Hue = k.KeyHue;
 
  from.AddToBackpack( key );
 }
 
 public void ChangeKeyRingSkin ( int currentkeynb )
 {
  int maxk = this.MaxKeyNb;
  if ( currentkeynb == 0 )
  {
   this.ItemID = 0x1011;
  }
  else if ( currentkeynb < ( maxk / 2 ) )
  {
   this.ItemID = 0x1769;
  }
  else if ( currentkeynb < maxk )
  {
   this.ItemID = 0x176a;
  }
  else
  {
   this.ItemID = 0x176b;
  }
 }
 
 public override void GetContextMenuEntries( Mobile from, ArrayList list )
 {
  base.GetContextMenuEntries( from, list );
  if ( from.CheckAlive() && IsChildOf( from.Backpack ) )
   list.Add( new KeyRingNameEntry( from, this ) );
 }
 
 private class KeyRingNameEntry : ContextMenuEntry
 {
  private Mobile m_From;
  private DwsKeyRing m_KeyRing;
 
  public KeyRingNameEntry( Mobile from, DwsKeyRing keyring ) : base ( 6216 )
  {
   m_From = from;
   m_KeyRing = keyring;
  }
 
  public override void OnClick()
  {
   if ( m_From.CheckAlive() && m_KeyRing.IsChildOf( m_From.Backpack ) )
   {
    m_From.SendMessage( "Entrez un nouveau nom." );
    m_From.Prompt = new KeyRingNamePrompt( m_KeyRing );
   }
  }
 }
 
 private class KeyRingNamePrompt : Prompt
 {
  private DwsKeyRing m_KeyRing;
 
  public KeyRingNamePrompt( DwsKeyRing keyring )
  {
   m_KeyRing = keyring;
  }
 
  public override void OnResponse( Mobile from, string text )
  {
   if ( text.Length > 40 )
    text = text.Substring( 0, 40 );
   if ( from.CheckAlive() && m_KeyRing.IsChildOf( from.Backpack ) )
   {
    m_KeyRing.KeyRingName = text.Trim();
    from.SendMessage( "Le nom du porte-clef a été changé." );
   }
  }
 
  public override void OnCancel( Mobile from )
  {
  }
 }
}

public class KeyRingEntry
{
 private string m_KeyDesc;
 private uint m_KeyVal;
 private Item m_KeyLink;
 private int m_KeyMaxRange;
 
 private int m_KeyType;
 private int m_KeyHue;
 
 public string KeyDesc{ get{ return m_KeyDesc; } }
 public uint KeyVal{ get{ return m_KeyVal; } }
 public Item KeyLink{ get{ return m_KeyLink; } }
 public int KeyMaxRange{ get{ return m_KeyMaxRange; } }
 
 public int KeyType{ get{ return m_KeyType; } }
 public int KeyHue{ get{ return m_KeyHue;} }
 
 public KeyRingEntry( string desc, uint keyval, Item link, int maxrange, int type, int hue)
 {
  m_KeyDesc = desc;
  m_KeyVal = keyval;
  m_KeyLink = link;
  m_KeyMaxRange = maxrange;
 
  m_KeyType = type;
  m_KeyHue = hue;
 }
 
 public void Serialize( GenericWriter writer )
 {
  writer.WriteEncodedInt( 1 ); // version
 
  writer.Write( (int) m_KeyType );
  writer.Write( (int) m_KeyHue );
 
  writer.Write( (string) m_KeyDesc );
  writer.Write( (uint) m_KeyVal );
  writer.Write( (Item) m_KeyLink );
  writer.Write( (int) m_KeyMaxRange );
 }
 
 public KeyRingEntry( GenericReader reader )
 {
  int version = reader.ReadEncodedInt();
 
  switch ( version )
  {
   case 1:
   {
    m_KeyType = reader.ReadInt();
    m_KeyHue = reader.ReadInt();
    goto case 0;
   }
   case 0:
   {
    m_KeyDesc = reader.ReadString();
    m_KeyVal = reader.ReadUInt();
    m_KeyLink = reader.ReadItem();
    m_KeyMaxRange = reader.ReadInt();
    break;
   }
  }
 }
}
}

Utilisation identique à celui de Sphere :
-> DragDrop de clef sur le porte-clef
-> DClick porte-clef + Target porte ou container lockable -> ouvrir / fermer
-> DClick porte-clef + Target porte-clef -> restitution des clefs
-> SingleClick porte-clef -> Prompt description du porte-clef

Dorkiwan Scriptobi - July 26, 2004 11:16 AM (GMT)
Modification du BaseDoor.cs
CODE
 public virtual void Use( Mobile from )
 {
  if ( m_Locked && !m_Open && UseLocks() )
  {
   if ( from.AccessLevel >= AccessLevel.GameMaster )
   {
    from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 502502 ); // That is locked, but you open it with your godly powers.
    //from.Send( new MessageLocalized( Serial, ItemID, MessageType.Regular, 0x3B2, 3, 502502, "", "" ) ); // That is locked, but you open it with your godly powers.
   }
   else
   {
    Container pack = from.Backpack;
    bool found = false;
     
    if ( pack != null )
    {
     Item[] items = pack.FindItemsByType( typeof( Key ) );

     foreach( Key k in items )
     {
      if ( k.KeyValue == this.KeyValue )
      {
       found = true;
       from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 501282 ); // You quickly unlock, open, and relock the door
       break;
      }
     }
//* DwsKeyRing AddOn
     if ( !found )
     {
      Item[] items2 = pack.FindItemsByType( typeof ( DwsKeyRing ) );
      foreach( DwsKeyRing kr in items2 )
      {
       if ( kr.SearchForKey( this.KeyValue, kr.KeyEntries ) )
       {
        found = true;
        from.LocalOverheadMessage( MessageType.Regular, 0x3b2, 501282 );
        break;
       }
      }
     }
//  End of DwsKeyRing Addon
//*/
    }

    if ( !found && IsInside( from ) )
    {
     from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 501280 ); // That is locked, but is usable from the inside.
    }
    else if ( !found )
    {
     from.LocalOverheadMessage( MessageType.Regular, 0x3B2, 502503 ); // That is locked.
     //from.Send( new MessageLocalized( Serial, ItemID, MessageType.Regular, 0x3B2, 3, 502503, "", "" ) );
     return;
    }
   }
  }

  if ( m_Open && !IsFreeToClose() )
   return;

  if ( m_Open )
   OnClosed( from );
  else
   OnOpened( from );

  if ( UseChainedFunctionality )
  {
   bool open = !m_Open;

   ArrayList list = GetChain();

   for ( int i = 0; i < list.Count; ++i )
    ((BaseDoor)list[i]).Open = open;
  }
  else
  {
   Open = !m_Open;

   BaseDoor link = this.Link;

   if ( m_Open && link != null && !link.Open )
    link.Open = true;
  }
 }

slade15 - July 26, 2004 11:37 AM (GMT)
pourais tu expliquer en quelque mot ce que ce scripte fait?

Dorkiwan Scriptobi - July 26, 2004 12:45 PM (GMT)
De base, l'item stocke dans un ArrayList les props des clefs qui sont lui sont confiées.
Les props stockées sont :
- Props de Key
-> KeyType
-> KeyLink
-> KeyValue
-> Description
-> MaxRange

- Props de Key personalisées
-> Hue

On peut stocker les clefs de 2 façon :
-> en DragDrop une clef sur le porte-clef.
-> en DClick sur le porte-clef puis en Targettant une clef.

Le porte-clef a une capacité max de 20 clefs ( paramétrable >= GM ) et son skin change en fonction du nb de clefs stockées. Les doublon de clefs sont refusées ( comparaison KeyValue avec ArrayList ). Les clefs vierges sont refusées ( KeyValue == 0 )

La restitution des clefs se fait en DClick sur le porte-clef puis Target porte-clef.

Pour locker/delocker ( Locked = true/false ) une porte ou un container lockable ( ILocackable ) il suffit de DClick porte-clef puis Target le ILockable.

Pour ouvrir/fermer une porte il est obligatoire d'ajouter dans le BaseDoor.cs méthode ( fonction ) public virtual void Use( Mobile from ) le bout de code //* DwsKeyRing AddOn. Celui ci permet de scanner le sac du mobile à la recherche d'un ou plusieurs porte-clef et de chercher dans chaque porte-clef la 1ère clef correspondant au KeyValue de la porte.

Je pense que c tout là...
A suivre... ^_^

Injall - July 26, 2004 02:33 PM (GMT)
Sympathique :D

Didi - July 26, 2004 02:33 PM (GMT)
Jen avais fait un différent que jai un peu laisser dans loubli, javais pas penser au truc des portes.

Le truc qui manque pour que se soit comme sphere, c'est que les container s'ouvrent si ta la clef dans ton sac. C'est chiant délocker relocker chaque fois :P
Mais sa je suis capable de le faire :P

Injall - July 26, 2004 02:37 PM (GMT)
Hu oui c est sur mais est ce que même quand on a la clef sans qu elle soit sur un trousseau dans le sac ca le fait?

Didi - July 26, 2004 02:38 PM (GMT)
pour linstant si je me trompe pas la seule maniere douvrir un container locker c'est en le délockant avant, sa souvre pas si ta la clef dans ton sac.

Chose que jadore pas :P

Injall - July 26, 2004 02:41 PM (GMT)
Ouep, mais ca serais peut être faisable, vu que quand on rentre chez soit pas besoin de délocker : "promptement, vous ouvrez la porte et la reverrouillez derriere vous" ou un truc du genre :P

Dorkiwan Scriptobi - July 26, 2004 03:27 PM (GMT)
QUOTE (Didi @ Jul 26 2004, 03:38 PM)
pour linstant si je me trompe pas la seule maniere douvrir un container locker c'est en le délockant avant, sa souvre pas si ta la clef dans ton sac.

Chose que jadore pas :P

Pour que ça marche comme tu dis, il suffit juste de modifier le LockableContainer pour qu'il accepte les clefs dans le OnDoubleClick de la même façon que le BaseDoor...

Note sur les serrures :
Calcul des niveaux de sécurité des serrures :
Skill Tinkering * 0.8 => Base Level

Require Skill : Base Level - 4 => Max 95%
LockLevel : Base Level - 14 => Max 95%
MaxLockLevel : BaseLevel + 35 => Max 95%

Pour un GM Tinker (100%)
-> ReqSkill : 76%
-> LockLevel : 66%
-> MaxLockLevel : 95% ( 115% )

De ce fait, il apparait qu'un coffre avec serrure crafté par un Carpenter n'est pas inviolable...
Pour qu'une serrure soit inviolable mettre le LockLevel à 0 ou à -255 ( magique )

Note sur le spell MagicLock :
Il ne peut être casté que sur un container ILockable ayant un LockLevel != 0 et n'étant pas déja locké ( !Locked ).
Le LockLevel passe alors à -255 et le container ne peut être ouvert que par le caster.

Note sur le spell Unlock :
Il ne peut être casté que sur un container ILockable ayant un LockLevel != 0 et n'étant pas déja locké ( !Locked ).
Il agit exactement comme l'item LockPick avec la possibilité de délocker les serrures lockées par MagicLock avec un malus de 10% sur la skill Magery.
Le container forcé se retrouve avec un LockLevel = -1 ...

A suivre... ^_^

slade15 - July 26, 2004 03:50 PM (GMT)
ca a l'aire bien ce scripte , merci

Didi - July 26, 2004 04:23 PM (GMT)
QUOTE (Dorkiwan Scriptobi @ Jul 26 2004, 04:27 PM)
QUOTE (Didi @ Jul 26 2004, 03:38 PM)
pour linstant si je me trompe pas la seule maniere douvrir un container locker c'est en le délockant avant, sa souvre pas si ta la clef dans ton sac.

Chose que jadore pas :P

Pour que ça marche comme tu dis, il suffit juste de modifier le LockableContainer pour qu'il accepte les clefs dans le OnDoubleClick de la même façon que le BaseDoor...

Note sur les serrures :
Calcul des niveaux de sécurité des serrures :
Skill Tinkering * 0.8 => Base Level

Require Skill : Base Level - 4 => Max 95%
LockLevel : Base Level - 14 => Max 95%
MaxLockLevel : BaseLevel + 35 => Max 95%

Pour un GM Tinker (100%)
-> ReqSkill : 76%
-> LockLevel : 66%
-> MaxLockLevel : 95% ( 115% )

De ce fait, il apparait qu'un coffre avec serrure crafté par un Carpenter n'est pas inviolable...
Pour qu'une serrure soit inviolable mettre le LockLevel à 0 ou à -255 ( magique )

Note sur le spell MagicLock :
Il ne peut être casté que sur un container ILockable ayant un LockLevel != 0 et n'étant pas déja locké ( !Locked ).
Le LockLevel passe alors à -255 et le container ne peut être ouvert que par le caster.

Note sur le spell Unlock :
Il ne peut être casté que sur un container ILockable ayant un LockLevel != 0 et n'étant pas déja locké ( !Locked ).
Il agit exactement comme l'item LockPick avec la possibilité de délocker les serrures lockées par MagicLock avec un malus de 10% sur la skill Magery.
Le container forcé se retrouve avec un LockLevel = -1 ...

A suivre... ^_^

c'est de base sous run uo sa ?

Dorkiwan Scriptobi - July 26, 2004 04:24 PM (GMT)
CODE
 public virtual bool CheckLocked( Mobile from )
 {
  bool inaccessible = false;

  if ( m_Locked )
  {
   int number;

   if ( from.AccessLevel >= AccessLevel.GameMaster )
   {
    number = 502502; // That is locked, but you open it with your godly powers.
   }
   else
   {
    Container pack = from.Backpack;
    bool found = false;

    if ( pack != null )
    {
     Item[] items = pack.FindItemsByType( typeof( Key ) );

     foreach( Key k in items )
     {
      if ( k.KeyValue == this.KeyValue )
      {
       found = true;
       break;
      }
     }
     //* DwsKeyRing AddOn
     if ( !found )
     {
      Item[] items2 = pack.FindItemsByType( typeof ( DwsKeyRing ) );
      foreach( DwsKeyRing kr in items2 )
      {
       if ( kr.SearchForKey( this.KeyValue, kr.KeyEntries ) )
       {
        found = true;
        break;
       }
      }
     }
     //  End of DwsKeyRing Addon
     //*/
    }

    if ( !found )
    {
     number = 502503;
     inaccessible = true;
    }
   }
  }
  else
  {
   number = 502503; // That is locked.
   inaccessible = true;
  }

  return inaccessible;
 }


Modif à placer dans le LockableContainer.cs...
Permet d'ouvrir un container locké en ayant la clef en poche ou sur porte-clef ;)

Pas testé encore... :unsure:

Dorkiwan Scriptobi - July 26, 2004 04:33 PM (GMT)
100% RunUO :)

Injall - July 26, 2004 05:15 PM (GMT)
vraimment bien ca :D




Hosted for free by InvisionFree