using System;
using Server;
using System.Collections;
using Server.Items;
using Server.ContextMenus;
using Server.Misc;
using Server.Mobiles;
using Server.Network;
namespace Server.Mobiles
{
public class BaseHire : BaseCreature
{
private int m_Pay = 1;
private bool m_IsHired;
private int m_HoldGold = 8;
private Timer m_PayTimer;
public BaseHire( AIType AI ): base( AI, FightMode.Agressor, 10, 1, 0.1, 4.0 )
{
}
public BaseHire(): base( AIType.AI_Melee, FightMode.Agressor, 10, 1, 0.1, 4.0 )
{
}
public BaseHire( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
writer.Write( (bool)m_IsHired );
writer.Write( (int)m_HoldGold );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_IsHired = reader.ReadBool();
m_HoldGold = reader.ReadInt();
m_PayTimer = new PayTimer( this );
m_PayTimer.Start();
}
private static Hashtable m_HireTable = new Hashtable();
public static Hashtable HireTable
{
get{ return m_HireTable; }
}
public override bool KeepsItemsOnDeath{ get{ return true; } }
private int m_GoldOnDeath = 0;
public override bool OnBeforeDeath()
{
// Stop the pay timer if its running
if( m_PayTimer != null )
m_PayTimer.Stop();
m_PayTimer = null;
// Get all of the gold on the hireling and add up the total amount
if( this.Backpack != null )
{
Item[] AllGold = this.Backpack.FindItemsByType( typeof(Gold), true );
if( AllGold != null )
{
foreach( Gold g in AllGold )
this.m_GoldOnDeath += g.Amount;
}
}
return base.OnBeforeDeath();
}
public override void OnDeath( Container c )
{
if( this.m_GoldOnDeath > 0 )
c.DropItem( new Gold( this.m_GoldOnDeath ) );
base.OnDeath( c );
}
[CommandProperty( AccessLevel.Administrator )]
public bool IsHired
{
get
{
return m_IsHired;
}
set
{
if ( m_IsHired== value )
return;
m_IsHired= value;
Delta( MobileDelta.Noto );
InvalidateProperties();
}
}
#region [ GetOwner ]
public virtual Mobile GetOwner()
{
if( !Controled )
return null;
Mobile Owner = ControlMaster;
m_IsHired = true;
if( Owner == null )
return null;
if( Owner.Deleted || Owner.Map != this.Map || !Owner.InRange( Location, 30 ) )
{
Say( 1005653 ); // Hmmm. I seem to have lost my master.
BaseHire.HireTable.Remove( Owner );
SetControlMaster( null );
return null;
}
return Owner;
}
#endregion
#region [ AddHire ]
public virtual bool AddHire( Mobile m )
{
Mobile owner = GetOwner();
if( owner != null )
{
m.SendLocalizedMessage( 1043283, owner.Name ); // I am following ~1_NAME~.
return false;
}
if( SetControlMaster( m ) )
{
m_IsHired = true;
return true;
}
return false;
}
#endregion
#region [ Payday ]
public virtual bool Payday( BaseHire m )
{
m_Pay = (int)m.Skills[SkillName.Anatomy].Value + (int)m.Skills[SkillName.Tactics].Value;
m_Pay += (int)m.Skills[SkillName.Macing].Value + (int)m.Skills[SkillName.Swords].Value;
m_Pay += (int)m.Skills[SkillName.Fencing].Value + (int)m.Skills[SkillName.Archery].Value;
m_Pay += (int)m.Skills[SkillName.MagicResist].Value + (int)m.Skills[SkillName.Healing].Value;
m_Pay += (int)m.Skills[SkillName.Magery].Value + (int)m.Skills[SkillName.Parry].Value;
m_Pay /= 35;
m_Pay += 1;
return true;
}
#endregion
#region [ OnDragDrop ]
public override bool OnDragDrop( Mobile from, Item item )
{
if( m_Pay != 0 )
{
// Is the creature already hired
if( Controled == false )
{
// Is the item the payment in gold
if( item is Gold )
{
// Is the payment in gold sufficient
if( item.Amount >= m_Pay )
{
// Check if this mobile already has a hire
BaseHire hire = (BaseHire)m_HireTable[from];
if( hire != null && !hire.Deleted && hire.GetOwner() == from )
{
SayTo( from, 500896 ); // I see you already have an escort.
return false;
}
// Try to add the hireling as a follower
if( AddHire(from) == true )
{
SayTo( from, 1043258, string.Format( "{0}", (int)item.Amount / m_Pay ) );//"I thank thee for paying me. I will work for thee for ~1_NUMBER~ days.", (int)item.Amount / m_Pay );
m_HireTable[from] = this;
m_HoldGold += item.Amount;
m_PayTimer = new PayTimer( this );
m_PayTimer.Start();
return true;
}
else
return false;
}
else
{
this.SayHireCost();
}
}
else
{
SayTo( from, 1043268 ); // Tis crass of me, but I want gold
}
}
else
{
Say( 1042495 );// I have already been hired.
}
}
else
{
SayTo( from, 500200 ); // I have no need for that.
}
return base.OnDragDrop( from, item );
}
#endregion
#region [ OnSpeech ]
internal void SayHireCost()
{
Say( 1043256, string.Format( "{0}", m_Pay ) ); // "I am available for hire for ~1_AMOUNT~ gold coins a day. If thou dost give me gold, I will work for thee."
}
public override void OnSpeech( SpeechEventArgs e )
{
if( !e.Handled && e.Mobile.InRange( this, 6 ) )
{
int[] keywords = e.Keywords;
string speech = e.Speech;
// Check for a greeting or 'Hire'
if( ( e.HasKeyword( 0x003B ) == true ) || ( e.HasKeyword( 0x0162 ) == true ) )
{
e.Handled = Payday( this );
this.SayHireCost();
}
}
base.OnSpeech( e );
}
#endregion
#region [ GetContextMenuEntries ]
public override void GetContextMenuEntries( Mobile from, ArrayList list )
{
Mobile Owner = GetOwner();
if( Owner == null )
{
base.GetContextMenuEntries( from, list );
list.Add( new HireEntry( from, this ) );
}
else
base.GetContextMenuEntries( from, list );
}
#endregion
#region [ Class PayTimer ]
private class PayTimer : Timer
{
private BaseHire m_Hire;
public PayTimer( BaseHire vend ) : base( TimeSpan.FromMinutes( 30.0 ), TimeSpan.FromMinutes( 30.0 ) )
{
m_Hire = vend;
Priority = TimerPriority.OneMinute;
}
protected override void OnTick()
{
int m_Pay = m_Hire.m_Pay;
if( m_Hire.m_HoldGold <= m_Pay )
{
// Get the current owner, if any (updates HireTable)
Mobile owner = m_Hire.GetOwner();
m_Hire.Say( 503235 ); // I regret nothing!postal
m_Hire.Delete();
}
else
{
m_Hire.m_HoldGold -= m_Pay;
}
}
}
#endregion
#region [ Class HireEntry ]
public class HireEntry : ContextMenuEntry
{
private Mobile m_Mobile;
private BaseHire m_Hire;
public HireEntry( Mobile from, BaseHire hire ) : base( 6120, 3 )
{
m_Hire = hire;
m_Mobile = from;
}
public override void OnClick()
{
m_Hire.Payday(m_Hire);
m_Hire.SayHireCost();
}
}
#endregion
}
}