BritainKnights/Scripts/Items/Treasure/TreasureMapChest.cs

426 lines
10 KiB
C#

using System;
using System.Collections.Generic;
using Server;
using Server.ContextMenus;
using Server.Engines.PartySystem;
using Server.Gumps;
using Server.Multis;
using Server.Network;
namespace Server.Items
{
public class TreasureMapChest : LockableContainer
{
public override int LabelNumber{ get{ return 3000541; } }
private int m_Level;
private DateTime m_DeleteTime;
private Timer m_Timer;
private Mobile m_Owner;
private bool m_Temporary;
private List<Mobile> m_Guardians;
[CommandProperty( AccessLevel.GameMaster )]
public int Level{ get{ return m_Level; } set{ m_Level = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public Mobile Owner{ get{ return m_Owner; } set{ m_Owner = value; } }
[CommandProperty( AccessLevel.GameMaster )]
public DateTime DeleteTime{ get{ return m_DeleteTime; } }
[CommandProperty( AccessLevel.GameMaster )]
public bool Temporary{ get{ return m_Temporary; } set{ m_Temporary = value; } }
public List<Mobile> Guardians { get { return m_Guardians; } }
[Constructable]
public TreasureMapChest( int level ) : this( null, level, false )
{
}
public TreasureMapChest( Mobile owner, int level, bool temporary ) : base( 0xE40 )
{
m_Owner = owner;
m_Level = level;
m_DeleteTime = DateTime.Now + TimeSpan.FromHours( 3.0 );
m_Temporary = temporary;
m_Guardians = new List<Mobile>();
m_Timer = new DeleteTimer( this, m_DeleteTime );
m_Timer.Start();
Fill( this, level );
}
public static void Fill( LockableContainer cont, int level )
{
cont.Movable = false;
cont.Locked = true;
int numberItems;
if ( level == 0 )
{
cont.LockLevel = 0; // Can't be unlocked
cont.DropItem( new Gold( Utility.RandomMinMax( 50, 100 ) ) );
if ( Utility.RandomDouble() < 0.75 )
cont.DropItem( new TreasureMap( 0, Map.Britannia ) );
}
else
{
cont.TrapType = TrapType.ExplosionTrap;
cont.TrapPower = level * 25;
cont.TrapLevel = level;
switch ( level )
{
case 1: cont.RequiredSkill = 36; break;
case 2: cont.RequiredSkill = 76; break;
case 3: cont.RequiredSkill = 84; break;
case 4: cont.RequiredSkill = 92; break;
case 5: cont.RequiredSkill = 100; break;
case 6: cont.RequiredSkill = 100; break;
}
cont.LockLevel = cont.RequiredSkill - 10;
cont.MaxLockLevel = cont.RequiredSkill + 40;
cont.DropItem( new Gold( level * 1000 ) );
for ( int i = 0; i < level * 5; ++i )
cont.DropItem( Loot.RandomScroll( 0, 63, SpellbookType.Regular ) );
numberItems = level * 6;
for ( int i = 0; i < numberItems; ++i )
{
Item item = Loot.RandomArmorOrShieldOrWeapon();
if ( item is BaseWeapon )
{
BaseWeapon weapon = (BaseWeapon)item;
weapon.DamageLevel = (WeaponDamageLevel)Utility.Random( 6 );
weapon.AccuracyLevel = (WeaponAccuracyLevel)Utility.Random( 6 );
weapon.DurabilityLevel = (WeaponDurabilityLevel)Utility.Random( 6 );
cont.DropItem( item );
}
else if ( item is BaseArmor )
{
BaseArmor armor = (BaseArmor)item;
armor.ProtectionLevel = (ArmorProtectionLevel)Utility.Random( 6 );
armor.Durability = (ArmorDurabilityLevel)Utility.Random( 6 );
cont.DropItem( item );
}
else
{
cont.DropItem( item );
}
}
}
int reagents;
if ( level == 0 )
reagents = 12;
else
reagents = level * 3;
for ( int i = 0; i < reagents; i++ )
{
Item item = Loot.RandomReagent();
item.Amount = Utility.RandomMinMax( 40, 60 );
cont.DropItem( item );
}
int gems;
if ( level == 0 )
gems = 2;
else
gems = level * 3;
for ( int i = 0; i < gems; i++ )
{
Item item = Loot.RandomGem();
cont.DropItem( item );
}
}
public override bool CheckLocked( Mobile from )
{
if ( !this.Locked )
return false;
if ( this.Level == 0 && from.AccessLevel < AccessLevel.GameMaster )
{
foreach ( Mobile m in this.Guardians )
{
if ( m.Alive )
{
from.SendLocalizedMessage( 1046448 ); // You must first kill the guardians before you may open this chest.
return true;
}
}
LockPick( from );
return false;
}
else
{
return base.CheckLocked( from );
}
}
private List<Item> m_Lifted = new List<Item>();
private bool CheckLoot( Mobile m, bool criminalAction )
{
if ( m_Temporary )
return false;
if ( m.AccessLevel >= AccessLevel.GameMaster || m_Owner == null || m == m_Owner )
return true;
Party p = Party.Get( m_Owner );
if ( p != null && p.Contains( m ) )
return true;
Map map = this.Map;
if ( map != null && (map.Rules & MapRules.HarmfulRestrictions) == 0 )
{
if ( criminalAction )
m.CriminalAction( true );
else
m.SendLocalizedMessage( 1010630 ); // Taking someone else's treasure is a criminal offense!
return true;
}
m.SendLocalizedMessage( 1010631 ); // You did not discover this chest!
return false;
}
public override bool IsDecoContainer
{
get{ return false; }
}
public override bool CheckItemUse( Mobile from, Item item )
{
return CheckLoot( from, item != this ) && base.CheckItemUse( from, item );
}
public override bool CheckLift( Mobile from, Item item, ref LRReason reject )
{
return CheckLoot( from, true ) && base.CheckLift( from, item, ref reject );
}
public override void OnItemLifted( Mobile from, Item item )
{
bool notYetLifted = !m_Lifted.Contains( item );
from.RevealingAction();
if ( notYetLifted )
{
m_Lifted.Add( item );
if ( 0.1 >= Utility.RandomDouble() ) // 10% chance to spawn a new monster
TreasureMap.Spawn( m_Level, GetWorldLocation(), Map, from, false );
}
base.OnItemLifted( from, item );
}
public override bool CheckHold( Mobile m, Item item, bool message, bool checkItems, int plusItems, int plusWeight )
{
if ( m.AccessLevel < AccessLevel.GameMaster )
{
m.SendLocalizedMessage( 1048122, "", 0x8A5 ); // The chest refuses to be filled with treasure again.
return false;
}
return base.CheckHold( m, item, message, checkItems, plusItems, plusWeight );
}
public TreasureMapChest( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 2 ); // version
writer.Write( m_Guardians, true );
writer.Write( (bool) m_Temporary );
writer.Write( m_Owner );
writer.Write( (int) m_Level );
writer.WriteDeltaTime( m_DeleteTime );
writer.Write( m_Lifted, true );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
switch ( version )
{
case 2:
{
m_Guardians = reader.ReadStrongMobileList();
m_Temporary = reader.ReadBool();
goto case 1;
}
case 1:
{
m_Owner = reader.ReadMobile();
goto case 0;
}
case 0:
{
m_Level = reader.ReadInt();
m_DeleteTime = reader.ReadDeltaTime();
m_Lifted = reader.ReadStrongItemList();
if ( version < 2 )
m_Guardians = new List<Mobile>();
break;
}
}
if ( !m_Temporary )
{
m_Timer = new DeleteTimer( this, m_DeleteTime );
m_Timer.Start();
}
else
{
Delete();
}
}
public override void OnAfterDelete()
{
if ( m_Timer != null )
m_Timer.Stop();
m_Timer = null;
base.OnAfterDelete();
}
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
{
base.GetContextMenuEntries( from, list );
if ( from.Alive )
list.Add( new RemoveEntry( from, this ) );
}
public void BeginRemove( Mobile from )
{
if ( !from.Alive )
return;
from.CloseGump( typeof( RemoveGump ) );
from.SendGump( new RemoveGump( from, this ) );
}
public void EndRemove( Mobile from )
{
if ( Deleted || from != m_Owner || !from.InRange( GetWorldLocation(), 3 ) )
return;
from.SendLocalizedMessage( 1048124, "", 0x8A5 ); // The old, rusted chest crumbles when you hit it.
this.Delete();
}
private class RemoveGump : Gump
{
private Mobile m_From;
private TreasureMapChest m_Chest;
public RemoveGump( Mobile from, TreasureMapChest chest ) : base( 15, 15 )
{
m_From = from;
m_Chest = chest;
Closable = false;
Disposable = false;
AddPage( 0 );
AddBackground( 30, 0, 240, 240, 2620 );
AddHtmlLocalized( 45, 15, 200, 80, 1048125, 0xFFFFFF, false, false ); // When this treasure chest is removed, any items still inside of it will be lost.
AddHtmlLocalized( 45, 95, 200, 60, 1048126, 0xFFFFFF, false, false ); // Are you certain you're ready to remove this chest?
AddButton( 40, 153, 4005, 4007, 1, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 75, 155, 180, 40, 1048127, 0xFFFFFF, false, false ); // Remove the Treasure Chest
AddButton( 40, 195, 4005, 4007, 2, GumpButtonType.Reply, 0 );
AddHtmlLocalized( 75, 197, 180, 35, 1006045, 0xFFFFFF, false, false ); // Cancel
}
public override void OnResponse( NetState sender, RelayInfo info )
{
if ( info.ButtonID == 1 )
m_Chest.EndRemove( m_From );
}
}
private class RemoveEntry : ContextMenuEntry
{
private Mobile m_From;
private TreasureMapChest m_Chest;
public RemoveEntry( Mobile from, TreasureMapChest chest ) : base( 6149, 3 )
{
m_From = from;
m_Chest = chest;
Enabled = ( from == chest.Owner );
}
public override void OnClick()
{
if ( m_Chest.Deleted || m_From != m_Chest.Owner || !m_From.CheckAlive() )
return;
m_Chest.BeginRemove( m_From );
}
}
private class DeleteTimer : Timer
{
private Item m_Item;
public DeleteTimer( Item item, DateTime time ) : base( time - DateTime.Now )
{
m_Item = item;
Priority = TimerPriority.OneMinute;
}
protected override void OnTick()
{
m_Item.Delete();
}
}
}
}