#W# Source and Scripts added. Added Scripts/Settings.cs to expose some basic tweak able settings.
This commit is contained in:
parent
b51c58f514
commit
3045c83799
3512 changed files with 627673 additions and 0 deletions
69
Scripts/Mobiles/Townfolk/Actor.cs
Normal file
69
Scripts/Mobiles/Townfolk/Actor.cs
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server;
|
||||
using Server.Misc;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Actor : BaseCreature
|
||||
{
|
||||
[Constructable]
|
||||
public Actor () : base( AIType.AI_Animal, FightMode.None, 10, 1, 0.2, 0.4 )
|
||||
{
|
||||
InitStats( 31, 41, 51 );
|
||||
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
|
||||
Hue = Utility.RandomSkinHue();
|
||||
|
||||
if ( this.Female = Utility.RandomBool() )
|
||||
{
|
||||
this.Body = 0x191;
|
||||
this.Name = NameList.RandomName( "female" );
|
||||
AddItem( new FancyDress( Utility.RandomDyedHue() ) );
|
||||
Title = "the actress";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Body = 0x190;
|
||||
this.Name = NameList.RandomName( "male" );
|
||||
AddItem( new LongPants( Utility.RandomNeutralHue() ) );
|
||||
AddItem( new FancyShirt( Utility.RandomDyedHue() ) );
|
||||
Title = "the actor";
|
||||
}
|
||||
|
||||
AddItem( new Boots( Utility.RandomNeutralHue() ) );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
|
||||
Container pack = new Backpack();
|
||||
|
||||
pack.DropItem( new Gold( 250, 300 ) );
|
||||
|
||||
pack.Movable = false;
|
||||
|
||||
AddItem( pack );
|
||||
}
|
||||
|
||||
|
||||
public override bool ClickTitle{ get{ return false; } }
|
||||
|
||||
public Actor( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Scripts/Mobiles/Townfolk/Artist.cs
Normal file
74
Scripts/Mobiles/Townfolk/Artist.cs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server;
|
||||
using Server.Misc;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Artist : BaseCreature
|
||||
{
|
||||
public override bool CanTeach { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public Artist()
|
||||
: base( AIType.AI_Animal, FightMode.None, 10, 1, 0.2, 0.4 )
|
||||
{
|
||||
InitStats( 31, 41, 51 );
|
||||
|
||||
SetSkill( SkillName.Healing, 36, 68 );
|
||||
|
||||
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
Title = "the artist";
|
||||
Hue = Utility.RandomSkinHue();
|
||||
|
||||
|
||||
if( this.Female = Utility.RandomBool() )
|
||||
{
|
||||
this.Body = 0x191;
|
||||
this.Name = NameList.RandomName( "female" );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Body = 0x190;
|
||||
this.Name = NameList.RandomName( "male" );
|
||||
}
|
||||
AddItem( new Doublet( Utility.RandomDyedHue() ) );
|
||||
AddItem( new Sandals( Utility.RandomNeutralHue() ) );
|
||||
AddItem( new ShortPants( Utility.RandomNeutralHue() ) );
|
||||
AddItem( new HalfApron( Utility.RandomDyedHue() ) );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
|
||||
Container pack = new Backpack();
|
||||
|
||||
pack.DropItem( new Gold( 250, 300 ) );
|
||||
|
||||
pack.Movable = false;
|
||||
|
||||
AddItem( pack );
|
||||
}
|
||||
|
||||
public override bool ClickTitle { get { return false; } }
|
||||
|
||||
|
||||
public Artist( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
467
Scripts/Mobiles/Townfolk/Banker.cs
Normal file
467
Scripts/Mobiles/Townfolk/Banker.cs
Normal file
|
|
@ -0,0 +1,467 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server.Accounting;
|
||||
using Server.Items;
|
||||
using Server.ContextMenus;
|
||||
using Server.Misc;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Banker : BaseVendor
|
||||
{
|
||||
private List<SBInfo> m_SBInfos = new List<SBInfo>();
|
||||
protected override List<SBInfo> SBInfos{ get { return m_SBInfos; } }
|
||||
|
||||
public override NpcGuild NpcGuild{ get{ return NpcGuild.MerchantsGuild; } }
|
||||
|
||||
[Constructable]
|
||||
public Banker() : base( "the banker" )
|
||||
{
|
||||
}
|
||||
|
||||
public override void InitSBInfo()
|
||||
{
|
||||
m_SBInfos.Add( new SBBanker() );
|
||||
}
|
||||
|
||||
public static int GetBalance(Mobile m)
|
||||
{
|
||||
double balance = 0;
|
||||
|
||||
if (AccountGold.Enabled && m.Account != null)
|
||||
{
|
||||
int goldStub;
|
||||
m.Account.GetGoldBalance(out goldStub, out balance);
|
||||
|
||||
if (balance > Int32.MaxValue)
|
||||
{
|
||||
return Int32.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
Container bank = m.FindBankNoCreate();
|
||||
|
||||
if (bank != null)
|
||||
{
|
||||
var gold = bank.FindItemsByType<Gold>();
|
||||
var checks = bank.FindItemsByType<BankCheck>();
|
||||
|
||||
balance += gold.Aggregate(0.0, (c, t) => c + t.Amount);
|
||||
balance += checks.Aggregate(0.0, (c, t) => c + t.Worth);
|
||||
}
|
||||
|
||||
return (int)Math.Max(0, Math.Min(Int32.MaxValue, balance));
|
||||
}
|
||||
|
||||
public static int GetBalance(Mobile m, out Item[] gold, out Item[] checks)
|
||||
{
|
||||
double balance = 0;
|
||||
|
||||
if (AccountGold.Enabled && m.Account != null)
|
||||
{
|
||||
int goldStub;
|
||||
|
||||
m.Account.GetGoldBalance(out goldStub, out balance);
|
||||
|
||||
if (balance > Int32.MaxValue)
|
||||
{
|
||||
gold = checks = new Item[0];
|
||||
|
||||
return Int32.MaxValue;
|
||||
}
|
||||
}
|
||||
|
||||
Container bank = m.FindBankNoCreate();
|
||||
|
||||
if (bank != null)
|
||||
{
|
||||
gold = bank.FindItemsByType(typeof(Gold));
|
||||
checks = bank.FindItemsByType(typeof(BankCheck));
|
||||
|
||||
balance += gold.OfType<Gold>().Aggregate(0.0, (c, t) => c + t.Amount);
|
||||
balance += checks.OfType<BankCheck>().Aggregate(0.0, (c, t) => c + t.Worth);
|
||||
}
|
||||
else
|
||||
{
|
||||
gold = checks = new Item[0];
|
||||
}
|
||||
|
||||
return (int)Math.Max(0, Math.Min(Int32.MaxValue, balance));
|
||||
}
|
||||
|
||||
public static bool Withdraw(Mobile from, int amount)
|
||||
{
|
||||
// If for whatever reason the TOL checks fail, we should still try old methods for withdrawing currency.
|
||||
if (AccountGold.Enabled && from.Account != null && from.Account.WithdrawGold(amount))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Item[] gold, checks;
|
||||
var balance = GetBalance(from, out gold, out checks);
|
||||
|
||||
if (balance < amount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; amount > 0 && i < gold.Length; ++i)
|
||||
{
|
||||
if (gold[i].Amount <= amount)
|
||||
{
|
||||
amount -= gold[i].Amount;
|
||||
gold[i].Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
gold[i].Amount -= amount;
|
||||
amount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; amount > 0 && i < checks.Length; ++i)
|
||||
{
|
||||
var check = (BankCheck)checks[i];
|
||||
|
||||
if (check.Worth <= amount)
|
||||
{
|
||||
amount -= check.Worth;
|
||||
check.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
check.Worth -= amount;
|
||||
amount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool Deposit(Mobile from, int amount)
|
||||
{
|
||||
// If for whatever reason the TOL checks fail, we should still try old methods for depositing currency.
|
||||
if (AccountGold.Enabled && from.Account != null && from.Account.DepositGold(amount))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var box = from.FindBankNoCreate();
|
||||
|
||||
if (box == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var items = new List<Item>();
|
||||
|
||||
while (amount > 0)
|
||||
{
|
||||
Item item;
|
||||
if (amount < 5000)
|
||||
{
|
||||
item = new Gold(amount);
|
||||
amount = 0;
|
||||
}
|
||||
else if (amount <= 1000000)
|
||||
{
|
||||
item = new BankCheck(amount);
|
||||
amount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = new BankCheck(1000000);
|
||||
amount -= 1000000;
|
||||
}
|
||||
|
||||
if (box.TryDropItem(from, item, false))
|
||||
{
|
||||
items.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Delete();
|
||||
|
||||
foreach (var curItem in items)
|
||||
{
|
||||
curItem.Delete();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int DepositUpTo(Mobile from, int amount)
|
||||
{
|
||||
// If for whatever reason the TOL checks fail, we should still try old methods for depositing currency.
|
||||
if (AccountGold.Enabled && from.Account != null && from.Account.DepositGold(amount))
|
||||
{
|
||||
return amount;
|
||||
}
|
||||
|
||||
var box = from.FindBankNoCreate();
|
||||
|
||||
if (box == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
var amountLeft = amount;
|
||||
|
||||
while (amountLeft > 0)
|
||||
{
|
||||
Item item;
|
||||
int amountGiven;
|
||||
|
||||
if (amountLeft < 5000)
|
||||
{
|
||||
item = new Gold(amountLeft);
|
||||
amountGiven = amountLeft;
|
||||
}
|
||||
else if (amountLeft <= 1000000)
|
||||
{
|
||||
item = new BankCheck(amountLeft);
|
||||
amountGiven = amountLeft;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = new BankCheck(1000000);
|
||||
amountGiven = 1000000;
|
||||
}
|
||||
|
||||
if (box.TryDropItem(from, item, false))
|
||||
{
|
||||
amountLeft -= amountGiven;
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Delete();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return amount - amountLeft;
|
||||
}
|
||||
|
||||
public static void Deposit(Container cont, int amount)
|
||||
{
|
||||
while (amount > 0)
|
||||
{
|
||||
Item item;
|
||||
|
||||
if (amount < 5000)
|
||||
{
|
||||
item = new Gold(amount);
|
||||
amount = 0;
|
||||
}
|
||||
else if (amount <= 1000000)
|
||||
{
|
||||
item = new BankCheck(amount);
|
||||
amount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = new BankCheck(1000000);
|
||||
amount -= 1000000;
|
||||
}
|
||||
|
||||
cont.DropItem(item);
|
||||
}
|
||||
}
|
||||
|
||||
public Banker( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override bool HandlesOnSpeech( Mobile from )
|
||||
{
|
||||
if ( from.InRange( this.Location, 12 ) )
|
||||
return true;
|
||||
|
||||
return base.HandlesOnSpeech( from );
|
||||
}
|
||||
|
||||
public override void OnSpeech( SpeechEventArgs e )
|
||||
{
|
||||
if ( !e.Handled && e.Mobile.InRange( this.Location, 12 ) )
|
||||
{
|
||||
for ( int i = 0; i < e.Keywords.Length; ++i )
|
||||
{
|
||||
int keyword = e.Keywords[i];
|
||||
|
||||
switch ( keyword )
|
||||
{
|
||||
case 0x0000: // *withdraw*
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
if ( e.Mobile.Criminal )
|
||||
{
|
||||
this.Say( 500389 ); // I will not do business with a criminal!
|
||||
break;
|
||||
}
|
||||
|
||||
string[] split = e.Speech.Split( ' ' );
|
||||
|
||||
if ( split.Length >= 2 )
|
||||
{
|
||||
int amount;
|
||||
|
||||
Container pack = e.Mobile.Backpack;
|
||||
|
||||
if ( !int.TryParse( split[1], out amount ) )
|
||||
break;
|
||||
|
||||
if ( (!Core.ML && amount > 5000) || (Core.ML && amount > 60000) )
|
||||
{
|
||||
this.Say( 500381 ); // Thou canst not withdraw so much at one time!
|
||||
}
|
||||
else if (pack == null || pack.Deleted || !(pack.TotalWeight < pack.MaxWeight) || !(pack.TotalItems < pack.MaxItems))
|
||||
{
|
||||
this.Say(1048147); // Your backpack can't hold anything else.
|
||||
}
|
||||
else if (amount > 0)
|
||||
{
|
||||
BankBox box = e.Mobile.FindBankNoCreate();
|
||||
|
||||
if (box == null || !Withdraw(e.Mobile, amount))
|
||||
{
|
||||
this.Say(500384); // Ah, art thou trying to fool me? Thou hast not so much gold!
|
||||
}
|
||||
else
|
||||
{
|
||||
pack.DropItem(new Gold(amount));
|
||||
|
||||
this.Say(1010005); // Thou hast withdrawn gold from thy account.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x0001: // *balance*
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
if ( e.Mobile.Criminal )
|
||||
{
|
||||
this.Say( 500389 ); // I will not do business with a criminal!
|
||||
break;
|
||||
}
|
||||
|
||||
if ( AccountGold.Enabled && e.Mobile.Account != null )
|
||||
{
|
||||
this.Say( 1155855, String.Format("{0:#,0}\t{1:#,0}", e.Mobile.Account.TotalPlat, e.Mobile.Account.TotalGold) ); // Thy current bank balance is ~1_AMOUNT~ platinum and ~2_AMOUNT~ gold.
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Say( 1042759, GetBalance(e.Mobile).ToString("#,0") ); // Thy current bank balance is ~1_AMOUNT~ gold.
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x0002: // *bank*
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
if ( e.Mobile.Criminal )
|
||||
{
|
||||
this.Say( 500378 ); // Thou art a criminal and cannot access thy bank box.
|
||||
break;
|
||||
}
|
||||
|
||||
e.Mobile.BankBox.Open();
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x0003: // *check*
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
if ( AccountGold.Enabled )
|
||||
break;
|
||||
|
||||
if ( e.Mobile.Criminal )
|
||||
{
|
||||
this.Say( 500389 ); // I will not do business with a criminal!
|
||||
break;
|
||||
}
|
||||
|
||||
string[] split = e.Speech.Split( ' ' );
|
||||
|
||||
if ( split.Length >= 2 )
|
||||
{
|
||||
int amount;
|
||||
|
||||
if ( !int.TryParse( split[1], out amount ) )
|
||||
break;
|
||||
|
||||
if ( amount < 5000 )
|
||||
{
|
||||
this.Say( 1010006 ); // We cannot create checks for such a paltry amount of gold!
|
||||
}
|
||||
else if ( amount > 1000000 )
|
||||
{
|
||||
this.Say( 1010007 ); // Our policies prevent us from creating checks worth that much!
|
||||
}
|
||||
else
|
||||
{
|
||||
BankCheck check = new BankCheck( amount );
|
||||
|
||||
BankBox box = e.Mobile.BankBox;
|
||||
|
||||
if ( !box.TryDropItem( e.Mobile, check, false ) )
|
||||
{
|
||||
this.Say( 500386 ); // There's not enough room in your bankbox for the check!
|
||||
check.Delete();
|
||||
}
|
||||
else if ( !box.ConsumeTotal( typeof( Gold ), amount ) )
|
||||
{
|
||||
this.Say( 500384 ); // Ah, art thou trying to fool me? Thou hast not so much gold!
|
||||
check.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Say( 1042673, AffixType.Append, amount.ToString(), "" ); // Into your bank box I have placed a check in the amount of:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnSpeech( e );
|
||||
}
|
||||
|
||||
public override void AddCustomContextEntries( Mobile from, List<ContextMenuEntry> list )
|
||||
{
|
||||
if ( from.Alive )
|
||||
list.Add( new OpenBankEntry( from, this ) );
|
||||
|
||||
base.AddCustomContextEntries( from, list );
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
778
Scripts/Mobiles/Townfolk/BaseEscortable.cs
Normal file
778
Scripts/Mobiles/Townfolk/BaseEscortable.cs
Normal file
|
|
@ -0,0 +1,778 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
using Server.ContextMenus;
|
||||
using EDI = Server.Mobiles.EscortDestinationInfo;
|
||||
using Server.Engines.MLQuests;
|
||||
using Server.Engines.MLQuests.Definitions;
|
||||
using Server.Engines.MLQuests.Objectives;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class BaseEscortable : BaseCreature
|
||||
{
|
||||
public static readonly TimeSpan EscortDelay = TimeSpan.FromMinutes( 5.0 );
|
||||
public static readonly TimeSpan AbandonDelay = MLQuestSystem.Enabled ? TimeSpan.FromMinutes( 1.0 ) : TimeSpan.FromMinutes( 2.0 );
|
||||
public static readonly TimeSpan DeleteTime = MLQuestSystem.Enabled ? TimeSpan.FromSeconds( 100 ) : TimeSpan.FromSeconds( 30 );
|
||||
|
||||
public override bool StaticMLQuester { get { return false; } } // Suppress automatic quest registration on creation/deserialization
|
||||
|
||||
private MLQuest m_MLQuest;
|
||||
|
||||
protected override List<MLQuest> ConstructQuestList()
|
||||
{
|
||||
if ( m_MLQuest == null )
|
||||
{
|
||||
Region reg = Region;
|
||||
Type[] list = reg.IsPartOf( "Haven Island" ) ? m_MLQuestTypesNH : m_MLQuestTypes;
|
||||
|
||||
int randomIdx = Utility.Random( list.Length );
|
||||
|
||||
for ( int i = 0; i < list.Length; ++i )
|
||||
{
|
||||
Type questType = list[randomIdx];
|
||||
|
||||
MLQuest quest = MLQuestSystem.FindQuest( questType );
|
||||
|
||||
if ( quest != null )
|
||||
{
|
||||
bool okay = true;
|
||||
|
||||
foreach ( BaseObjective obj in quest.Objectives )
|
||||
{
|
||||
if ( obj is EscortObjective && ( (EscortObjective)obj ).Destination.Contains( reg ) )
|
||||
{
|
||||
okay = false; // We're already there!
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( okay )
|
||||
{
|
||||
m_MLQuest = quest;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ( MLQuestSystem.Debug )
|
||||
{
|
||||
Console.WriteLine( "Warning: Escortable cannot be assigned quest type '{0}', it is not registered", questType.Name );
|
||||
}
|
||||
|
||||
randomIdx = ( randomIdx + 1 ) % list.Length;
|
||||
}
|
||||
|
||||
if ( m_MLQuest == null )
|
||||
{
|
||||
if ( MLQuestSystem.Debug )
|
||||
Console.WriteLine( "Warning: No suitable quest found for escort {0}", Serial );
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
List<MLQuest> result = new List<MLQuest>();
|
||||
result.Add( m_MLQuest );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override bool CanShout { get { return ( !Controlled && !IsBeingDeleted ); } }
|
||||
|
||||
public override void Shout( PlayerMobile pm )
|
||||
{
|
||||
/*
|
||||
* 1072301 - You there! Care to hear how to earn some easy gold?
|
||||
* 1072302 - Adventurer! I have an offer for you.
|
||||
* 1072303 - Wait! I have an opportunity for you to make some gold!
|
||||
*/
|
||||
MLQuestSystem.Tell( this, pm, Utility.Random( 1072301, 3 ) );
|
||||
}
|
||||
|
||||
private EDI m_Destination;
|
||||
private string m_DestinationString;
|
||||
|
||||
private DateTime m_DeleteTime;
|
||||
private Timer m_DeleteTimer;
|
||||
|
||||
private bool m_DeleteCorpse = false;
|
||||
|
||||
public bool IsBeingDeleted
|
||||
{
|
||||
get { return ( m_DeleteTimer != null ); }
|
||||
}
|
||||
|
||||
public override bool Commandable { get { return false; } } // Our master cannot boss us around!
|
||||
public override bool DeleteCorpseOnDeath { get { return m_DeleteCorpse; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Destination
|
||||
{
|
||||
get { return m_Destination == null ? null : m_Destination.Name; }
|
||||
set { m_DestinationString = value; m_Destination = EDI.Find(value); }
|
||||
}
|
||||
|
||||
// Classic list
|
||||
// Used when: !MLQuestSystem.Enabled && !Core.ML
|
||||
private static string[] m_TownNames = new string[]
|
||||
{
|
||||
"Cove", "Britain", "Jhelom",
|
||||
"Minoc", "Ocllo", "Trinsic",
|
||||
"Vesper", "Yew", "Skara Brae",
|
||||
"Nujel'm", "Moonglow", "Magincia"
|
||||
};
|
||||
|
||||
// ML list, pre-ML quest system
|
||||
// Used when: !MLQuestSystem.Enabled && Core.ML
|
||||
private static string[] m_MLTownNames = new string[]
|
||||
{
|
||||
"Cove", "Serpent's Hold", "Jhelom",
|
||||
"Nujel'm"
|
||||
};
|
||||
|
||||
// ML quest system general list
|
||||
// Used when: MLQuestSystem.Enabled && !Region.IsPartOf( "Haven Island" )
|
||||
private static Type[] m_MLQuestTypes =
|
||||
{
|
||||
typeof( EscortToYew ),
|
||||
typeof( EscortToVesper ),
|
||||
typeof( EscortToTrinsic ),
|
||||
typeof( EscortToSkaraBrae ),
|
||||
typeof( EscortToSerpentsHold ),
|
||||
typeof( EscortToNujelm ),
|
||||
typeof( EscortToMoonglow ),
|
||||
typeof( EscortToMinoc ),
|
||||
typeof( EscortToMagincia ),
|
||||
typeof( EscortToJhelom ),
|
||||
typeof( EscortToCove ),
|
||||
typeof( EscortToBritain )
|
||||
// Ocllo was removed in pub 56
|
||||
//typeof( EscortToOcllo )
|
||||
};
|
||||
|
||||
// ML quest system New Haven list
|
||||
// Used when: MLQuestSystem.Enabled && Region.IsPartOf( "Haven Island" )
|
||||
private static Type[] m_MLQuestTypesNH =
|
||||
{
|
||||
typeof( EscortToNHAlchemist ),
|
||||
typeof( EscortToNHBard ),
|
||||
typeof( EscortToNHWarrior ),
|
||||
typeof( EscortToNHTailor ),
|
||||
typeof( EscortToNHCarpenter ),
|
||||
typeof( EscortToNHMapmaker ),
|
||||
typeof( EscortToNHMage ),
|
||||
typeof( EscortToNHInn ),
|
||||
// Farm destination was removed
|
||||
//typeof( EscortToNHFarm ),
|
||||
typeof( EscortToNHDocks ),
|
||||
typeof( EscortToNHBowyer ),
|
||||
typeof( EscortToNHBank )
|
||||
};
|
||||
|
||||
[Constructable]
|
||||
public BaseEscortable()
|
||||
: base(AIType.AI_Melee, FightMode.Aggressor, 22, 1, 0.2, 1.0)
|
||||
{
|
||||
InitBody();
|
||||
InitOutfit();
|
||||
|
||||
Fame = 200;
|
||||
Karma = 4000;
|
||||
}
|
||||
|
||||
public virtual void InitBody()
|
||||
{
|
||||
SetStr(90, 100);
|
||||
SetDex(90, 100);
|
||||
SetInt(15, 25);
|
||||
|
||||
Hue = Utility.RandomSkinHue();
|
||||
|
||||
if (Female = Utility.RandomBool())
|
||||
{
|
||||
Body = 401;
|
||||
Name = NameList.RandomName("female");
|
||||
}
|
||||
else
|
||||
{
|
||||
Body = 400;
|
||||
Name = NameList.RandomName("male");
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void InitOutfit()
|
||||
{
|
||||
AddItem(new FancyShirt(Utility.RandomNeutralHue()));
|
||||
AddItem(new ShortPants(Utility.RandomNeutralHue()));
|
||||
AddItem(new Boots(Utility.RandomNeutralHue()));
|
||||
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
PackGold(200, 250);
|
||||
}
|
||||
|
||||
public virtual bool SayDestinationTo(Mobile m)
|
||||
{
|
||||
EDI dest = GetDestination();
|
||||
|
||||
if (dest == null || !m.Alive)
|
||||
return false;
|
||||
|
||||
Mobile escorter = GetEscorter();
|
||||
|
||||
if (escorter == null)
|
||||
{
|
||||
Say("I am looking to go to {0}, will you take me?", (dest.Name == "Ocllo" && m.Map == Map.Trammel) ? "Haven" : dest.Name);
|
||||
return true;
|
||||
}
|
||||
else if (escorter == m)
|
||||
{
|
||||
Say("Lead on! Payment will be made when we arrive in {0}.", (dest.Name == "Ocllo" && m.Map == Map.Trammel) ? "Haven" : dest.Name);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Hashtable m_EscortTable = new Hashtable();
|
||||
|
||||
public static Hashtable EscortTable
|
||||
{
|
||||
get { return m_EscortTable; }
|
||||
}
|
||||
|
||||
public virtual bool AcceptEscorter(Mobile m)
|
||||
{
|
||||
EDI dest = GetDestination();
|
||||
|
||||
if (dest == null)
|
||||
return false;
|
||||
|
||||
Mobile escorter = GetEscorter();
|
||||
|
||||
if (escorter != null || !m.Alive)
|
||||
return false;
|
||||
|
||||
BaseEscortable escortable = (BaseEscortable)m_EscortTable[m];
|
||||
|
||||
if (escortable != null && !escortable.Deleted && escortable.GetEscorter() == m)
|
||||
{
|
||||
Say("I see you already have an escort.");
|
||||
return false;
|
||||
}
|
||||
else if (m is PlayerMobile && (((PlayerMobile)m).LastEscortTime + EscortDelay) >= DateTime.UtcNow)
|
||||
{
|
||||
int minutes = (int)Math.Ceiling(((((PlayerMobile)m).LastEscortTime + EscortDelay) - DateTime.UtcNow).TotalMinutes);
|
||||
|
||||
Say("You must rest {0} minute{1} before we set out on this journey.", minutes, minutes == 1 ? "" : "s");
|
||||
return false;
|
||||
}
|
||||
else if (SetControlMaster(m))
|
||||
{
|
||||
m_LastSeenEscorter = DateTime.UtcNow;
|
||||
|
||||
if (m is PlayerMobile)
|
||||
((PlayerMobile)m).LastEscortTime = DateTime.UtcNow;
|
||||
|
||||
Say("Lead on! Payment will be made when we arrive in {0}.", (dest.Name == "Ocllo" && m.Map == Map.Trammel) ? "Haven" : dest.Name);
|
||||
m_EscortTable[m] = this;
|
||||
StartFollow();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool HandlesOnSpeech(Mobile from)
|
||||
{
|
||||
if ( MLQuestSystem.Enabled )
|
||||
return false;
|
||||
|
||||
if (from.InRange(this.Location, 3))
|
||||
return true;
|
||||
|
||||
return base.HandlesOnSpeech(from);
|
||||
}
|
||||
|
||||
public override void OnSpeech(SpeechEventArgs e)
|
||||
{
|
||||
base.OnSpeech(e);
|
||||
|
||||
EDI dest = GetDestination();
|
||||
|
||||
if (dest != null && !e.Handled && e.Mobile.InRange(this.Location, 3))
|
||||
{
|
||||
if (e.HasKeyword(0x1D)) // *destination*
|
||||
e.Handled = SayDestinationTo(e.Mobile);
|
||||
else if (e.HasKeyword(0x1E)) // *i will take thee*
|
||||
e.Handled = AcceptEscorter(e.Mobile);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnAfterDelete()
|
||||
{
|
||||
if (m_DeleteTimer != null)
|
||||
m_DeleteTimer.Stop();
|
||||
|
||||
m_DeleteTimer = null;
|
||||
|
||||
base.OnAfterDelete();
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
CheckAtDestination();
|
||||
}
|
||||
|
||||
protected override bool OnMove(Direction d)
|
||||
{
|
||||
if (!base.OnMove(d))
|
||||
return false;
|
||||
|
||||
CheckAtDestination();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Pre-ML methods below, might be mergeable with the ML methods in EscortObjective
|
||||
|
||||
public virtual void StartFollow()
|
||||
{
|
||||
StartFollow(GetEscorter());
|
||||
}
|
||||
|
||||
public virtual void StartFollow(Mobile escorter)
|
||||
{
|
||||
if (escorter == null)
|
||||
return;
|
||||
|
||||
ActiveSpeed = 0.1;
|
||||
PassiveSpeed = 0.2;
|
||||
|
||||
ControlOrder = OrderType.Follow;
|
||||
ControlTarget = escorter;
|
||||
|
||||
if ((IsPrisoner == true) && (CantWalk == true))
|
||||
{
|
||||
CantWalk = false;
|
||||
}
|
||||
CurrentSpeed = 0.1;
|
||||
}
|
||||
|
||||
public virtual void StopFollow()
|
||||
{
|
||||
ActiveSpeed = 0.2;
|
||||
PassiveSpeed = 1.0;
|
||||
|
||||
ControlOrder = OrderType.None;
|
||||
ControlTarget = null;
|
||||
|
||||
CurrentSpeed = 1.0;
|
||||
}
|
||||
|
||||
private DateTime m_LastSeenEscorter;
|
||||
|
||||
public virtual Mobile GetEscorter()
|
||||
{
|
||||
if ( !Controlled )
|
||||
return null;
|
||||
|
||||
Mobile master = ControlMaster;
|
||||
|
||||
if ( MLQuestSystem.Enabled || master == null )
|
||||
return master;
|
||||
|
||||
if (master.Deleted || master.Map != this.Map || !master.InRange(Location, 30) || !master.Alive)
|
||||
{
|
||||
StopFollow();
|
||||
|
||||
TimeSpan lastSeenDelay = DateTime.UtcNow - m_LastSeenEscorter;
|
||||
|
||||
if (lastSeenDelay >= AbandonDelay)
|
||||
{
|
||||
master.SendLocalizedMessage(1042473); // You have lost the person you were escorting.
|
||||
Say(1005653); // Hmmm. I seem to have lost my master.
|
||||
|
||||
SetControlMaster(null);
|
||||
m_EscortTable.Remove(master);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(5.0), new TimerCallback(Delete));
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
ControlOrder = OrderType.Stay;
|
||||
return master;
|
||||
}
|
||||
}
|
||||
|
||||
if (ControlOrder != OrderType.Follow)
|
||||
StartFollow(master);
|
||||
|
||||
m_LastSeenEscorter = DateTime.UtcNow;
|
||||
return master;
|
||||
}
|
||||
|
||||
public virtual void BeginDelete()
|
||||
{
|
||||
if (m_DeleteTimer != null)
|
||||
m_DeleteTimer.Stop();
|
||||
|
||||
m_DeleteTime = DateTime.UtcNow + DeleteTime;
|
||||
|
||||
m_DeleteTimer = new DeleteTimer(this, m_DeleteTime - DateTime.UtcNow);
|
||||
m_DeleteTimer.Start();
|
||||
}
|
||||
|
||||
public virtual bool CheckAtDestination()
|
||||
{
|
||||
if ( MLQuestSystem.Enabled )
|
||||
return false;
|
||||
|
||||
EDI dest = GetDestination();
|
||||
|
||||
if (dest == null)
|
||||
return false;
|
||||
|
||||
Mobile escorter = GetEscorter();
|
||||
|
||||
if (escorter == null)
|
||||
return false;
|
||||
|
||||
if (dest.Contains(Location))
|
||||
{
|
||||
Say(1042809, escorter.Name); // We have arrived! I thank thee, ~1_PLAYER_NAME~! I have no further need of thy services. Here is thy pay.
|
||||
|
||||
// not going anywhere
|
||||
m_Destination = null;
|
||||
m_DestinationString = null;
|
||||
|
||||
Container cont = escorter.Backpack;
|
||||
|
||||
if (cont == null)
|
||||
cont = escorter.BankBox;
|
||||
|
||||
Gold gold = new Gold(500, 1000);
|
||||
|
||||
if (!cont.TryDropItem(escorter, gold, false))
|
||||
gold.MoveToWorld(escorter.Location, escorter.Map);
|
||||
|
||||
StopFollow();
|
||||
SetControlMaster(null);
|
||||
m_EscortTable.Remove(escorter);
|
||||
BeginDelete();
|
||||
|
||||
Misc.Titles.AwardFame(escorter, 10, true);
|
||||
|
||||
bool gainedPath = false;
|
||||
|
||||
PlayerMobile pm = escorter as PlayerMobile;
|
||||
|
||||
if (pm != null)
|
||||
{
|
||||
if (pm.CompassionGains > 0 && DateTime.UtcNow > pm.NextCompassionDay)
|
||||
{
|
||||
pm.NextCompassionDay = DateTime.MinValue;
|
||||
pm.CompassionGains = 0;
|
||||
}
|
||||
|
||||
if (pm.CompassionGains >= 5) // have already gained 5 times in one day, can gain no more
|
||||
{
|
||||
pm.SendLocalizedMessage(1053004); // You must wait about a day before you can gain in compassion again.
|
||||
}
|
||||
else if (VirtueHelper.Award(pm, VirtueName.Compassion, this.IsPrisoner ? 400 : 200, ref gainedPath))
|
||||
{
|
||||
if (gainedPath)
|
||||
pm.SendLocalizedMessage(1053005); // You have achieved a path in compassion!
|
||||
else
|
||||
pm.SendLocalizedMessage(1053002); // You have gained in compassion.
|
||||
|
||||
pm.NextCompassionDay = DateTime.UtcNow + TimeSpan.FromDays(1.0); // in one day CompassionGains gets reset to 0
|
||||
++pm.CompassionGains;
|
||||
|
||||
if (pm.CompassionGains >= 5)
|
||||
pm.SendLocalizedMessage(1053004); // You must wait about a day before you can gain in compassion again.
|
||||
}
|
||||
else
|
||||
{
|
||||
pm.SendLocalizedMessage(1053003); // You have achieved the highest path of compassion and can no longer gain any further.
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnBeforeDeath()
|
||||
{
|
||||
m_DeleteCorpse = ( Controlled || IsBeingDeleted );
|
||||
|
||||
return base.OnBeforeDeath();
|
||||
}
|
||||
|
||||
public BaseEscortable(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write((int)1); // version
|
||||
|
||||
EDI dest = GetDestination();
|
||||
|
||||
writer.Write(dest != null);
|
||||
|
||||
if (dest != null)
|
||||
writer.Write(dest.Name);
|
||||
|
||||
writer.Write(m_DeleteTimer != null);
|
||||
|
||||
if (m_DeleteTimer != null)
|
||||
writer.WriteDeltaTime(m_DeleteTime);
|
||||
|
||||
MLQuestSystem.WriteQuestRef( writer, StaticMLQuester ? null : m_MLQuest );
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
if (reader.ReadBool())
|
||||
m_DestinationString = reader.ReadString(); // NOTE: We cannot EDI.Find here, regions have not yet been loaded :-(
|
||||
|
||||
if (reader.ReadBool())
|
||||
{
|
||||
m_DeleteTime = reader.ReadDeltaTime();
|
||||
m_DeleteTimer = new DeleteTimer(this, m_DeleteTime - DateTime.UtcNow);
|
||||
m_DeleteTimer.Start();
|
||||
}
|
||||
|
||||
if ( version >= 1 )
|
||||
{
|
||||
MLQuest quest = MLQuestSystem.ReadQuestRef( reader );
|
||||
|
||||
if ( MLQuestSystem.Enabled && quest != null && !StaticMLQuester )
|
||||
m_MLQuest = quest;
|
||||
}
|
||||
}
|
||||
|
||||
public override bool CanBeRenamedBy(Mobile from)
|
||||
{
|
||||
return (from.AccessLevel >= AccessLevel.GameMaster);
|
||||
}
|
||||
|
||||
public override void AddCustomContextEntries( Mobile from, List<ContextMenuEntry> list )
|
||||
{
|
||||
if ( from.Alive )
|
||||
{
|
||||
Mobile escorter = GetEscorter();
|
||||
|
||||
if ( !MLQuestSystem.Enabled && GetDestination() != null )
|
||||
{
|
||||
if ( escorter == null || escorter == from )
|
||||
list.Add( new AskDestinationEntry( this, from ) );
|
||||
|
||||
if ( escorter == null )
|
||||
list.Add( new AcceptEscortEntry( this, from ) );
|
||||
}
|
||||
|
||||
if ( escorter == from )
|
||||
list.Add( new AbandonEscortEntry( this, from ) );
|
||||
}
|
||||
|
||||
base.AddCustomContextEntries( from, list );
|
||||
}
|
||||
|
||||
public virtual string[] GetPossibleDestinations()
|
||||
{
|
||||
if (!Core.ML)
|
||||
return m_TownNames;
|
||||
else
|
||||
return m_MLTownNames;
|
||||
}
|
||||
|
||||
public virtual string PickRandomDestination()
|
||||
{
|
||||
if (Map.Felucca.Regions.Count == 0 || Map == null || Map == Map.Internal || Location == Point3D.Zero)
|
||||
return null; // Not yet fully initialized
|
||||
|
||||
string[] possible = GetPossibleDestinations();
|
||||
string picked = null;
|
||||
|
||||
while (picked == null)
|
||||
{
|
||||
picked = possible[Utility.Random(possible.Length)];
|
||||
EDI test = EDI.Find(picked);
|
||||
|
||||
if (test != null && test.Contains(Location))
|
||||
picked = null;
|
||||
}
|
||||
|
||||
return picked;
|
||||
}
|
||||
|
||||
public EDI GetDestination()
|
||||
{
|
||||
if ( MLQuestSystem.Enabled )
|
||||
return null;
|
||||
|
||||
if (m_DestinationString == null && m_DeleteTimer == null)
|
||||
m_DestinationString = PickRandomDestination();
|
||||
|
||||
if (m_Destination != null && m_Destination.Name == m_DestinationString)
|
||||
return m_Destination;
|
||||
|
||||
if (Map.Felucca.Regions.Count > 0)
|
||||
return (m_Destination = EDI.Find(m_DestinationString));
|
||||
|
||||
return (m_Destination = null);
|
||||
}
|
||||
|
||||
private class DeleteTimer : Timer
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
|
||||
public DeleteTimer(Mobile m, TimeSpan delay)
|
||||
: base(delay)
|
||||
{
|
||||
m_Mobile = m;
|
||||
|
||||
Priority = TimerPriority.OneSecond;
|
||||
}
|
||||
|
||||
protected override void OnTick()
|
||||
{
|
||||
m_Mobile.Delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class EscortDestinationInfo
|
||||
{
|
||||
private string m_Name;
|
||||
private Region m_Region;
|
||||
//private Rectangle2D[] m_Bounds;
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return m_Name; }
|
||||
}
|
||||
|
||||
public Region Region
|
||||
{
|
||||
get { return m_Region; }
|
||||
}
|
||||
|
||||
/*public Rectangle2D[] Bounds
|
||||
{
|
||||
get{ return m_Bounds; }
|
||||
}*/
|
||||
|
||||
public bool Contains(Point3D p)
|
||||
{
|
||||
return m_Region.Contains(p);
|
||||
}
|
||||
|
||||
public EscortDestinationInfo(string name, Region region)
|
||||
{
|
||||
m_Name = name;
|
||||
m_Region = region;
|
||||
}
|
||||
|
||||
private static Hashtable m_Table;
|
||||
|
||||
public static void LoadTable()
|
||||
{
|
||||
ICollection list = Map.Felucca.Regions.Values;
|
||||
|
||||
if (list.Count == 0)
|
||||
return;
|
||||
|
||||
m_Table = new Hashtable();
|
||||
|
||||
foreach (Region r in list)
|
||||
{
|
||||
if (r.Name == null)
|
||||
continue;
|
||||
|
||||
if (r is Regions.DungeonRegion || r is Regions.TownRegion)
|
||||
m_Table[r.Name] = new EscortDestinationInfo(r.Name, r);
|
||||
}
|
||||
}
|
||||
|
||||
public static EDI Find(string name)
|
||||
{
|
||||
if (m_Table == null)
|
||||
LoadTable();
|
||||
|
||||
if (name == null || m_Table == null)
|
||||
return null;
|
||||
|
||||
return (EscortDestinationInfo)m_Table[name];
|
||||
}
|
||||
}
|
||||
|
||||
public class AskDestinationEntry : ContextMenuEntry
|
||||
{
|
||||
private BaseEscortable m_Mobile;
|
||||
private Mobile m_From;
|
||||
|
||||
public AskDestinationEntry(BaseEscortable m, Mobile from)
|
||||
: base(6100, 3)
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_From = from;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
m_Mobile.SayDestinationTo(m_From);
|
||||
}
|
||||
}
|
||||
|
||||
public class AcceptEscortEntry : ContextMenuEntry
|
||||
{
|
||||
private BaseEscortable m_Mobile;
|
||||
private Mobile m_From;
|
||||
|
||||
public AcceptEscortEntry(BaseEscortable m, Mobile from)
|
||||
: base(6101, 3)
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_From = from;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
m_Mobile.AcceptEscorter(m_From);
|
||||
}
|
||||
}
|
||||
|
||||
public class AbandonEscortEntry : ContextMenuEntry
|
||||
{
|
||||
private BaseEscortable m_Mobile;
|
||||
private Mobile m_From;
|
||||
|
||||
public AbandonEscortEntry(BaseEscortable m, Mobile from)
|
||||
: base(6102, 3)
|
||||
{
|
||||
m_Mobile = m;
|
||||
m_From = from;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
m_Mobile.Delete(); // OSI just seems to delete instantly
|
||||
}
|
||||
}
|
||||
}
|
||||
80
Scripts/Mobiles/Townfolk/BrideGroom.cs
Normal file
80
Scripts/Mobiles/Townfolk/BrideGroom.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using EDI = Server.Mobiles.EscortDestinationInfo;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class BrideGroom : BaseEscortable
|
||||
{
|
||||
[Constructable]
|
||||
public BrideGroom()
|
||||
{
|
||||
if ( Female )
|
||||
Title = "the bride";
|
||||
else
|
||||
Title = "the groom";
|
||||
}
|
||||
|
||||
public override bool CanTeach{ get{ return true; } }
|
||||
public override bool ClickTitle{ get{ return false; } } // Do not display 'the groom' when single-clicking
|
||||
|
||||
private static int GetRandomHue()
|
||||
{
|
||||
switch ( Utility.Random( 6 ) )
|
||||
{
|
||||
default:
|
||||
case 0: return 0;
|
||||
case 1: return Utility.RandomBlueHue();
|
||||
case 2: return Utility.RandomGreenHue();
|
||||
case 3: return Utility.RandomRedHue();
|
||||
case 4: return Utility.RandomYellowHue();
|
||||
case 5: return Utility.RandomNeutralHue();
|
||||
}
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
if ( Female )
|
||||
AddItem( new FancyDress() );
|
||||
else
|
||||
AddItem( new FancyShirt() );
|
||||
|
||||
int lowHue = GetRandomHue();
|
||||
|
||||
AddItem( new LongPants( lowHue ) );
|
||||
|
||||
if ( Female )
|
||||
AddItem( new Shoes( lowHue ) );
|
||||
else
|
||||
AddItem( new Boots( lowHue ) );
|
||||
|
||||
if( Utility.RandomBool() )
|
||||
HairItemID = 0x203B;
|
||||
else
|
||||
HairItemID = 0x203C;
|
||||
|
||||
HairHue = this.Race.RandomHairHue();
|
||||
|
||||
PackGold( 200, 250 );
|
||||
}
|
||||
|
||||
public BrideGroom( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
74
Scripts/Mobiles/Townfolk/EscortableMage.cs
Normal file
74
Scripts/Mobiles/Townfolk/EscortableMage.cs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using EDI = Server.Mobiles.EscortDestinationInfo;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class EscortableMage : BaseEscortable
|
||||
{
|
||||
[Constructable]
|
||||
public EscortableMage()
|
||||
{
|
||||
Title = "the mage";
|
||||
|
||||
SetSkill( SkillName.EvalInt, 80.0, 100.0 );
|
||||
SetSkill( SkillName.Inscribe, 80.0, 100.0 );
|
||||
SetSkill( SkillName.Magery, 80.0, 100.0 );
|
||||
SetSkill( SkillName.Meditation, 80.0, 100.0 );
|
||||
SetSkill( SkillName.MagicResist, 80.0, 100.0 );
|
||||
}
|
||||
|
||||
public override bool CanTeach{ get{ return true; } }
|
||||
public override bool ClickTitle{ get{ return false; } } // Do not display 'the mage' when single-clicking
|
||||
|
||||
private static int GetRandomHue()
|
||||
{
|
||||
switch ( Utility.Random( 5 ) )
|
||||
{
|
||||
default:
|
||||
case 0: return Utility.RandomBlueHue();
|
||||
case 1: return Utility.RandomGreenHue();
|
||||
case 2: return Utility.RandomRedHue();
|
||||
case 3: return Utility.RandomYellowHue();
|
||||
case 4: return Utility.RandomNeutralHue();
|
||||
}
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
AddItem( new Robe( GetRandomHue() ) );
|
||||
|
||||
int lowHue = GetRandomHue();
|
||||
|
||||
AddItem( new ShortPants( lowHue ) );
|
||||
|
||||
if ( Female )
|
||||
AddItem( new ThighBoots( lowHue ) );
|
||||
else
|
||||
AddItem( new Boots( lowHue ) );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
|
||||
PackGold( 200, 250 );
|
||||
}
|
||||
|
||||
public EscortableMage( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
82
Scripts/Mobiles/Townfolk/Gypsy.cs
Normal file
82
Scripts/Mobiles/Townfolk/Gypsy.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server;
|
||||
using Server.Misc;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Gypsy : BaseCreature
|
||||
{
|
||||
|
||||
|
||||
[Constructable]
|
||||
public Gypsy()
|
||||
: base( AIType.AI_Animal, FightMode.None, 10, 1, 0.2, 0.4 )
|
||||
{
|
||||
InitStats( 31, 41, 51 );
|
||||
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
|
||||
SetSkill( SkillName.Cooking, 65, 88 );
|
||||
SetSkill( SkillName.Snooping, 65, 88 );
|
||||
SetSkill( SkillName.Stealing, 65, 88 );
|
||||
|
||||
Hue = Utility.RandomSkinHue();
|
||||
|
||||
if( this.Female = Utility.RandomBool() )
|
||||
{
|
||||
this.Body = 0x191;
|
||||
this.Name = NameList.RandomName( "female" );
|
||||
AddItem( new Kilt( Utility.RandomDyedHue() ) );
|
||||
AddItem( new Shirt( Utility.RandomDyedHue() ) );
|
||||
AddItem( new ThighBoots() );
|
||||
Title = "the gypsy";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Body = 0x190;
|
||||
this.Name = NameList.RandomName( "male" );
|
||||
AddItem( new ShortPants( Utility.RandomNeutralHue() ) );
|
||||
AddItem( new Shirt( Utility.RandomDyedHue() ) );
|
||||
AddItem( new Sandals() );
|
||||
Title = "the gypsy";
|
||||
}
|
||||
|
||||
AddItem( new Bandana( Utility.RandomDyedHue() ) );
|
||||
AddItem( new Dagger() );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
|
||||
Container pack = new Backpack();
|
||||
|
||||
pack.DropItem( new Gold( 250, 300 ) );
|
||||
|
||||
pack.Movable = false;
|
||||
|
||||
AddItem( pack );
|
||||
}
|
||||
|
||||
|
||||
public override bool CanTeach { get { return true; } }
|
||||
public override bool ClickTitle { get { return false; } }
|
||||
|
||||
public Gypsy( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
76
Scripts/Mobiles/Townfolk/HarborMaster.cs
Normal file
76
Scripts/Mobiles/Townfolk/HarborMaster.cs
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server;
|
||||
using Server.Misc;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class HarborMaster : BaseCreature
|
||||
{
|
||||
public override bool CanTeach { get { return false; } }
|
||||
|
||||
[Constructable]
|
||||
public HarborMaster()
|
||||
: base( AIType.AI_Animal, FightMode.None, 10, 1, 0.2, 0.4 )
|
||||
{
|
||||
InitStats( 31, 41, 51 );
|
||||
|
||||
SetSkill( SkillName.Mining, 36, 68 );
|
||||
|
||||
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
Hue = Utility.RandomSkinHue();
|
||||
Blessed = true;
|
||||
|
||||
|
||||
if( this.Female = Utility.RandomBool() )
|
||||
{
|
||||
this.Body = 0x191;
|
||||
this.Name = NameList.RandomName( "female" );
|
||||
Title = "the Harbor Mistress";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Body = 0x190;
|
||||
this.Name = NameList.RandomName( "male" );
|
||||
Title = "the Harbor Master";
|
||||
}
|
||||
AddItem( new Shirt( Utility.RandomDyedHue() ) );
|
||||
AddItem( new Boots() );
|
||||
AddItem( new LongPants( Utility.RandomNeutralHue() ) );
|
||||
AddItem( new QuarterStaff() );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
|
||||
Container pack = new Backpack();
|
||||
|
||||
pack.DropItem( new Gold( 250, 300 ) );
|
||||
|
||||
pack.Movable = false;
|
||||
|
||||
AddItem( pack );
|
||||
}
|
||||
|
||||
public override bool ClickTitle { get { return false; } }
|
||||
|
||||
|
||||
public HarborMaster( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
85
Scripts/Mobiles/Townfolk/Merchant.cs
Normal file
85
Scripts/Mobiles/Townfolk/Merchant.cs
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using EDI=Server.Mobiles.EscortDestinationInfo;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Merchant : BaseEscortable
|
||||
{
|
||||
[Constructable]
|
||||
public Merchant()
|
||||
{
|
||||
Title = "the merchant";
|
||||
SetSkill( SkillName.ItemID, 55.0, 78.0 );
|
||||
SetSkill( SkillName.ArmsLore, 55, 78 );
|
||||
}
|
||||
|
||||
public override bool CanTeach { get { return true; } }
|
||||
public override bool ClickTitle { get { return false; } } // Do not display 'the merchant' when single-clicking
|
||||
|
||||
private static int GetRandomHue()
|
||||
{
|
||||
switch( Utility.Random( 6 ) )
|
||||
{
|
||||
default:
|
||||
case 0: return 0;
|
||||
case 1: return Utility.RandomBlueHue();
|
||||
case 2: return Utility.RandomGreenHue();
|
||||
case 3: return Utility.RandomRedHue();
|
||||
case 4: return Utility.RandomYellowHue();
|
||||
case 5: return Utility.RandomNeutralHue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
if( Female )
|
||||
AddItem( new PlainDress() );
|
||||
else
|
||||
AddItem( new Shirt( GetRandomHue() ) );
|
||||
|
||||
int lowHue = GetRandomHue();
|
||||
|
||||
AddItem( new ThighBoots() );
|
||||
|
||||
if( Female )
|
||||
AddItem( new FancyDress( lowHue ) );
|
||||
else
|
||||
AddItem( new FancyShirt( lowHue ) );
|
||||
AddItem( new LongPants( lowHue ) );
|
||||
|
||||
if( !Female )
|
||||
AddItem( new BodySash( lowHue ) );
|
||||
|
||||
|
||||
|
||||
//if ( !Female )
|
||||
//AddItem( new Longsword() );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
|
||||
PackGold( 200, 250 );
|
||||
}
|
||||
|
||||
public Merchant( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
86
Scripts/Mobiles/Townfolk/Messenger.cs
Normal file
86
Scripts/Mobiles/Townfolk/Messenger.cs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using EDI = Server.Mobiles.EscortDestinationInfo;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Messenger : BaseEscortable
|
||||
{
|
||||
[Constructable]
|
||||
public Messenger()
|
||||
{
|
||||
Title = "the messenger";
|
||||
}
|
||||
|
||||
public override bool CanTeach{ get{ return true; } }
|
||||
public override bool ClickTitle{ get{ return false; } } // Do not display 'the messenger' when single-clicking
|
||||
|
||||
private static int GetRandomHue()
|
||||
{
|
||||
switch ( Utility.Random( 6 ) )
|
||||
{
|
||||
default:
|
||||
case 0: return 0;
|
||||
case 1: return Utility.RandomBlueHue();
|
||||
case 2: return Utility.RandomGreenHue();
|
||||
case 3: return Utility.RandomRedHue();
|
||||
case 4: return Utility.RandomYellowHue();
|
||||
case 5: return Utility.RandomNeutralHue();
|
||||
}
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
if ( Female )
|
||||
AddItem( new PlainDress() );
|
||||
else
|
||||
AddItem( new Shirt( GetRandomHue() ) );
|
||||
|
||||
int lowHue = GetRandomHue();
|
||||
|
||||
AddItem( new ShortPants( lowHue ) );
|
||||
|
||||
if ( Female )
|
||||
AddItem( new Boots( lowHue ) );
|
||||
else
|
||||
AddItem( new Shoes( lowHue ) );
|
||||
|
||||
//if ( !Female )
|
||||
//AddItem( new BodySash( lowHue ) );
|
||||
|
||||
//AddItem( new Cloak( GetRandomHue() ) );
|
||||
|
||||
//if ( !Female )
|
||||
//AddItem( new Longsword() );
|
||||
|
||||
switch ( Utility.Random( 4 ) )
|
||||
{
|
||||
case 0: AddItem( new ShortHair( Utility.RandomHairHue() ) ); break;
|
||||
case 1: AddItem( new TwoPigTails( Utility.RandomHairHue() ) ); break;
|
||||
case 2: AddItem( new ReceedingHair( Utility.RandomHairHue() ) ); break;
|
||||
case 3: AddItem( new KrisnaHair( Utility.RandomHairHue() ) ); break;
|
||||
}
|
||||
|
||||
PackGold( 200, 250 );
|
||||
}
|
||||
|
||||
public Messenger( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Scripts/Mobiles/Townfolk/Minter.cs
Normal file
38
Scripts/Mobiles/Townfolk/Minter.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Server.Items;
|
||||
using Server.ContextMenus;
|
||||
using Server.Misc;
|
||||
using Server.Network;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Minter : Banker
|
||||
{
|
||||
public override NpcGuild NpcGuild{ get{ return NpcGuild.MerchantsGuild; } }
|
||||
|
||||
[Constructable]
|
||||
public Minter()
|
||||
{
|
||||
Title = "the minter";
|
||||
}
|
||||
|
||||
public Minter( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
78
Scripts/Mobiles/Townfolk/Ninja.cs
Normal file
78
Scripts/Mobiles/Townfolk/Ninja.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Ninja : BaseCreature
|
||||
{
|
||||
public override bool CanTeach{ get{ return true; } }
|
||||
public override bool ClickTitle{ get{ return false; } }
|
||||
|
||||
[Constructable]
|
||||
public Ninja() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
|
||||
{
|
||||
Title = "the ninja";
|
||||
|
||||
InitStats( 100, 100, 25 );
|
||||
|
||||
SetSkill( SkillName.Fencing, 64.0, 80.0 );
|
||||
SetSkill( SkillName.Macing, 64.0, 80.0 );
|
||||
SetSkill( SkillName.Ninjitsu, 60.0, 80.0 );
|
||||
SetSkill( SkillName.Parry, 64.0, 80.0 );
|
||||
SetSkill( SkillName.Tactics, 64.0, 85.0 );
|
||||
SetSkill( SkillName.Swords, 64.0, 85.0 );
|
||||
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
|
||||
Hue = Utility.RandomSkinHue();
|
||||
|
||||
if ( Female = Utility.RandomBool() )
|
||||
{
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName( "female" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Body = 0x190;
|
||||
Name = NameList.RandomName( "male" );
|
||||
}
|
||||
|
||||
if ( !Female )
|
||||
AddItem( new LeatherNinjaHood() );
|
||||
|
||||
AddItem( new LeatherNinjaPants() );
|
||||
AddItem( new LeatherNinjaBelt() );
|
||||
AddItem( new LeatherNinjaJacket() );
|
||||
AddItem( new NinjaTabi() );
|
||||
|
||||
int hairHue = Utility.RandomNondyedHue();
|
||||
|
||||
|
||||
Utility.AssignRandomHair( this, hairHue );
|
||||
|
||||
if( Utility.Random( 7 ) != 0 )
|
||||
Utility.AssignRandomFacialHair( this, hairHue );
|
||||
|
||||
PackGold( 250, 300 );
|
||||
}
|
||||
|
||||
public Ninja( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.WriteEncodedInt( 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
84
Scripts/Mobiles/Townfolk/Noble.cs
Normal file
84
Scripts/Mobiles/Townfolk/Noble.cs
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using EDI = Server.Mobiles.EscortDestinationInfo;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Noble : BaseEscortable
|
||||
{
|
||||
[Constructable]
|
||||
public Noble()
|
||||
{
|
||||
Title = "the noble";
|
||||
|
||||
SetSkill( SkillName.Parry, 80.0, 100.0 );
|
||||
SetSkill( SkillName.Swords, 80.0, 100.0 );
|
||||
SetSkill( SkillName.Tactics, 80.0, 100.0 );
|
||||
}
|
||||
|
||||
public override bool CanTeach{ get{ return true; } }
|
||||
public override bool ClickTitle{ get{ return false; } } // Do not display 'the noble' when single-clicking
|
||||
|
||||
private static int GetRandomHue()
|
||||
{
|
||||
switch ( Utility.Random( 6 ) )
|
||||
{
|
||||
default:
|
||||
case 0: return 0;
|
||||
case 1: return Utility.RandomBlueHue();
|
||||
case 2: return Utility.RandomGreenHue();
|
||||
case 3: return Utility.RandomRedHue();
|
||||
case 4: return Utility.RandomYellowHue();
|
||||
case 5: return Utility.RandomNeutralHue();
|
||||
}
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
if ( Female )
|
||||
AddItem( new FancyDress() );
|
||||
else
|
||||
AddItem( new FancyShirt( GetRandomHue() ) );
|
||||
|
||||
int lowHue = GetRandomHue();
|
||||
|
||||
AddItem( new ShortPants( lowHue ) );
|
||||
|
||||
if ( Female )
|
||||
AddItem( new ThighBoots( lowHue ) );
|
||||
else
|
||||
AddItem( new Boots( lowHue ) );
|
||||
|
||||
if ( !Female )
|
||||
AddItem( new BodySash( lowHue ) );
|
||||
|
||||
AddItem( new Cloak( GetRandomHue() ) );
|
||||
|
||||
if ( !Female )
|
||||
AddItem( new Longsword() );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
|
||||
PackGold( 200, 250 );
|
||||
}
|
||||
|
||||
public Noble( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
81
Scripts/Mobiles/Townfolk/Peasant.cs
Normal file
81
Scripts/Mobiles/Townfolk/Peasant.cs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using EDI = Server.Mobiles.EscortDestinationInfo;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Peasant : BaseEscortable
|
||||
{
|
||||
[Constructable]
|
||||
public Peasant()
|
||||
{
|
||||
Title = "the peasant";
|
||||
|
||||
}
|
||||
|
||||
public override bool CanTeach{ get{ return true; } }
|
||||
public override bool ClickTitle{ get{ return false; } } // Do not display 'the peasant' when single-clicking
|
||||
|
||||
private static int GetRandomHue()
|
||||
{
|
||||
switch ( Utility.Random( 6 ) )
|
||||
{
|
||||
default:
|
||||
case 0: return 0;
|
||||
case 1: return Utility.RandomBlueHue();
|
||||
case 2: return Utility.RandomGreenHue();
|
||||
case 3: return Utility.RandomRedHue();
|
||||
case 4: return Utility.RandomYellowHue();
|
||||
case 5: return Utility.RandomNeutralHue();
|
||||
}
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
if ( Female )
|
||||
AddItem( new PlainDress() );
|
||||
else
|
||||
AddItem( new Shirt( GetRandomHue() ) );
|
||||
|
||||
int lowHue = GetRandomHue();
|
||||
|
||||
AddItem( new ShortPants( lowHue ) );
|
||||
|
||||
if ( Female )
|
||||
AddItem( new Boots( lowHue ) );
|
||||
else
|
||||
AddItem( new Shoes( lowHue ) );
|
||||
|
||||
//if ( !Female )
|
||||
//AddItem( new BodySash( lowHue ) );
|
||||
|
||||
//AddItem( new Cloak( GetRandomHue() ) );
|
||||
|
||||
//if ( !Female )
|
||||
//AddItem( new Longsword() );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
|
||||
PackGold( 200, 250 );
|
||||
}
|
||||
|
||||
public Peasant( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
83
Scripts/Mobiles/Townfolk/Prisoner.cs
Normal file
83
Scripts/Mobiles/Townfolk/Prisoner.cs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server.Engines.MLQuests;
|
||||
|
||||
namespace Server.Mobiles.Townfolk
|
||||
{
|
||||
public class Prisoner : BaseEscortable
|
||||
{
|
||||
[Constructable]
|
||||
public Prisoner()
|
||||
{
|
||||
Title = Female ? "the noblewoman" : "the nobleman";
|
||||
|
||||
CantWalk = true;
|
||||
IsPrisoner = true;
|
||||
}
|
||||
|
||||
public override bool CanTeach { get { return true; } }
|
||||
public override bool ClickTitle { get { return false; } }
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
if ( Female )
|
||||
{
|
||||
AddItem( new FancyDress( Utility.RandomNondyedHue() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem( new FancyShirt( Utility.RandomNondyedHue() ) );
|
||||
AddItem( new LongPants( Utility.RandomNondyedHue() ) );
|
||||
}
|
||||
|
||||
if ( Utility.RandomBool() )
|
||||
AddItem( new Boots() );
|
||||
else
|
||||
AddItem( new ThighBoots() );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
Utility.AssignRandomFacialHair( this, HairHue );
|
||||
}
|
||||
|
||||
public override void Shout( PlayerMobile pm )
|
||||
{
|
||||
/*
|
||||
* 502261 - HELP!
|
||||
* 502262 - Help me!
|
||||
* 502263 - Canst thou aid me?!
|
||||
* 502264 - Help a poor prisoner!
|
||||
* 502265 - Help! Please!
|
||||
* 502266 - Aaah! Help me!
|
||||
* 502267 - Go and get some help!
|
||||
*/
|
||||
MLQuestSystem.Tell( this, pm, Utility.Random( 502261, 7 ) );
|
||||
}
|
||||
|
||||
public override void OnMovement( Mobile m, Point3D oldLocation )
|
||||
{
|
||||
base.OnMovement( m, oldLocation );
|
||||
|
||||
if ( CantWalk && InRange( m, 1 ) && !InRange( oldLocation, 1 ) && ( !m.Hidden || m.AccessLevel == AccessLevel.Player ) )
|
||||
Say( 502268 ); // Quickly, I beg thee! Unlock my chains! If thou dost look at me close thou canst see them.
|
||||
}
|
||||
|
||||
public Prisoner( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
94
Scripts/Mobiles/Townfolk/Samurai.cs
Normal file
94
Scripts/Mobiles/Townfolk/Samurai.cs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Samurai : BaseCreature
|
||||
{
|
||||
public override bool CanTeach{ get{ return true; } }
|
||||
public override bool ClickTitle{ get{ return false; } }
|
||||
|
||||
[Constructable]
|
||||
public Samurai() : base( AIType.AI_Melee, FightMode.Aggressor, 10, 1, 0.2, 0.4 )
|
||||
{
|
||||
Title = "the samurai";
|
||||
|
||||
InitStats( 100, 100, 25 );
|
||||
|
||||
SetSkill( SkillName.ArmsLore, 64.0, 80.0 );
|
||||
SetSkill( SkillName.Bushido, 64.0, 85.0 );
|
||||
SetSkill( SkillName.Parry, 64.0, 80.0 );
|
||||
SetSkill( SkillName.Swords, 64.0, 85.0 );
|
||||
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
|
||||
Hue = Utility.RandomSkinHue();
|
||||
|
||||
if ( Female = Utility.RandomBool() )
|
||||
{
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName( "female" );
|
||||
}
|
||||
else
|
||||
{
|
||||
Body = 0x190;
|
||||
Name = NameList.RandomName( "male" );
|
||||
}
|
||||
|
||||
switch ( Utility.Random( 3 ) )
|
||||
{
|
||||
case 0: AddItem( new Lajatang() ); break;
|
||||
case 1: AddItem( new Wakizashi() ); break;
|
||||
case 2: AddItem( new NoDachi() ); break;
|
||||
}
|
||||
|
||||
switch ( Utility.Random( 3 ) )
|
||||
{
|
||||
case 0: AddItem( new LeatherSuneate() ); break;
|
||||
case 1: AddItem( new PlateSuneate() ); break;
|
||||
case 2: AddItem( new StuddedHaidate() ); break;
|
||||
}
|
||||
|
||||
switch ( Utility.Random( 4 ) )
|
||||
{
|
||||
case 0: AddItem( new LeatherJingasa() ); break;
|
||||
case 1: AddItem( new ChainHatsuburi() ); break;
|
||||
case 2: AddItem( new HeavyPlateJingasa() ); break;
|
||||
case 3: AddItem( new DecorativePlateKabuto() ); break;
|
||||
}
|
||||
|
||||
AddItem( new LeatherDo() );
|
||||
AddItem( new LeatherHiroSode() );
|
||||
AddItem( new SamuraiTabi( Utility.RandomNondyedHue() ) ); // TODO: Hue
|
||||
|
||||
int hairHue = Utility.RandomNondyedHue();
|
||||
|
||||
|
||||
Utility.AssignRandomHair( this, hairHue );
|
||||
|
||||
if( Utility.Random( 7 ) != 0 )
|
||||
Utility.AssignRandomFacialHair( this, hairHue );
|
||||
|
||||
PackGold( 250, 300 );
|
||||
}
|
||||
|
||||
public Samurai( Serial serial ) : base( serial )
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.WriteEncodedInt( 0 ); // version
|
||||
}
|
||||
|
||||
public override void Deserialize( GenericReader reader )
|
||||
{
|
||||
base.Deserialize( reader );
|
||||
|
||||
int version = reader.ReadEncodedInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Scripts/Mobiles/Townfolk/Sculptor.cs
Normal file
70
Scripts/Mobiles/Townfolk/Sculptor.cs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
using System;
|
||||
using Server.Items;
|
||||
using Server;
|
||||
using Server.Misc;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Sculptor : BaseCreature
|
||||
{
|
||||
[Constructable]
|
||||
public Sculptor()
|
||||
: base( AIType.AI_Animal, FightMode.None, 10, 1, 0.2, 0.4 )
|
||||
{
|
||||
InitStats( 31, 41, 51 );
|
||||
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
Title = "the sculptor";
|
||||
Hue = Utility.RandomSkinHue();
|
||||
|
||||
if( this.Female = Utility.RandomBool() )
|
||||
{
|
||||
this.Body = 0x191;
|
||||
this.Name = NameList.RandomName( "female" );
|
||||
AddItem( new Kilt( Utility.RandomNeutralHue() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Body = 0x190;
|
||||
this.Name = NameList.RandomName( "male" );
|
||||
AddItem( new LongPants( Utility.RandomNeutralHue() ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
AddItem( new Doublet( Utility.RandomNeutralHue() ) );
|
||||
AddItem( new HalfApron() );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
|
||||
Container pack = new Backpack();
|
||||
|
||||
pack.DropItem( new Gold( 250, 300 ) );
|
||||
|
||||
pack.Movable = false;
|
||||
|
||||
AddItem( pack );
|
||||
}
|
||||
|
||||
public override bool ClickTitle { get { return false; } }
|
||||
|
||||
public Sculptor( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
99
Scripts/Mobiles/Townfolk/SeekerOfAdventure.cs
Normal file
99
Scripts/Mobiles/Townfolk/SeekerOfAdventure.cs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using EDI = Server.Mobiles.EscortDestinationInfo;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class SeekerOfAdventure : BaseEscortable
|
||||
{
|
||||
private static string[] m_Dungeons = new string[]
|
||||
{
|
||||
"Covetous", "Deceit", "Despise",
|
||||
"Destard", "Hythloth", "Shame", // Old Code for Pre-ML shards.
|
||||
"Wrong"
|
||||
};
|
||||
|
||||
private static string[] m_MLDestinations = new string[]
|
||||
{
|
||||
"Cove", "Serpent's Hold", "Jhelom", // ML List
|
||||
"Nujel'm"
|
||||
};
|
||||
|
||||
public override string[] GetPossibleDestinations()
|
||||
{
|
||||
if ( Core.ML )
|
||||
return m_MLDestinations;
|
||||
else
|
||||
return m_Dungeons;
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public SeekerOfAdventure()
|
||||
{
|
||||
Title = "the seeker of adventure";
|
||||
}
|
||||
|
||||
public override bool ClickTitle{ get{ return false; } } // Do not display 'the seeker of adventure' when single-clicking
|
||||
|
||||
private static int GetRandomHue()
|
||||
{
|
||||
switch ( Utility.Random( 6 ) )
|
||||
{
|
||||
default:
|
||||
case 0: return 0;
|
||||
case 1: return Utility.RandomBlueHue();
|
||||
case 2: return Utility.RandomGreenHue();
|
||||
case 3: return Utility.RandomRedHue();
|
||||
case 4: return Utility.RandomYellowHue();
|
||||
case 5: return Utility.RandomNeutralHue();
|
||||
}
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
if ( Female )
|
||||
AddItem( new FancyDress( GetRandomHue() ) );
|
||||
else
|
||||
AddItem( new FancyShirt( GetRandomHue() ) );
|
||||
|
||||
int lowHue = GetRandomHue();
|
||||
|
||||
AddItem( new ShortPants( lowHue ) );
|
||||
|
||||
if ( Female )
|
||||
AddItem( new ThighBoots( lowHue ) );
|
||||
else
|
||||
AddItem( new Boots( lowHue ) );
|
||||
|
||||
if ( !Female )
|
||||
AddItem( new BodySash( lowHue ) );
|
||||
|
||||
AddItem( new Cloak( GetRandomHue() ) );
|
||||
|
||||
AddItem( new Longsword() );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
|
||||
PackGold( 100, 150 );
|
||||
}
|
||||
|
||||
public SeekerOfAdventure( 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
568
Scripts/Mobiles/Townfolk/TownCrier.cs
Normal file
568
Scripts/Mobiles/Townfolk/TownCrier.cs
Normal file
|
|
@ -0,0 +1,568 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
using System.Collections.Generic;
|
||||
using Server;
|
||||
using Server.Prompts;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Server.Items;
|
||||
using Server.Misc;
|
||||
using Server.Commands;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public interface ITownCrierEntryList
|
||||
{
|
||||
List<TownCrierEntry> Entries{ get; }
|
||||
TownCrierEntry GetRandomEntry();
|
||||
TownCrierEntry AddEntry( string[] lines, TimeSpan duration );
|
||||
void RemoveEntry( TownCrierEntry entry );
|
||||
}
|
||||
|
||||
public class GlobalTownCrierEntryList : ITownCrierEntryList
|
||||
{
|
||||
private static GlobalTownCrierEntryList m_Instance;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "TownCriers", AccessLevel.GameMaster, new CommandEventHandler( TownCriers_OnCommand ) );
|
||||
}
|
||||
|
||||
[Usage( "TownCriers" )]
|
||||
[Description( "Manages the global town crier list." )]
|
||||
public static void TownCriers_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
e.Mobile.SendGump( new TownCrierGump( e.Mobile, Instance ) );
|
||||
}
|
||||
|
||||
public static GlobalTownCrierEntryList Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_Instance == null )
|
||||
m_Instance = new GlobalTownCrierEntryList();
|
||||
|
||||
return m_Instance;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEmpty{ get{ return ( m_Entries == null || m_Entries.Count == 0 ); } }
|
||||
|
||||
public GlobalTownCrierEntryList()
|
||||
{
|
||||
}
|
||||
|
||||
private List<TownCrierEntry> m_Entries;
|
||||
|
||||
public List<TownCrierEntry> Entries
|
||||
{
|
||||
get{ return m_Entries; }
|
||||
}
|
||||
|
||||
public TownCrierEntry GetRandomEntry()
|
||||
{
|
||||
if ( m_Entries == null || m_Entries.Count == 0 )
|
||||
return null;
|
||||
|
||||
for ( int i = m_Entries.Count - 1; m_Entries != null && i >= 0; --i )
|
||||
{
|
||||
if ( i >= m_Entries.Count )
|
||||
continue;
|
||||
|
||||
TownCrierEntry tce = m_Entries[i];
|
||||
|
||||
if ( tce.Expired )
|
||||
RemoveEntry( tce );
|
||||
}
|
||||
|
||||
if ( m_Entries == null || m_Entries.Count == 0 )
|
||||
return null;
|
||||
|
||||
return m_Entries[Utility.Random( m_Entries.Count )];
|
||||
}
|
||||
|
||||
public TownCrierEntry AddEntry( string[] lines, TimeSpan duration )
|
||||
{
|
||||
if ( m_Entries == null )
|
||||
m_Entries = new List<TownCrierEntry>();
|
||||
|
||||
TownCrierEntry tce = new TownCrierEntry( lines, duration );
|
||||
|
||||
m_Entries.Add( tce );
|
||||
|
||||
List<TownCrier> instances = TownCrier.Instances;
|
||||
|
||||
for ( int i = 0; i < instances.Count; ++i )
|
||||
instances[i].ForceBeginAutoShout();
|
||||
|
||||
return tce;
|
||||
}
|
||||
|
||||
public void RemoveEntry( TownCrierEntry tce )
|
||||
{
|
||||
if ( m_Entries == null )
|
||||
return;
|
||||
|
||||
m_Entries.Remove( tce );
|
||||
|
||||
if ( m_Entries.Count == 0 )
|
||||
m_Entries = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class TownCrierEntry
|
||||
{
|
||||
private string[] m_Lines;
|
||||
private DateTime m_ExpireTime;
|
||||
|
||||
public string[] Lines{ get{ return m_Lines; } }
|
||||
public DateTime ExpireTime{ get{ return m_ExpireTime; } }
|
||||
public bool Expired{ get{ return ( DateTime.UtcNow >= m_ExpireTime ); } }
|
||||
|
||||
public TownCrierEntry( string[] lines, TimeSpan duration )
|
||||
{
|
||||
m_Lines = lines;
|
||||
|
||||
if ( duration < TimeSpan.Zero )
|
||||
duration = TimeSpan.Zero;
|
||||
else if ( duration > TimeSpan.FromDays( 365.0 ) )
|
||||
duration = TimeSpan.FromDays( 365.0 );
|
||||
|
||||
m_ExpireTime = DateTime.UtcNow + duration;
|
||||
}
|
||||
}
|
||||
|
||||
public class TownCrierDurationPrompt : Prompt
|
||||
{
|
||||
private ITownCrierEntryList m_Owner;
|
||||
|
||||
public TownCrierDurationPrompt( ITownCrierEntryList owner )
|
||||
{
|
||||
m_Owner = owner;
|
||||
}
|
||||
|
||||
public override void OnResponse( Mobile from, string text )
|
||||
{
|
||||
TimeSpan ts;
|
||||
|
||||
if( !TimeSpan.TryParse( text, out ts ) )
|
||||
{
|
||||
from.SendMessage( "Value was not properly formatted. Use: <hours:minutes:seconds>" );
|
||||
from.SendGump( new TownCrierGump( from, m_Owner ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ts < TimeSpan.Zero )
|
||||
ts = TimeSpan.Zero;
|
||||
|
||||
from.SendMessage( "Duration set to: {0}", ts );
|
||||
from.SendMessage( "Enter the first line to shout:" );
|
||||
|
||||
from.Prompt = new TownCrierLinesPrompt( m_Owner, null, new List<String>(), ts );
|
||||
}
|
||||
|
||||
public override void OnCancel( Mobile from )
|
||||
{
|
||||
from.SendLocalizedMessage( 502980 ); // Message entry cancelled.
|
||||
from.SendGump( new TownCrierGump( from, m_Owner ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class TownCrierLinesPrompt : Prompt
|
||||
{
|
||||
private ITownCrierEntryList m_Owner;
|
||||
private TownCrierEntry m_Entry;
|
||||
private List<String> m_Lines;
|
||||
private TimeSpan m_Duration;
|
||||
|
||||
public TownCrierLinesPrompt( ITownCrierEntryList owner, TownCrierEntry entry, List<String> lines, TimeSpan duration )
|
||||
{
|
||||
m_Owner = owner;
|
||||
m_Entry = entry;
|
||||
m_Lines = lines;
|
||||
m_Duration = duration;
|
||||
}
|
||||
|
||||
public override void OnResponse( Mobile from, string text )
|
||||
{
|
||||
m_Lines.Add( text );
|
||||
|
||||
from.SendMessage( "Enter the next line to shout, or press <ESC> if the message is finished." );
|
||||
from.Prompt = new TownCrierLinesPrompt( m_Owner, m_Entry, m_Lines, m_Duration );
|
||||
}
|
||||
|
||||
public override void OnCancel( Mobile from )
|
||||
{
|
||||
if ( m_Entry != null )
|
||||
m_Owner.RemoveEntry( m_Entry );
|
||||
|
||||
if ( m_Lines.Count > 0 )
|
||||
{
|
||||
m_Owner.AddEntry( m_Lines.ToArray(), m_Duration );
|
||||
from.SendMessage( "Message has been set." );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_Entry != null )
|
||||
from.SendMessage( "Message deleted." );
|
||||
else
|
||||
from.SendLocalizedMessage( 502980 ); // Message entry cancelled.
|
||||
}
|
||||
|
||||
from.SendGump( new TownCrierGump( from, m_Owner ) );
|
||||
}
|
||||
}
|
||||
|
||||
public class TownCrierGump : Gump
|
||||
{
|
||||
private Mobile m_From;
|
||||
private ITownCrierEntryList m_Owner;
|
||||
|
||||
public override void OnResponse( NetState sender, RelayInfo info )
|
||||
{
|
||||
if ( info.ButtonID == 1 )
|
||||
{
|
||||
m_From.SendMessage( "Enter the duration for the new message. Format: <hours:minutes:seconds>" );
|
||||
m_From.Prompt = new TownCrierDurationPrompt( m_Owner );
|
||||
}
|
||||
else if ( info.ButtonID > 1 )
|
||||
{
|
||||
List<TownCrierEntry> entries = m_Owner.Entries;
|
||||
int index = info.ButtonID - 2;
|
||||
|
||||
if ( entries != null && index < entries.Count )
|
||||
{
|
||||
TownCrierEntry tce = entries[index];
|
||||
TimeSpan ts = tce.ExpireTime - DateTime.UtcNow;
|
||||
|
||||
if ( ts < TimeSpan.Zero )
|
||||
ts = TimeSpan.Zero;
|
||||
|
||||
m_From.SendMessage( "Editing entry #{0}.", index + 1 );
|
||||
m_From.SendMessage( "Enter the first line to shout:" );
|
||||
m_From.Prompt = new TownCrierLinesPrompt( m_Owner, tce, new List<String>(), ts );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TownCrierGump( Mobile from, ITownCrierEntryList owner ) : base( 50, 50 )
|
||||
{
|
||||
m_From = from;
|
||||
m_Owner = owner;
|
||||
|
||||
from.CloseGump( typeof( TownCrierGump ) );
|
||||
|
||||
AddPage( 0 );
|
||||
|
||||
List<TownCrierEntry> entries = owner.Entries;
|
||||
|
||||
owner.GetRandomEntry(); // force expiration checks
|
||||
|
||||
int count = 0;
|
||||
|
||||
if ( entries != null )
|
||||
count = entries.Count;
|
||||
|
||||
AddImageTiled( 0, 0, 300, 38 + (count == 0 ? 20 : (count * 85)), 0xA40 );
|
||||
AddAlphaRegion( 1, 1, 298, 36 + (count == 0 ? 20 : (count * 85)) );
|
||||
|
||||
AddHtml( 8, 8, 300 - 8 - 30, 20, "<basefont color=#FFFFFF><center>TOWN CRIER MESSAGES</center></basefont>", false, false );
|
||||
|
||||
AddButton( 300 - 8 - 30, 8, 0xFAB, 0xFAD, 1, GumpButtonType.Reply, 0 );
|
||||
|
||||
if ( count == 0 )
|
||||
{
|
||||
AddHtml( 8, 30, 284, 20, "<basefont color=#FFFFFF>The crier has no news.</basefont>", false, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int i = 0; i < entries.Count; ++i )
|
||||
{
|
||||
TownCrierEntry tce = (TownCrierEntry)entries[i];
|
||||
|
||||
TimeSpan toExpire = tce.ExpireTime - DateTime.UtcNow;
|
||||
|
||||
if ( toExpire < TimeSpan.Zero )
|
||||
toExpire = TimeSpan.Zero;
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.Append( "[Expires: " );
|
||||
|
||||
if ( toExpire.TotalHours >= 1 )
|
||||
{
|
||||
sb.Append( (int)toExpire.TotalHours );
|
||||
sb.Append( ':' );
|
||||
sb.Append( toExpire.Minutes.ToString( "D2" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append( toExpire.Minutes );
|
||||
}
|
||||
|
||||
sb.Append( ':' );
|
||||
sb.Append( toExpire.Seconds.ToString( "D2" ) );
|
||||
|
||||
sb.Append( "] " );
|
||||
|
||||
for ( int j = 0; j < tce.Lines.Length; ++j )
|
||||
{
|
||||
if ( j > 0 )
|
||||
sb.Append( "<br>" );
|
||||
|
||||
sb.Append( tce.Lines[j] );
|
||||
}
|
||||
|
||||
AddHtml( 8, 35 + (i * 85), 254, 80, sb.ToString(), true, true );
|
||||
|
||||
AddButton( 300 - 8 - 26, 35 + (i * 85), 0x15E1, 0x15E5, 2 + i, GumpButtonType.Reply, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TownCrier : Mobile, ITownCrierEntryList
|
||||
{
|
||||
private List<TownCrierEntry> m_Entries;
|
||||
private Timer m_NewsTimer;
|
||||
private Timer m_AutoShoutTimer;
|
||||
|
||||
public List<TownCrierEntry> Entries
|
||||
{
|
||||
get{ return m_Entries; }
|
||||
}
|
||||
|
||||
public TownCrierEntry GetRandomEntry()
|
||||
{
|
||||
if ( m_Entries == null || m_Entries.Count == 0 )
|
||||
return GlobalTownCrierEntryList.Instance.GetRandomEntry();
|
||||
|
||||
for ( int i = m_Entries.Count - 1; m_Entries != null && i >= 0; --i )
|
||||
{
|
||||
if ( i >= m_Entries.Count )
|
||||
continue;
|
||||
|
||||
TownCrierEntry tce = m_Entries[i];
|
||||
|
||||
if ( tce.Expired )
|
||||
RemoveEntry( tce );
|
||||
}
|
||||
|
||||
if ( m_Entries == null || m_Entries.Count == 0 )
|
||||
return GlobalTownCrierEntryList.Instance.GetRandomEntry();
|
||||
|
||||
TownCrierEntry entry = GlobalTownCrierEntryList.Instance.GetRandomEntry();
|
||||
|
||||
if ( entry == null || Utility.RandomBool() )
|
||||
entry = m_Entries[Utility.Random( m_Entries.Count )];
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
public void ForceBeginAutoShout()
|
||||
{
|
||||
if ( m_AutoShoutTimer == null )
|
||||
m_AutoShoutTimer = Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromMinutes( 1.0 ), new TimerCallback( AutoShout_Callback ) );
|
||||
}
|
||||
|
||||
public TownCrierEntry AddEntry( string[] lines, TimeSpan duration )
|
||||
{
|
||||
if ( m_Entries == null )
|
||||
m_Entries = new List<TownCrierEntry>();
|
||||
|
||||
TownCrierEntry tce = new TownCrierEntry( lines, duration );
|
||||
|
||||
m_Entries.Add( tce );
|
||||
|
||||
if ( m_AutoShoutTimer == null )
|
||||
m_AutoShoutTimer = Timer.DelayCall( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromMinutes( 1.0 ), new TimerCallback( AutoShout_Callback ) );
|
||||
|
||||
return tce;
|
||||
}
|
||||
|
||||
public void RemoveEntry( TownCrierEntry tce )
|
||||
{
|
||||
if ( m_Entries == null )
|
||||
return;
|
||||
|
||||
m_Entries.Remove( tce );
|
||||
|
||||
if ( m_Entries.Count == 0 )
|
||||
m_Entries = null;
|
||||
|
||||
if ( m_Entries == null && GlobalTownCrierEntryList.Instance.IsEmpty )
|
||||
{
|
||||
if ( m_AutoShoutTimer != null )
|
||||
m_AutoShoutTimer.Stop();
|
||||
|
||||
m_AutoShoutTimer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void AutoShout_Callback()
|
||||
{
|
||||
TownCrierEntry tce = GetRandomEntry();
|
||||
|
||||
if ( tce == null )
|
||||
{
|
||||
if ( m_AutoShoutTimer != null )
|
||||
m_AutoShoutTimer.Stop();
|
||||
|
||||
m_AutoShoutTimer = null;
|
||||
}
|
||||
else if ( m_NewsTimer == null )
|
||||
{
|
||||
m_NewsTimer = Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), TimeSpan.FromSeconds( 3.0 ), new TimerStateCallback( ShoutNews_Callback ), new object[]{ tce, 0 } );
|
||||
|
||||
PublicOverheadMessage( MessageType.Regular, 0x3B2, 502976 ); // Hear ye! Hear ye!
|
||||
}
|
||||
}
|
||||
|
||||
private void ShoutNews_Callback( object state )
|
||||
{
|
||||
object[] states = (object[])state;
|
||||
TownCrierEntry tce = (TownCrierEntry)states[0];
|
||||
int index = (int)states[1];
|
||||
|
||||
if ( index < 0 || index >= tce.Lines.Length )
|
||||
{
|
||||
if ( m_NewsTimer != null )
|
||||
m_NewsTimer.Stop();
|
||||
|
||||
m_NewsTimer = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
PublicOverheadMessage( MessageType.Regular, 0x3B2, false, tce.Lines[index] );
|
||||
states[1] = index + 1;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnDoubleClick( Mobile from )
|
||||
{
|
||||
if ( from.AccessLevel >= AccessLevel.GameMaster )
|
||||
from.SendGump( new TownCrierGump( from, this ) );
|
||||
else
|
||||
base.OnDoubleClick( from );
|
||||
}
|
||||
|
||||
public override bool HandlesOnSpeech( Mobile from )
|
||||
{
|
||||
return ( m_NewsTimer == null && from.Alive && InRange( from, 12 ) );
|
||||
}
|
||||
|
||||
public override void OnSpeech( SpeechEventArgs e )
|
||||
{
|
||||
if ( m_NewsTimer == null && e.HasKeyword( 0x30 ) && e.Mobile.Alive && InRange( e.Mobile, 12 ) ) // *news*
|
||||
{
|
||||
Direction = GetDirectionTo( e.Mobile );
|
||||
|
||||
TownCrierEntry tce = GetRandomEntry();
|
||||
|
||||
if ( tce == null )
|
||||
{
|
||||
PublicOverheadMessage( MessageType.Regular, 0x3B2, 1005643 ); // I have no news at this time.
|
||||
}
|
||||
else
|
||||
{
|
||||
m_NewsTimer = Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), TimeSpan.FromSeconds( 3.0 ), new TimerStateCallback( ShoutNews_Callback ), new object[]{ tce, 0 } );
|
||||
|
||||
PublicOverheadMessage( MessageType.Regular, 0x3B2, 502978 ); // Some of the latest news!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static List<TownCrier> m_Instances = new List<TownCrier>();
|
||||
|
||||
public static List<TownCrier> Instances
|
||||
{
|
||||
get{ return m_Instances; }
|
||||
}
|
||||
|
||||
[Constructable]
|
||||
public TownCrier()
|
||||
{
|
||||
m_Instances.Add( this );
|
||||
|
||||
InitStats( 100, 100, 25 );
|
||||
|
||||
Title = "the town crier";
|
||||
Hue = Utility.RandomSkinHue();
|
||||
|
||||
if ( !Core.AOS )
|
||||
NameHue = 0x35;
|
||||
|
||||
if ( this.Female = Utility.RandomBool() )
|
||||
{
|
||||
this.Body = 0x191;
|
||||
this.Name = NameList.RandomName( "female" );
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Body = 0x190;
|
||||
this.Name = NameList.RandomName( "male" );
|
||||
}
|
||||
|
||||
AddItem( new FancyShirt( Utility.RandomBlueHue() ) );
|
||||
|
||||
Item skirt;
|
||||
|
||||
switch ( Utility.Random( 2 ) )
|
||||
{
|
||||
case 0: skirt = new Skirt(); break;
|
||||
default: case 1: skirt = new Kilt(); break;
|
||||
}
|
||||
|
||||
skirt.Hue = Utility.RandomGreenHue();
|
||||
|
||||
AddItem( skirt );
|
||||
|
||||
AddItem( new FeatheredHat( Utility.RandomGreenHue() ) );
|
||||
|
||||
Item boots;
|
||||
|
||||
switch ( Utility.Random( 2 ) )
|
||||
{
|
||||
case 0: boots = new Boots(); break;
|
||||
default: case 1: boots = new ThighBoots(); break;
|
||||
}
|
||||
|
||||
AddItem( boots );
|
||||
|
||||
Utility.AssignRandomHair( this );
|
||||
}
|
||||
|
||||
public override bool CanBeDamaged()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnDelete()
|
||||
{
|
||||
m_Instances.Remove( this );
|
||||
base.OnDelete();
|
||||
}
|
||||
|
||||
public TownCrier( Serial serial ) : base( serial )
|
||||
{
|
||||
m_Instances.Add( this );
|
||||
}
|
||||
|
||||
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 ( Core.AOS && NameHue == 0x35 )
|
||||
NameHue = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue