fix: Fixes ML Escortables and codegens (#1525)
### Summary - [X] Adds tot.json to ignore list. - [X] Fixes bias in escortable random quest selection. - [X] Adds New Haven specific destination/payment messages for escortable quests. - [X] Codegens escortables.
This commit is contained in:
parent
7d05e3b1cb
commit
d55406337f
40 changed files with 2382 additions and 2480 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -9,6 +9,7 @@
|
||||||
/Distribution/Configuration/modernuo.json
|
/Distribution/Configuration/modernuo.json
|
||||||
/Distribution/Configuration/email-settings.json
|
/Distribution/Configuration/email-settings.json
|
||||||
/Distribution/Configuration/throttles.json
|
/Distribution/Configuration/throttles.json
|
||||||
|
/Distribution/Configuration/tot.json
|
||||||
/Distribution/Logs
|
/Distribution/Logs
|
||||||
/Distribution/Archives
|
/Distribution/Archives
|
||||||
/Distribution/Backups
|
/Distribution/Backups
|
||||||
|
|
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Actor.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Actor.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Actor"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Artist.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Artist.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Artist"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Banker.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Banker.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Banker"
|
||||||
|
}
|
||||||
43
Projects/UOContent/Migrations/Server.Mobiles.BaseEscortable.v2.json
generated
Normal file
43
Projects/UOContent/Migrations/Server.Mobiles.BaseEscortable.v2.json
generated
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"type": "Server.Mobiles.BaseEscortable",
|
||||||
|
"properties": [
|
||||||
|
{
|
||||||
|
"name": "DestinationString",
|
||||||
|
"type": "string",
|
||||||
|
"rule": "PrimitiveTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DeleteTimer",
|
||||||
|
"type": "Server.Timer",
|
||||||
|
"rule": "TimerMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"@TimerDrift"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "MlQuestType",
|
||||||
|
"type": "System.Type",
|
||||||
|
"rule": "PrimitiveTypeMigrationRule"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "MlQuestDestinationMessage",
|
||||||
|
"type": "Server.TextDefinition",
|
||||||
|
"rule": "PrimitiveUOTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"TextDefinition"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "MlQuestPaymentMessage",
|
||||||
|
"type": "Server.TextDefinition",
|
||||||
|
"rule": "PrimitiveUOTypeMigrationRule",
|
||||||
|
"ruleArguments": [
|
||||||
|
"TextDefinition"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.BrideGroom.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.BrideGroom.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.BrideGroom"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.EscortableMage.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.EscortableMage.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.EscortableMage"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Gypsy.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Gypsy.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Gypsy"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.HarborMaster.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.HarborMaster.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.HarborMaster"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Merchant.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Merchant.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Merchant"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Messenger.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Messenger.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Messenger"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Minter.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Minter.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Minter"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Ninja.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Ninja.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Ninja"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Noble.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Noble.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Noble"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Peasant.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Peasant.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Peasant"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Samurai.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Samurai.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Samurai"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Sculptor.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Sculptor.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Sculptor"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.SeekerOfAdventure.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.SeekerOfAdventure.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.SeekerOfAdventure"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.TownCrier.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.TownCrier.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.TownCrier"
|
||||||
|
}
|
||||||
4
Projects/UOContent/Migrations/Server.Mobiles.Townfolk.Prisoner.v0.json
generated
Normal file
4
Projects/UOContent/Migrations/Server.Mobiles.Townfolk.Prisoner.v0.json
generated
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"version": 0,
|
||||||
|
"type": "Server.Mobiles.Townfolk.Prisoner"
|
||||||
|
}
|
||||||
|
|
@ -1091,31 +1091,9 @@ namespace Server.Mobiles
|
||||||
|
|
||||||
public HonorContext ReceivedHonorContext { get; set; }
|
public HonorContext ReceivedHonorContext { get; set; }
|
||||||
|
|
||||||
public List<MLQuest> MLQuests
|
public List<MLQuest> MLQuests =>
|
||||||
{
|
// Assign the quests if we don't have one, and if it is still null, return an empty list
|
||||||
get
|
(m_MLQuests ??= StaticMLQuester ? MLQuestSystem.FindQuestList(GetType()) : ConstructQuestList()) ?? MLQuestSystem.EmptyList;
|
||||||
{
|
|
||||||
if (m_MLQuests == null)
|
|
||||||
{
|
|
||||||
if (StaticMLQuester)
|
|
||||||
{
|
|
||||||
m_MLQuests = MLQuestSystem.FindQuestList(GetType());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_MLQuests = ConstructQuestList();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_MLQuests == null)
|
|
||||||
{
|
|
||||||
// return EmptyList, but don't cache it (run construction again next time)
|
|
||||||
return MLQuestSystem.EmptyList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m_MLQuests;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual MonsterAbility[] GetMonsterAbilities() => null;
|
public virtual MonsterAbility[] GetMonsterAbilities() => null;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,65 +1,48 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class Actor : BaseCreature
|
||||||
{
|
{
|
||||||
public class Actor : BaseCreature
|
[Constructible]
|
||||||
|
public Actor() : base(AIType.AI_Animal, FightMode.None)
|
||||||
{
|
{
|
||||||
[Constructible]
|
InitStats(31, 41, 51);
|
||||||
public Actor() : base(AIType.AI_Animal, FightMode.None)
|
|
||||||
|
SetSpeed(0.2, 0.4);
|
||||||
|
SpeechHue = Utility.RandomDyedHue();
|
||||||
|
Hue = Race.Human.RandomSkinHue();
|
||||||
|
|
||||||
|
if (Female = Utility.RandomBool())
|
||||||
{
|
{
|
||||||
InitStats(31, 41, 51);
|
Body = 0x191;
|
||||||
|
Name = NameList.RandomName("female");
|
||||||
SetSpeed(0.2, 0.4);
|
AddItem(new FancyDress(Utility.RandomDyedHue()));
|
||||||
SpeechHue = Utility.RandomDyedHue();
|
Title = "the actress";
|
||||||
Hue = Race.Human.RandomSkinHue();
|
}
|
||||||
|
else
|
||||||
if (Female = Utility.RandomBool())
|
{
|
||||||
{
|
Body = 0x190;
|
||||||
Body = 0x191;
|
Name = NameList.RandomName("male");
|
||||||
Name = NameList.RandomName("female");
|
AddItem(new LongPants(Utility.RandomNeutralHue()));
|
||||||
AddItem(new FancyDress(Utility.RandomDyedHue()));
|
AddItem(new FancyShirt(Utility.RandomDyedHue()));
|
||||||
Title = "the actress";
|
Title = "the actor";
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Body = 0x190;
|
|
||||||
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 Actor(Serial serial) : base(serial)
|
AddItem(new Boots(Utility.RandomNeutralHue()));
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool ClickTitle => false;
|
Utility.AssignRandomHair(this);
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
Container pack = new Backpack();
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
pack.DropItem(new Gold(250, 300));
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
pack.Movable = false;
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
AddItem(pack);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool ClickTitle => false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,68 +1,50 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class Artist : BaseCreature
|
||||||
{
|
{
|
||||||
public class Artist : BaseCreature
|
[Constructible]
|
||||||
|
public Artist() : base(AIType.AI_Animal, FightMode.None)
|
||||||
{
|
{
|
||||||
[Constructible]
|
InitStats(31, 41, 51);
|
||||||
public Artist() : base(AIType.AI_Animal, FightMode.None)
|
SetSkill(SkillName.Healing, 36, 68);
|
||||||
|
|
||||||
|
SetSpeed(0.2, 0.4);
|
||||||
|
SpeechHue = Utility.RandomDyedHue();
|
||||||
|
Title = "the artist";
|
||||||
|
Hue = Race.Human.RandomSkinHue();
|
||||||
|
|
||||||
|
if (Female = Utility.RandomBool())
|
||||||
{
|
{
|
||||||
InitStats(31, 41, 51);
|
Body = 0x191;
|
||||||
SetSkill(SkillName.Healing, 36, 68);
|
Name = NameList.RandomName("female");
|
||||||
|
}
|
||||||
SetSpeed(0.2, 0.4);
|
else
|
||||||
SpeechHue = Utility.RandomDyedHue();
|
{
|
||||||
Title = "the artist";
|
Body = 0x190;
|
||||||
Hue = Race.Human.RandomSkinHue();
|
Name = NameList.RandomName("male");
|
||||||
|
|
||||||
if (Female = Utility.RandomBool())
|
|
||||||
{
|
|
||||||
Body = 0x191;
|
|
||||||
Name = NameList.RandomName("female");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Body = 0x190;
|
|
||||||
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 Artist(Serial serial)
|
AddItem(new Doublet(Utility.RandomDyedHue()));
|
||||||
: base(serial)
|
AddItem(new Sandals(Utility.RandomNeutralHue()));
|
||||||
{
|
AddItem(new ShortPants(Utility.RandomNeutralHue()));
|
||||||
}
|
AddItem(new HalfApron(Utility.RandomDyedHue()));
|
||||||
|
|
||||||
public override bool CanTeach => true;
|
Utility.AssignRandomHair(this);
|
||||||
|
|
||||||
public override bool ClickTitle => false;
|
Container pack = new Backpack();
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
pack.DropItem(new Gold(250, 300));
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
pack.Movable = false;
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
AddItem(pack);
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool CanTeach => true;
|
||||||
|
|
||||||
|
public override bool ClickTitle => false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,481 +1,464 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Accounting;
|
using Server.Accounting;
|
||||||
using Server.ContextMenus;
|
using Server.ContextMenus;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class Banker : BaseVendor
|
||||||
{
|
{
|
||||||
public class Banker : BaseVendor
|
private readonly List<SBInfo> m_SBInfos = new();
|
||||||
|
|
||||||
|
[Constructible]
|
||||||
|
public Banker() : base("the banker")
|
||||||
{
|
{
|
||||||
private readonly List<SBInfo> m_SBInfos = new();
|
}
|
||||||
|
|
||||||
[Constructible]
|
protected override List<SBInfo> SBInfos => m_SBInfos;
|
||||||
public Banker() : base("the banker")
|
|
||||||
|
public override NpcGuild NpcGuild => NpcGuild.MerchantsGuild;
|
||||||
|
|
||||||
|
public override void InitSBInfo()
|
||||||
|
{
|
||||||
|
m_SBInfos.Add(new SBBanker());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetBalance(Mobile m)
|
||||||
|
{
|
||||||
|
long balance = 0;
|
||||||
|
|
||||||
|
if (AccountGold.Enabled && m.Account != null)
|
||||||
{
|
{
|
||||||
|
balance = m.Account.GetTotalGold();
|
||||||
|
if (balance >= int.MaxValue)
|
||||||
|
{
|
||||||
|
return int.MaxValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Banker(Serial serial) : base(serial)
|
Container bank = m.FindBankNoCreate();
|
||||||
|
|
||||||
|
if (bank != null)
|
||||||
{
|
{
|
||||||
|
foreach (var gold in bank.FindItemsByType<Gold>())
|
||||||
|
{
|
||||||
|
balance += gold.Amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (balance >= int.MaxValue)
|
||||||
|
{
|
||||||
|
return int.MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var check in bank.FindItemsByType<BankCheck>())
|
||||||
|
{
|
||||||
|
balance += check.Worth;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override List<SBInfo> SBInfos => m_SBInfos;
|
return (int)Math.Clamp(balance, 0, int.MaxValue);
|
||||||
|
}
|
||||||
|
|
||||||
public override NpcGuild NpcGuild => NpcGuild.MerchantsGuild;
|
public static int GetBalance(Mobile m, out List<Item> gold, out List<Item> checks)
|
||||||
|
{
|
||||||
|
long balance = 0;
|
||||||
|
gold = checks = new List<Item>();
|
||||||
|
|
||||||
public override void InitSBInfo()
|
if (AccountGold.Enabled && m.Account != null)
|
||||||
{
|
{
|
||||||
m_SBInfos.Add(new SBBanker());
|
balance = m.Account.GetTotalGold();
|
||||||
|
|
||||||
|
if (balance >= int.MaxValue)
|
||||||
|
{
|
||||||
|
return int.MaxValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetBalance(Mobile m)
|
Container bank = m.FindBankNoCreate();
|
||||||
|
|
||||||
|
if (bank != null)
|
||||||
{
|
{
|
||||||
long balance = 0;
|
foreach (var g in bank.FindItemsByType<Gold>())
|
||||||
|
|
||||||
if (AccountGold.Enabled && m.Account != null)
|
|
||||||
{
|
{
|
||||||
balance = m.Account.GetTotalGold();
|
balance += g.Amount;
|
||||||
if (balance >= int.MaxValue)
|
gold.Add(g);
|
||||||
{
|
|
||||||
return int.MaxValue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Container bank = m.FindBankNoCreate();
|
if (balance >= int.MaxValue)
|
||||||
|
|
||||||
if (bank != null)
|
|
||||||
{
|
{
|
||||||
foreach (var gold in bank.FindItemsByType<Gold>())
|
return int.MaxValue;
|
||||||
{
|
|
||||||
balance += gold.Amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (balance >= int.MaxValue)
|
|
||||||
{
|
|
||||||
return int.MaxValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var check in bank.FindItemsByType<BankCheck>())
|
|
||||||
{
|
|
||||||
balance += check.Worth;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int)Math.Clamp(balance, 0, int.MaxValue);
|
foreach (var bc in bank.FindItemsByType<BankCheck>())
|
||||||
|
{
|
||||||
|
balance += bc.Worth;
|
||||||
|
checks.Add(bc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int GetBalance(Mobile m, out List<Item> gold, out List<Item> checks)
|
return (int)Math.Clamp(balance, 0, int.MaxValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
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?.WithdrawGold(amount) == true)
|
||||||
{
|
{
|
||||||
long balance = 0;
|
|
||||||
gold = checks = new List<Item>();
|
|
||||||
|
|
||||||
if (AccountGold.Enabled && m.Account != null)
|
|
||||||
{
|
|
||||||
balance = m.Account.GetTotalGold();
|
|
||||||
|
|
||||||
if (balance >= int.MaxValue)
|
|
||||||
{
|
|
||||||
return int.MaxValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Container bank = m.FindBankNoCreate();
|
|
||||||
|
|
||||||
if (bank != null)
|
|
||||||
{
|
|
||||||
foreach (var g in bank.FindItemsByType<Gold>())
|
|
||||||
{
|
|
||||||
balance += g.Amount;
|
|
||||||
gold.Add(g);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (balance >= int.MaxValue)
|
|
||||||
{
|
|
||||||
return int.MaxValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var bc in bank.FindItemsByType<BankCheck>())
|
|
||||||
{
|
|
||||||
balance += bc.Worth;
|
|
||||||
checks.Add(bc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int)Math.Clamp(balance, 0, int.MaxValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
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?.WithdrawGold(amount) == true)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
var balance = GetBalance(from, out var gold, out var checks);
|
|
||||||
|
|
||||||
if (balance < amount)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; amount > 0 && i < gold.Count; ++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.Count; ++i)
|
|
||||||
{
|
|
||||||
var check = (BankCheck)checks[i];
|
|
||||||
|
|
||||||
if (check.Worth <= amount)
|
|
||||||
{
|
|
||||||
amount -= check.Worth;
|
|
||||||
check.Delete();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
check.Worth -= amount;
|
|
||||||
amount = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool Deposit(Mobile from, int amount)
|
var balance = GetBalance(from, out var gold, out var checks);
|
||||||
|
|
||||||
|
if (balance < amount)
|
||||||
{
|
{
|
||||||
// If for whatever reason the TOL checks fail, we should still try old methods for depositing currency.
|
return false;
|
||||||
if (AccountGold.Enabled && from.Account?.DepositGold(amount) == true)
|
}
|
||||||
|
|
||||||
|
for (var i = 0; amount > 0 && i < gold.Count; ++i)
|
||||||
|
{
|
||||||
|
if (gold[i].Amount <= amount)
|
||||||
{
|
{
|
||||||
return true;
|
amount -= gold[i].Amount;
|
||||||
|
gold[i].Delete();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
var box = from.FindBankNoCreate();
|
|
||||||
|
|
||||||
if (box == null)
|
|
||||||
{
|
{
|
||||||
return false;
|
gold[i].Amount -= amount;
|
||||||
|
amount = 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var items = new List<Item>();
|
for (var i = 0; amount > 0 && i < checks.Count; ++i)
|
||||||
|
{
|
||||||
|
var check = (BankCheck)checks[i];
|
||||||
|
|
||||||
while (amount > 0)
|
if (check.Worth <= amount)
|
||||||
{
|
{
|
||||||
Item item;
|
amount -= check.Worth;
|
||||||
if (amount < 5000)
|
check.Delete();
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
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?.DepositGold(amount) == true)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int DepositUpTo(Mobile from, int amount)
|
var box = from.FindBankNoCreate();
|
||||||
|
|
||||||
|
if (box == null)
|
||||||
{
|
{
|
||||||
// If for whatever reason the TOL checks fail, we should still try old methods for depositing currency.
|
return false;
|
||||||
if (AccountGold.Enabled && from.Account?.DepositGold(amount) == true)
|
|
||||||
{
|
|
||||||
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)
|
var items = new List<Item>();
|
||||||
|
|
||||||
|
while (amount > 0)
|
||||||
{
|
{
|
||||||
while (amount > 0)
|
Item item;
|
||||||
|
if (amount < 5000)
|
||||||
{
|
{
|
||||||
Item item;
|
item = new Gold(amount);
|
||||||
|
amount = 0;
|
||||||
|
}
|
||||||
|
else if (amount <= 1000000)
|
||||||
|
{
|
||||||
|
item = new BankCheck(amount);
|
||||||
|
amount = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item = new BankCheck(1000000);
|
||||||
|
amount -= 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
if (amount < 5000)
|
if (box.TryDropItem(from, item, false))
|
||||||
|
{
|
||||||
|
items.Add(item);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.Delete();
|
||||||
|
foreach (var curItem in items)
|
||||||
{
|
{
|
||||||
item = new Gold(amount);
|
curItem.Delete();
|
||||||
amount = 0;
|
|
||||||
}
|
|
||||||
else if (amount <= 1000000)
|
|
||||||
{
|
|
||||||
item = new BankCheck(amount);
|
|
||||||
amount = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
item = new BankCheck(1000000);
|
|
||||||
amount -= 1000000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cont.DropItem(item);
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HandlesOnSpeech(Mobile from) => from.InRange(Location, 12) || base.HandlesOnSpeech(from);
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public override void OnSpeech(SpeechEventArgs e)
|
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?.DepositGold(amount) == true)
|
||||||
{
|
{
|
||||||
if (!e.Handled && e.Mobile.InRange(Location, 12))
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
var box = from.FindBankNoCreate();
|
||||||
|
|
||||||
|
if (box == null)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var amountLeft = amount;
|
||||||
|
while (amountLeft > 0)
|
||||||
|
{
|
||||||
|
Item item;
|
||||||
|
int amountGiven;
|
||||||
|
|
||||||
|
if (amountLeft < 5000)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < e.Keywords.Length; ++i)
|
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 override bool HandlesOnSpeech(Mobile from) => from.InRange(Location, 12) || base.HandlesOnSpeech(from);
|
||||||
|
|
||||||
|
public override void OnSpeech(SpeechEventArgs e)
|
||||||
|
{
|
||||||
|
if (!e.Handled && e.Mobile.InRange(Location, 12))
|
||||||
|
{
|
||||||
|
for (var i = 0; i < e.Keywords.Length; ++i)
|
||||||
|
{
|
||||||
|
var keyword = e.Keywords[i];
|
||||||
|
|
||||||
|
switch (keyword)
|
||||||
{
|
{
|
||||||
var keyword = e.Keywords[i];
|
case 0x0000: // *withdraw*
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
|
||||||
switch (keyword)
|
if (e.Mobile.Criminal)
|
||||||
{
|
|
||||||
case 0x0000: // *withdraw*
|
|
||||||
{
|
{
|
||||||
e.Handled = true;
|
Say(500389); // I will not do business with a criminal!
|
||||||
|
|
||||||
if (e.Mobile.Criminal)
|
|
||||||
{
|
|
||||||
Say(500389); // I will not do business with a criminal!
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
var split = e.Speech.Split(' ');
|
|
||||||
|
|
||||||
if (split.Length >= 2)
|
|
||||||
{
|
|
||||||
var pack = e.Mobile.Backpack;
|
|
||||||
|
|
||||||
if (!int.TryParse(split[1], out var amount))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Core.ML && amount > 5000 || Core.ML && amount > 60000)
|
|
||||||
{
|
|
||||||
Say(500381); // Thou canst not withdraw so much at one time!
|
|
||||||
}
|
|
||||||
else if (pack?.Deleted != false || !(pack.TotalWeight < pack.MaxWeight) ||
|
|
||||||
!(pack.TotalItems < pack.MaxItems))
|
|
||||||
{
|
|
||||||
Say(1048147); // Your backpack can't hold anything else.
|
|
||||||
}
|
|
||||||
else if (amount > 0)
|
|
||||||
{
|
|
||||||
var box = e.Mobile.FindBankNoCreate();
|
|
||||||
|
|
||||||
if (box == null || !Withdraw(e.Mobile, amount))
|
|
||||||
{
|
|
||||||
Say(500384); // Ah, art thou trying to fool me? Thou hast not so much gold!
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pack.DropItem(new Gold(amount));
|
|
||||||
|
|
||||||
Say(1010005); // Thou hast withdrawn gold from thy account.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x0001: // *balance*
|
|
||||||
|
var split = e.Speech.Split(' ');
|
||||||
|
|
||||||
|
if (split.Length >= 2)
|
||||||
{
|
{
|
||||||
e.Handled = true;
|
var pack = e.Mobile.Backpack;
|
||||||
|
|
||||||
if (e.Mobile.Criminal)
|
if (!int.TryParse(split[1], out var amount))
|
||||||
{
|
|
||||||
Say(500389); // I will not do business with a criminal!
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (AccountGold.Enabled && e.Mobile.Account != null)
|
|
||||||
{
|
|
||||||
Say(
|
|
||||||
1155855,
|
|
||||||
$"{e.Mobile.Account.TotalPlat:#,0}\t{e.Mobile.Account.TotalGold:#,0}"
|
|
||||||
); // Thy current bank balance is ~1_AMOUNT~ platinum and ~2_AMOUNT~ gold.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Thy current bank balance is ~1_AMOUNT~ gold.
|
|
||||||
Say(1042759, $"{GetBalance(e.Mobile):N0}");
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 0x0002: // *bank*
|
|
||||||
{
|
|
||||||
e.Handled = true;
|
|
||||||
|
|
||||||
if (e.Mobile.Criminal)
|
|
||||||
{
|
|
||||||
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e.Mobile.Criminal)
|
if (!Core.ML && amount > 5000 || Core.ML && amount > 60000)
|
||||||
{
|
{
|
||||||
Say(500389); // I will not do business with a criminal!
|
Say(500381); // Thou canst not withdraw so much at one time!
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else if (pack?.Deleted != false || !(pack.TotalWeight < pack.MaxWeight) ||
|
||||||
var split = e.Speech.Split(' ');
|
!(pack.TotalItems < pack.MaxItems))
|
||||||
|
|
||||||
if (split.Length >= 2)
|
|
||||||
{
|
{
|
||||||
if (!int.TryParse(split[1], out var amount))
|
Say(1048147); // Your backpack can't hold anything else.
|
||||||
|
}
|
||||||
|
else if (amount > 0)
|
||||||
|
{
|
||||||
|
var box = e.Mobile.FindBankNoCreate();
|
||||||
|
|
||||||
|
if (box == null || !Withdraw(e.Mobile, amount))
|
||||||
{
|
{
|
||||||
break;
|
Say(500384); // Ah, art thou trying to fool me? Thou hast not so much gold!
|
||||||
}
|
|
||||||
|
|
||||||
if (amount < 5000)
|
|
||||||
{
|
|
||||||
Say(1010006); // We cannot create checks for such a paltry amount of gold!
|
|
||||||
}
|
|
||||||
else if (amount > 1000000)
|
|
||||||
{
|
|
||||||
Say(1010007); // Our policies prevent us from creating checks worth that much!
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var check = new BankCheck(amount);
|
pack.DropItem(new Gold(amount));
|
||||||
|
|
||||||
var box = e.Mobile.BankBox;
|
Say(1010005); // Thou hast withdrawn gold from thy account.
|
||||||
|
|
||||||
if (!box.TryDropItem(e.Mobile, check, false))
|
|
||||||
{
|
|
||||||
Say(500386); // There's not enough room in your bankbox for the check!
|
|
||||||
check.Delete();
|
|
||||||
}
|
|
||||||
else if (!box.ConsumeTotal(typeof(Gold), amount))
|
|
||||||
{
|
|
||||||
Say(500384); // Ah, art thou trying to fool me? Thou hast not so much gold!
|
|
||||||
check.Delete();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Say(
|
|
||||||
1042673, // Into your bank box I have placed a check in the amount of:
|
|
||||||
AffixType.Append,
|
|
||||||
amount.ToString(),
|
|
||||||
""
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x0001: // *balance*
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
|
||||||
|
if (e.Mobile.Criminal)
|
||||||
|
{
|
||||||
|
Say(500389); // I will not do business with a criminal!
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (AccountGold.Enabled && e.Mobile.Account != null)
|
||||||
|
{
|
||||||
|
Say(
|
||||||
|
1155855,
|
||||||
|
$"{e.Mobile.Account.TotalPlat:#,0}\t{e.Mobile.Account.TotalGold:#,0}"
|
||||||
|
); // Thy current bank balance is ~1_AMOUNT~ platinum and ~2_AMOUNT~ gold.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Thy current bank balance is ~1_AMOUNT~ gold.
|
||||||
|
Say(1042759, $"{GetBalance(e.Mobile):N0}");
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x0002: // *bank*
|
||||||
|
{
|
||||||
|
e.Handled = true;
|
||||||
|
|
||||||
|
if (e.Mobile.Criminal)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Say(500389); // I will not do business with a criminal!
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var split = e.Speech.Split(' ');
|
||||||
|
|
||||||
|
if (split.Length >= 2)
|
||||||
|
{
|
||||||
|
if (!int.TryParse(split[1], out var amount))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (amount < 5000)
|
||||||
|
{
|
||||||
|
Say(1010006); // We cannot create checks for such a paltry amount of gold!
|
||||||
|
}
|
||||||
|
else if (amount > 1000000)
|
||||||
|
{
|
||||||
|
Say(1010007); // Our policies prevent us from creating checks worth that much!
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var check = new BankCheck(amount);
|
||||||
|
|
||||||
|
var box = e.Mobile.BankBox;
|
||||||
|
|
||||||
|
if (!box.TryDropItem(e.Mobile, check, false))
|
||||||
|
{
|
||||||
|
Say(500386); // There's not enough room in your bankbox for the check!
|
||||||
|
check.Delete();
|
||||||
|
}
|
||||||
|
else if (!box.ConsumeTotal(typeof(Gold), amount))
|
||||||
|
{
|
||||||
|
Say(500384); // Ah, art thou trying to fool me? Thou hast not so much gold!
|
||||||
|
check.Delete();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Say(
|
||||||
|
1042673, // Into your bank box I have placed a check in the amount of:
|
||||||
|
AffixType.Append,
|
||||||
|
amount.ToString(),
|
||||||
|
""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base.OnSpeech(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void AddCustomContextEntries(Mobile from, List<ContextMenuEntry> list)
|
base.OnSpeech(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void AddCustomContextEntries(Mobile from, List<ContextMenuEntry> list)
|
||||||
|
{
|
||||||
|
if (from.Alive)
|
||||||
{
|
{
|
||||||
if (from.Alive)
|
list.Add(new OpenBankEntry(this));
|
||||||
{
|
|
||||||
list.Add(new OpenBankEntry(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
base.AddCustomContextEntries(from, list);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
base.AddCustomContextEntries(from, list);
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,93 +1,76 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class BrideGroom : BaseEscortable
|
||||||
{
|
{
|
||||||
public class BrideGroom : BaseEscortable
|
[Constructible]
|
||||||
|
public BrideGroom()
|
||||||
{
|
{
|
||||||
[Constructible]
|
if (Female)
|
||||||
public BrideGroom()
|
|
||||||
{
|
{
|
||||||
if (Female)
|
Title = "the bride";
|
||||||
{
|
|
||||||
Title = "the bride";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Title = "the groom";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
public BrideGroom(Serial serial) : base(serial)
|
|
||||||
{
|
{
|
||||||
}
|
Title = "the groom";
|
||||||
|
|
||||||
public override bool CanTeach => true;
|
|
||||||
public override bool ClickTitle => false; // Do not display 'the groom' when single-clicking
|
|
||||||
|
|
||||||
private static int GetRandomHue()
|
|
||||||
{
|
|
||||||
return Utility.Random(6) switch
|
|
||||||
{
|
|
||||||
0 => 0,
|
|
||||||
1 => Utility.RandomBlueHue(),
|
|
||||||
2 => Utility.RandomGreenHue(),
|
|
||||||
3 => Utility.RandomRedHue(),
|
|
||||||
4 => Utility.RandomYellowHue(),
|
|
||||||
5 => Utility.RandomNeutralHue(),
|
|
||||||
_ => 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void InitOutfit()
|
|
||||||
{
|
|
||||||
if (Female)
|
|
||||||
{
|
|
||||||
AddItem(new FancyDress());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddItem(new FancyShirt());
|
|
||||||
}
|
|
||||||
|
|
||||||
var 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 = Race.RandomHairHue();
|
|
||||||
|
|
||||||
PackGold(200, 250);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool CanTeach => true;
|
||||||
|
public override bool ClickTitle => false; // Do not display 'the groom' when single-clicking
|
||||||
|
|
||||||
|
private static int GetRandomHue()
|
||||||
|
{
|
||||||
|
return Utility.Random(6) switch
|
||||||
|
{
|
||||||
|
0 => 0,
|
||||||
|
1 => Utility.RandomBlueHue(),
|
||||||
|
2 => Utility.RandomGreenHue(),
|
||||||
|
3 => Utility.RandomRedHue(),
|
||||||
|
4 => Utility.RandomYellowHue(),
|
||||||
|
5 => Utility.RandomNeutralHue(),
|
||||||
|
_ => 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void InitOutfit()
|
||||||
|
{
|
||||||
|
if (Female)
|
||||||
|
{
|
||||||
|
AddItem(new FancyDress());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddItem(new FancyShirt());
|
||||||
|
}
|
||||||
|
|
||||||
|
var 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 = Race.RandomHairHue();
|
||||||
|
|
||||||
|
PackGold(200, 250);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,75 +1,58 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class EscortableMage : BaseEscortable
|
||||||
{
|
{
|
||||||
public class EscortableMage : BaseEscortable
|
[Constructible]
|
||||||
|
public EscortableMage()
|
||||||
{
|
{
|
||||||
[Constructible]
|
Title = "the mage";
|
||||||
public EscortableMage()
|
|
||||||
{
|
|
||||||
Title = "the mage";
|
|
||||||
|
|
||||||
SetSkill(SkillName.EvalInt, 80.0, 100.0);
|
SetSkill(SkillName.EvalInt, 80.0, 100.0);
|
||||||
SetSkill(SkillName.Inscribe, 80.0, 100.0);
|
SetSkill(SkillName.Inscribe, 80.0, 100.0);
|
||||||
SetSkill(SkillName.Magery, 80.0, 100.0);
|
SetSkill(SkillName.Magery, 80.0, 100.0);
|
||||||
SetSkill(SkillName.Meditation, 80.0, 100.0);
|
SetSkill(SkillName.Meditation, 80.0, 100.0);
|
||||||
SetSkill(SkillName.MagicResist, 80.0, 100.0);
|
SetSkill(SkillName.MagicResist, 80.0, 100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanTeach => true;
|
||||||
|
public override bool ClickTitle => false; // Do not display 'the mage' when single-clicking
|
||||||
|
|
||||||
|
private static int GetRandomHue()
|
||||||
|
{
|
||||||
|
return Utility.Random(5) switch
|
||||||
|
{
|
||||||
|
0 => Utility.RandomBlueHue(),
|
||||||
|
1 => Utility.RandomGreenHue(),
|
||||||
|
2 => Utility.RandomRedHue(),
|
||||||
|
3 => Utility.RandomYellowHue(),
|
||||||
|
4 => Utility.RandomNeutralHue(),
|
||||||
|
_ => Utility.RandomBlueHue()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void InitOutfit()
|
||||||
|
{
|
||||||
|
AddItem(new Robe(GetRandomHue()));
|
||||||
|
|
||||||
|
var lowHue = GetRandomHue();
|
||||||
|
|
||||||
|
AddItem(new ShortPants(lowHue));
|
||||||
|
|
||||||
|
if (Female)
|
||||||
|
{
|
||||||
|
AddItem(new ThighBoots(lowHue));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddItem(new Boots(lowHue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public EscortableMage(Serial serial) : base(serial)
|
Utility.AssignRandomHair(this);
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CanTeach => true;
|
PackGold(200, 250);
|
||||||
public override bool ClickTitle => false; // Do not display 'the mage' when single-clicking
|
|
||||||
|
|
||||||
private static int GetRandomHue()
|
|
||||||
{
|
|
||||||
return Utility.Random(5) switch
|
|
||||||
{
|
|
||||||
0 => Utility.RandomBlueHue(),
|
|
||||||
1 => Utility.RandomGreenHue(),
|
|
||||||
2 => Utility.RandomRedHue(),
|
|
||||||
3 => Utility.RandomYellowHue(),
|
|
||||||
4 => Utility.RandomNeutralHue(),
|
|
||||||
_ => Utility.RandomBlueHue()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void InitOutfit()
|
|
||||||
{
|
|
||||||
AddItem(new Robe(GetRandomHue()));
|
|
||||||
|
|
||||||
var lowHue = GetRandomHue();
|
|
||||||
|
|
||||||
AddItem(new ShortPants(lowHue));
|
|
||||||
|
|
||||||
if (Female)
|
|
||||||
{
|
|
||||||
AddItem(new ThighBoots(lowHue));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddItem(new Boots(lowHue));
|
|
||||||
}
|
|
||||||
|
|
||||||
Utility.AssignRandomHair(this);
|
|
||||||
|
|
||||||
PackGold(200, 250);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,74 +1,56 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class Gypsy : BaseCreature
|
||||||
{
|
{
|
||||||
public class Gypsy : BaseCreature
|
[Constructible]
|
||||||
|
public Gypsy() : base(AIType.AI_Animal, FightMode.None)
|
||||||
{
|
{
|
||||||
[Constructible]
|
InitStats(31, 41, 51);
|
||||||
public Gypsy() : base(AIType.AI_Animal, FightMode.None)
|
SetSkill(SkillName.Cooking, 65, 88);
|
||||||
|
SetSkill(SkillName.Snooping, 65, 88);
|
||||||
|
SetSkill(SkillName.Stealing, 65, 88);
|
||||||
|
|
||||||
|
SetSpeed(0.2, 0.4);
|
||||||
|
SpeechHue = Utility.RandomDyedHue();
|
||||||
|
Hue = Race.Human.RandomSkinHue();
|
||||||
|
|
||||||
|
if (Female = Utility.RandomBool())
|
||||||
{
|
{
|
||||||
InitStats(31, 41, 51);
|
Body = 0x191;
|
||||||
SetSkill(SkillName.Cooking, 65, 88);
|
Name = NameList.RandomName("female");
|
||||||
SetSkill(SkillName.Snooping, 65, 88);
|
AddItem(new Kilt(Utility.RandomDyedHue()));
|
||||||
SetSkill(SkillName.Stealing, 65, 88);
|
AddItem(new Shirt(Utility.RandomDyedHue()));
|
||||||
|
AddItem(new ThighBoots());
|
||||||
SetSpeed(0.2, 0.4);
|
Title = "the gypsy";
|
||||||
SpeechHue = Utility.RandomDyedHue();
|
}
|
||||||
Hue = Race.Human.RandomSkinHue();
|
else
|
||||||
|
{
|
||||||
if (Female = Utility.RandomBool())
|
Body = 0x190;
|
||||||
{
|
Name = NameList.RandomName("male");
|
||||||
Body = 0x191;
|
AddItem(new ShortPants(Utility.RandomNeutralHue()));
|
||||||
Name = NameList.RandomName("female");
|
AddItem(new Shirt(Utility.RandomDyedHue()));
|
||||||
AddItem(new Kilt(Utility.RandomDyedHue()));
|
AddItem(new Sandals());
|
||||||
AddItem(new Shirt(Utility.RandomDyedHue()));
|
Title = "the gypsy";
|
||||||
AddItem(new ThighBoots());
|
|
||||||
Title = "the gypsy";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Body = 0x190;
|
|
||||||
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 Gypsy(Serial serial)
|
AddItem(new Bandana(Utility.RandomDyedHue()));
|
||||||
: base(serial)
|
AddItem(new Dagger());
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CanTeach => true;
|
Utility.AssignRandomHair(this);
|
||||||
public override bool ClickTitle => false;
|
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
Container pack = new Backpack();
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
pack.DropItem(new Gold(250, 300));
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
pack.Movable = false;
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
AddItem(pack);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool CanTeach => true;
|
||||||
|
public override bool ClickTitle => false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,70 +1,52 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class HarborMaster : BaseCreature
|
||||||
{
|
{
|
||||||
public class HarborMaster : BaseCreature
|
[Constructible]
|
||||||
|
public HarborMaster() : base(AIType.AI_Animal, FightMode.None)
|
||||||
{
|
{
|
||||||
[Constructible]
|
InitStats(31, 41, 51);
|
||||||
public HarborMaster() : base(AIType.AI_Animal, FightMode.None)
|
SetSkill(SkillName.Mining, 36, 68);
|
||||||
|
|
||||||
|
SetSpeed(0.2, 0.4);
|
||||||
|
SpeechHue = Utility.RandomDyedHue();
|
||||||
|
Hue = Race.Human.RandomSkinHue();
|
||||||
|
Blessed = true;
|
||||||
|
|
||||||
|
if (Female = Utility.RandomBool())
|
||||||
{
|
{
|
||||||
InitStats(31, 41, 51);
|
Body = 0x191;
|
||||||
SetSkill(SkillName.Mining, 36, 68);
|
Name = NameList.RandomName("female");
|
||||||
|
Title = "the Harbor Mistress";
|
||||||
SetSpeed(0.2, 0.4);
|
}
|
||||||
SpeechHue = Utility.RandomDyedHue();
|
else
|
||||||
Hue = Race.Human.RandomSkinHue();
|
{
|
||||||
Blessed = true;
|
Body = 0x190;
|
||||||
|
Name = NameList.RandomName("male");
|
||||||
if (Female = Utility.RandomBool())
|
Title = "the Harbor Master";
|
||||||
{
|
|
||||||
Body = 0x191;
|
|
||||||
Name = NameList.RandomName("female");
|
|
||||||
Title = "the Harbor Mistress";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Body = 0x190;
|
|
||||||
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 HarborMaster(Serial serial)
|
AddItem(new Shirt(Utility.RandomDyedHue()));
|
||||||
: base(serial)
|
AddItem(new Boots());
|
||||||
{
|
AddItem(new LongPants(Utility.RandomNeutralHue()));
|
||||||
}
|
AddItem(new QuarterStaff());
|
||||||
|
|
||||||
public override bool CanTeach => false;
|
Utility.AssignRandomHair(this);
|
||||||
|
|
||||||
public override bool ClickTitle => false;
|
Container pack = new Backpack();
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
pack.DropItem(new Gold(250, 300));
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
pack.Movable = false;
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
AddItem(pack);
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool CanTeach => false;
|
||||||
|
|
||||||
|
public override bool ClickTitle => false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,90 +1,72 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class Merchant : BaseEscortable
|
||||||
{
|
{
|
||||||
public class Merchant : BaseEscortable
|
[Constructible]
|
||||||
|
public Merchant()
|
||||||
{
|
{
|
||||||
[Constructible]
|
Title = "the merchant";
|
||||||
public Merchant()
|
SetSkill(SkillName.ItemID, 55.0, 78.0);
|
||||||
|
SetSkill(SkillName.ArmsLore, 55, 78);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanTeach => true;
|
||||||
|
public override bool ClickTitle => false; // Do not display 'the merchant' when single-clicking
|
||||||
|
|
||||||
|
private static int GetRandomHue()
|
||||||
|
{
|
||||||
|
return Utility.Random(6) switch
|
||||||
{
|
{
|
||||||
Title = "the merchant";
|
0 => 0,
|
||||||
SetSkill(SkillName.ItemID, 55.0, 78.0);
|
1 => Utility.RandomBlueHue(),
|
||||||
SetSkill(SkillName.ArmsLore, 55, 78);
|
2 => Utility.RandomGreenHue(),
|
||||||
|
3 => Utility.RandomRedHue(),
|
||||||
|
4 => Utility.RandomYellowHue(),
|
||||||
|
5 => Utility.RandomNeutralHue(),
|
||||||
|
_ => 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void InitOutfit()
|
||||||
|
{
|
||||||
|
if (Female)
|
||||||
|
{
|
||||||
|
AddItem(new PlainDress());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddItem(new Shirt(GetRandomHue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Merchant(Serial serial)
|
var lowHue = GetRandomHue();
|
||||||
: base(serial)
|
|
||||||
|
AddItem(new ThighBoots());
|
||||||
|
|
||||||
|
if (Female)
|
||||||
{
|
{
|
||||||
|
AddItem(new FancyDress(lowHue));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddItem(new FancyShirt(lowHue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanTeach => true;
|
AddItem(new LongPants(lowHue));
|
||||||
public override bool ClickTitle => false; // Do not display 'the merchant' when single-clicking
|
|
||||||
|
|
||||||
private static int GetRandomHue()
|
if (!Female)
|
||||||
{
|
{
|
||||||
return Utility.Random(6) switch
|
AddItem(new BodySash(lowHue));
|
||||||
{
|
|
||||||
0 => 0,
|
|
||||||
1 => Utility.RandomBlueHue(),
|
|
||||||
2 => Utility.RandomGreenHue(),
|
|
||||||
3 => Utility.RandomRedHue(),
|
|
||||||
4 => Utility.RandomYellowHue(),
|
|
||||||
5 => Utility.RandomNeutralHue(),
|
|
||||||
_ => 0
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void InitOutfit()
|
// if (!Female)
|
||||||
{
|
// AddItem( new Longsword() );
|
||||||
if (Female)
|
|
||||||
{
|
|
||||||
AddItem(new PlainDress());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddItem(new Shirt(GetRandomHue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var lowHue = GetRandomHue();
|
Utility.AssignRandomHair(this);
|
||||||
|
|
||||||
AddItem(new ThighBoots());
|
PackGold(200, 250);
|
||||||
|
|
||||||
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 override void Serialize(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,76 +1,59 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class Messenger : BaseEscortable
|
||||||
{
|
{
|
||||||
public class Messenger : BaseEscortable
|
[Constructible]
|
||||||
|
public Messenger() => Title = "the messenger";
|
||||||
|
|
||||||
|
public override bool CanTeach => true;
|
||||||
|
public override bool ClickTitle => false; // Do not display 'the messenger' when single-clicking
|
||||||
|
|
||||||
|
private static int GetRandomHue()
|
||||||
{
|
{
|
||||||
[Constructible]
|
return Utility.Random(6) switch
|
||||||
public Messenger() => Title = "the messenger";
|
|
||||||
|
|
||||||
public Messenger(Serial serial) : base(serial)
|
|
||||||
{
|
{
|
||||||
|
1 => Utility.RandomBlueHue(),
|
||||||
|
2 => Utility.RandomGreenHue(),
|
||||||
|
3 => Utility.RandomRedHue(),
|
||||||
|
4 => Utility.RandomYellowHue(),
|
||||||
|
5 => Utility.RandomNeutralHue(),
|
||||||
|
_ => 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void InitOutfit()
|
||||||
|
{
|
||||||
|
if (Female)
|
||||||
|
{
|
||||||
|
AddItem(new PlainDress());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddItem(new Shirt(GetRandomHue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanTeach => true;
|
var lowHue = GetRandomHue();
|
||||||
public override bool ClickTitle => false; // Do not display 'the messenger' when single-clicking
|
|
||||||
|
|
||||||
private static int GetRandomHue()
|
AddItem(new ShortPants(lowHue));
|
||||||
|
|
||||||
|
if (Female)
|
||||||
{
|
{
|
||||||
return Utility.Random(6) switch
|
AddItem(new Boots(lowHue));
|
||||||
{
|
}
|
||||||
1 => Utility.RandomBlueHue(),
|
else
|
||||||
2 => Utility.RandomGreenHue(),
|
{
|
||||||
3 => Utility.RandomRedHue(),
|
AddItem(new Shoes(lowHue));
|
||||||
4 => Utility.RandomYellowHue(),
|
|
||||||
5 => Utility.RandomNeutralHue(),
|
|
||||||
_ => 0
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void InitOutfit()
|
var randomHair = Utility.Random(4);
|
||||||
{
|
HairItemID = randomHair == 4 ? 0x203B : 0x2048 + randomHair;
|
||||||
if (Female)
|
|
||||||
{
|
|
||||||
AddItem(new PlainDress());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddItem(new Shirt(GetRandomHue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var lowHue = GetRandomHue();
|
HairHue = Race.RandomHairHue();
|
||||||
|
|
||||||
AddItem(new ShortPants(lowHue));
|
PackGold(200, 250);
|
||||||
|
|
||||||
if (Female)
|
|
||||||
{
|
|
||||||
AddItem(new Boots(lowHue));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddItem(new Shoes(lowHue));
|
|
||||||
}
|
|
||||||
|
|
||||||
var randomHair = Utility.Random(4);
|
|
||||||
HairItemID = randomHair == 4 ? 0x203B : 0x2048 + randomHair;
|
|
||||||
|
|
||||||
HairHue = Race.RandomHairHue();
|
|
||||||
|
|
||||||
PackGold(200, 250);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,12 @@
|
||||||
namespace Server.Mobiles
|
using ModernUO.Serialization;
|
||||||
|
|
||||||
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class Minter : Banker
|
||||||
{
|
{
|
||||||
public class Minter : Banker
|
[Constructible]
|
||||||
{
|
public Minter() => Title = "the minter";
|
||||||
[Constructible]
|
|
||||||
public Minter() => Title = "the minter";
|
|
||||||
|
|
||||||
public Minter(Serial serial) : base(serial)
|
public override NpcGuild NpcGuild => NpcGuild.MerchantsGuild;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override NpcGuild NpcGuild => NpcGuild.MerchantsGuild;
|
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,78 +1,61 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0)]
|
||||||
|
public partial class Ninja : BaseCreature
|
||||||
{
|
{
|
||||||
public class Ninja : BaseCreature
|
[Constructible]
|
||||||
|
public Ninja() : base(AIType.AI_Melee, FightMode.Aggressor)
|
||||||
{
|
{
|
||||||
[Constructible]
|
Title = "the ninja";
|
||||||
public Ninja() : base(AIType.AI_Melee, FightMode.Aggressor)
|
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);
|
||||||
|
|
||||||
|
SetSpeed(0.2, 0.4);
|
||||||
|
SpeechHue = Utility.RandomDyedHue();
|
||||||
|
Hue = Race.Human.RandomSkinHue();
|
||||||
|
|
||||||
|
if (Female = Utility.RandomBool())
|
||||||
{
|
{
|
||||||
Title = "the ninja";
|
Body = 0x191;
|
||||||
InitStats(100, 100, 25);
|
Name = NameList.RandomName("female");
|
||||||
|
}
|
||||||
SetSkill(SkillName.Fencing, 64.0, 80.0);
|
else
|
||||||
SetSkill(SkillName.Macing, 64.0, 80.0);
|
{
|
||||||
SetSkill(SkillName.Ninjitsu, 60.0, 80.0);
|
Body = 0x190;
|
||||||
SetSkill(SkillName.Parry, 64.0, 80.0);
|
Name = NameList.RandomName("male");
|
||||||
SetSkill(SkillName.Tactics, 64.0, 85.0);
|
|
||||||
SetSkill(SkillName.Swords, 64.0, 85.0);
|
|
||||||
|
|
||||||
SetSpeed(0.2, 0.4);
|
|
||||||
SpeechHue = Utility.RandomDyedHue();
|
|
||||||
Hue = Race.Human.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());
|
|
||||||
|
|
||||||
var 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)
|
if (!Female)
|
||||||
{
|
{
|
||||||
|
AddItem(new LeatherNinjaHood());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanTeach => true;
|
AddItem(new LeatherNinjaPants());
|
||||||
public override bool ClickTitle => false;
|
AddItem(new LeatherNinjaBelt());
|
||||||
|
AddItem(new LeatherNinjaJacket());
|
||||||
|
AddItem(new NinjaTabi());
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
var hairHue = Utility.RandomNondyedHue();
|
||||||
|
|
||||||
|
Utility.AssignRandomHair(this, hairHue);
|
||||||
|
|
||||||
|
if (Utility.Random(7) != 0)
|
||||||
{
|
{
|
||||||
base.Serialize(writer);
|
Utility.AssignRandomFacialHair(this, hairHue);
|
||||||
|
|
||||||
writer.WriteEncodedInt(0); // version
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
PackGold(250, 300);
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadEncodedInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool CanTeach => true;
|
||||||
|
public override bool ClickTitle => false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,92 +1,75 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class Noble : BaseEscortable
|
||||||
{
|
{
|
||||||
public class Noble : BaseEscortable
|
[Constructible]
|
||||||
|
public Noble()
|
||||||
{
|
{
|
||||||
[Constructible]
|
Title = "the noble";
|
||||||
public Noble()
|
|
||||||
{
|
|
||||||
Title = "the noble";
|
|
||||||
|
|
||||||
SetSkill(SkillName.Parry, 80.0, 100.0);
|
SetSkill(SkillName.Parry, 80.0, 100.0);
|
||||||
SetSkill(SkillName.Swords, 80.0, 100.0);
|
SetSkill(SkillName.Swords, 80.0, 100.0);
|
||||||
SetSkill(SkillName.Tactics, 80.0, 100.0);
|
SetSkill(SkillName.Tactics, 80.0, 100.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanTeach => true;
|
||||||
|
public override bool ClickTitle => false; // Do not display 'the noble' when single-clicking
|
||||||
|
|
||||||
|
private static int GetRandomHue()
|
||||||
|
{
|
||||||
|
return Utility.Random(6) switch
|
||||||
|
{
|
||||||
|
1 => Utility.RandomBlueHue(),
|
||||||
|
2 => Utility.RandomGreenHue(),
|
||||||
|
3 => Utility.RandomRedHue(),
|
||||||
|
4 => Utility.RandomYellowHue(),
|
||||||
|
5 => Utility.RandomNeutralHue(),
|
||||||
|
_ => 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void InitOutfit()
|
||||||
|
{
|
||||||
|
if (Female)
|
||||||
|
{
|
||||||
|
AddItem(new FancyDress());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddItem(new FancyShirt(GetRandomHue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Noble(Serial serial) : base(serial)
|
var lowHue = GetRandomHue();
|
||||||
|
|
||||||
|
AddItem(new ShortPants(lowHue));
|
||||||
|
|
||||||
|
if (Female)
|
||||||
{
|
{
|
||||||
|
AddItem(new ThighBoots(lowHue));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddItem(new Boots(lowHue));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanTeach => true;
|
if (!Female)
|
||||||
public override bool ClickTitle => false; // Do not display 'the noble' when single-clicking
|
|
||||||
|
|
||||||
private static int GetRandomHue()
|
|
||||||
{
|
{
|
||||||
return Utility.Random(6) switch
|
AddItem(new BodySash(lowHue));
|
||||||
{
|
|
||||||
1 => Utility.RandomBlueHue(),
|
|
||||||
2 => Utility.RandomGreenHue(),
|
|
||||||
3 => Utility.RandomRedHue(),
|
|
||||||
4 => Utility.RandomYellowHue(),
|
|
||||||
5 => Utility.RandomNeutralHue(),
|
|
||||||
_ => 0
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void InitOutfit()
|
AddItem(new Cloak(GetRandomHue()));
|
||||||
|
|
||||||
|
if (!Female)
|
||||||
{
|
{
|
||||||
if (Female)
|
AddItem(new Longsword());
|
||||||
{
|
|
||||||
AddItem(new FancyDress());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddItem(new FancyShirt(GetRandomHue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var 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 override void Serialize(IGenericWriter writer)
|
Utility.AssignRandomHair(this);
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
PackGold(200, 250);
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,82 +1,65 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class Peasant : BaseEscortable
|
||||||
{
|
{
|
||||||
public class Peasant : BaseEscortable
|
[Constructible]
|
||||||
|
public Peasant() => Title = "the peasant";
|
||||||
|
|
||||||
|
public override bool CanTeach => true;
|
||||||
|
public override bool ClickTitle => false; // Do not display 'the peasant' when single-clicking
|
||||||
|
|
||||||
|
private static int GetRandomHue()
|
||||||
{
|
{
|
||||||
[Constructible]
|
return Utility.Random(6) switch
|
||||||
public Peasant() => Title = "the peasant";
|
|
||||||
|
|
||||||
public Peasant(Serial serial) : base(serial)
|
|
||||||
{
|
{
|
||||||
|
0 => 0,
|
||||||
|
1 => Utility.RandomBlueHue(),
|
||||||
|
2 => Utility.RandomGreenHue(),
|
||||||
|
3 => Utility.RandomRedHue(),
|
||||||
|
4 => Utility.RandomYellowHue(),
|
||||||
|
5 => Utility.RandomNeutralHue(),
|
||||||
|
_ => 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void InitOutfit()
|
||||||
|
{
|
||||||
|
if (Female)
|
||||||
|
{
|
||||||
|
AddItem(new PlainDress());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddItem(new Shirt(GetRandomHue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanTeach => true;
|
var lowHue = GetRandomHue();
|
||||||
public override bool ClickTitle => false; // Do not display 'the peasant' when single-clicking
|
|
||||||
|
|
||||||
private static int GetRandomHue()
|
AddItem(new ShortPants(lowHue));
|
||||||
|
|
||||||
|
if (Female)
|
||||||
{
|
{
|
||||||
return Utility.Random(6) switch
|
AddItem(new Boots(lowHue));
|
||||||
{
|
}
|
||||||
0 => 0,
|
else
|
||||||
1 => Utility.RandomBlueHue(),
|
{
|
||||||
2 => Utility.RandomGreenHue(),
|
AddItem(new Shoes(lowHue));
|
||||||
3 => Utility.RandomRedHue(),
|
|
||||||
4 => Utility.RandomYellowHue(),
|
|
||||||
5 => Utility.RandomNeutralHue(),
|
|
||||||
_ => 0
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void InitOutfit()
|
// if (!Female)
|
||||||
{
|
// AddItem( new BodySash( lowHue ) );
|
||||||
if (Female)
|
|
||||||
{
|
|
||||||
AddItem(new PlainDress());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddItem(new Shirt(GetRandomHue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var lowHue = GetRandomHue();
|
// AddItem( new Cloak( GetRandomHue() ) );
|
||||||
|
|
||||||
AddItem(new ShortPants(lowHue));
|
// if (!Female)
|
||||||
|
// AddItem( new Longsword() );
|
||||||
|
|
||||||
if (Female)
|
Utility.AssignRandomHair(this);
|
||||||
{
|
|
||||||
AddItem(new Boots(lowHue));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddItem(new Shoes(lowHue));
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (!Female)
|
PackGold(200, 250);
|
||||||
// AddItem( new BodySash( lowHue ) );
|
|
||||||
|
|
||||||
// AddItem( new Cloak( GetRandomHue() ) );
|
|
||||||
|
|
||||||
// if (!Female)
|
|
||||||
// AddItem( new Longsword() );
|
|
||||||
|
|
||||||
Utility.AssignRandomHair(this);
|
|
||||||
|
|
||||||
PackGold(200, 250);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,88 +1,70 @@
|
||||||
using Server.Engines.MLQuests;
|
using ModernUO.Serialization;
|
||||||
|
using Server.Engines.MLQuests;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles.Townfolk
|
namespace Server.Mobiles.Townfolk;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class Prisoner : BaseEscortable
|
||||||
{
|
{
|
||||||
public class Prisoner : BaseEscortable
|
[Constructible]
|
||||||
|
public Prisoner()
|
||||||
{
|
{
|
||||||
[Constructible]
|
Title = Female ? "the noblewoman" : "the nobleman";
|
||||||
public Prisoner()
|
|
||||||
{
|
|
||||||
Title = Female ? "the noblewoman" : "the nobleman";
|
|
||||||
|
|
||||||
CantWalk = true;
|
CantWalk = true;
|
||||||
IsPrisoner = true;
|
IsPrisoner = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool CanTeach => true;
|
||||||
|
public override bool ClickTitle => false;
|
||||||
|
|
||||||
|
public override void InitOutfit()
|
||||||
|
{
|
||||||
|
if (Female)
|
||||||
|
{
|
||||||
|
AddItem(new FancyDress(Utility.RandomNondyedHue()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddItem(new FancyShirt(Utility.RandomNondyedHue()));
|
||||||
|
AddItem(new LongPants(Utility.RandomNondyedHue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Prisoner(Serial serial)
|
if (Utility.RandomBool())
|
||||||
: base(serial)
|
|
||||||
{
|
{
|
||||||
|
AddItem(new Boots());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AddItem(new ThighBoots());
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanTeach => true;
|
Utility.AssignRandomHair(this);
|
||||||
public override bool ClickTitle => false;
|
Utility.AssignRandomFacialHair(this, HairHue);
|
||||||
|
}
|
||||||
|
|
||||||
public override void InitOutfit()
|
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))
|
||||||
{
|
{
|
||||||
if (Female)
|
Say(502268); // Quickly, I beg thee! Unlock my chains! If thou dost look at me close thou canst see them.
|
||||||
{
|
|
||||||
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 override void Serialize(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,113 +1,116 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0)]
|
||||||
|
public partial class Samurai : BaseCreature
|
||||||
{
|
{
|
||||||
public class Samurai : BaseCreature
|
[Constructible]
|
||||||
|
public Samurai() : base(AIType.AI_Melee, FightMode.Aggressor)
|
||||||
{
|
{
|
||||||
[Constructible]
|
Title = "the samurai";
|
||||||
public Samurai() : base(AIType.AI_Melee, FightMode.Aggressor)
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
SetSpeed(0.2, 0.4);
|
||||||
|
SpeechHue = Utility.RandomDyedHue();
|
||||||
|
Hue = Race.Human.RandomSkinHue();
|
||||||
|
|
||||||
|
if (Female = Utility.RandomBool())
|
||||||
{
|
{
|
||||||
Title = "the samurai";
|
Body = 0x191;
|
||||||
|
Name = NameList.RandomName("female");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Body = 0x190;
|
||||||
|
Name = NameList.RandomName("male");
|
||||||
|
}
|
||||||
|
|
||||||
InitStats(100, 100, 25);
|
switch (Utility.Random(3))
|
||||||
|
{
|
||||||
SetSkill(SkillName.ArmsLore, 64.0, 80.0);
|
case 0:
|
||||||
SetSkill(SkillName.Bushido, 64.0, 85.0);
|
{
|
||||||
SetSkill(SkillName.Parry, 64.0, 80.0);
|
|
||||||
SetSkill(SkillName.Swords, 64.0, 85.0);
|
|
||||||
|
|
||||||
SetSpeed(0.2, 0.4);
|
|
||||||
SpeechHue = Utility.RandomDyedHue();
|
|
||||||
Hue = Race.Human.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());
|
AddItem(new Lajatang());
|
||||||
break;
|
break;
|
||||||
case 1:
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
AddItem(new Wakizashi());
|
AddItem(new Wakizashi());
|
||||||
break;
|
break;
|
||||||
case 2:
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
AddItem(new NoDachi());
|
AddItem(new NoDachi());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (Utility.Random(3))
|
switch (Utility.Random(3))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
{
|
||||||
AddItem(new LeatherSuneate());
|
AddItem(new LeatherSuneate());
|
||||||
break;
|
break;
|
||||||
case 1:
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
AddItem(new PlateSuneate());
|
AddItem(new PlateSuneate());
|
||||||
break;
|
break;
|
||||||
case 2:
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
AddItem(new StuddedHaidate());
|
AddItem(new StuddedHaidate());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (Utility.Random(4))
|
switch (Utility.Random(4))
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
{
|
||||||
AddItem(new LeatherJingasa());
|
AddItem(new LeatherJingasa());
|
||||||
break;
|
break;
|
||||||
case 1:
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
AddItem(new ChainHatsuburi());
|
AddItem(new ChainHatsuburi());
|
||||||
break;
|
break;
|
||||||
case 2:
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
AddItem(new HeavyPlateJingasa());
|
AddItem(new HeavyPlateJingasa());
|
||||||
break;
|
break;
|
||||||
case 3:
|
}
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
AddItem(new DecorativePlateKabuto());
|
AddItem(new DecorativePlateKabuto());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddItem(new LeatherDo());
|
|
||||||
AddItem(new LeatherHiroSode());
|
|
||||||
AddItem(new SamuraiTabi(Utility.RandomNondyedHue())); // TODO: Hue
|
|
||||||
|
|
||||||
var 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)
|
AddItem(new LeatherDo());
|
||||||
|
AddItem(new LeatherHiroSode());
|
||||||
|
AddItem(new SamuraiTabi(Utility.RandomNondyedHue())); // TODO: Hue
|
||||||
|
|
||||||
|
var hairHue = Utility.RandomNondyedHue();
|
||||||
|
|
||||||
|
Utility.AssignRandomHair(this, hairHue);
|
||||||
|
|
||||||
|
if (Utility.Random(7) != 0)
|
||||||
{
|
{
|
||||||
|
Utility.AssignRandomFacialHair(this, hairHue);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool CanTeach => true;
|
PackGold(250, 300);
|
||||||
public override bool ClickTitle => false;
|
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.WriteEncodedInt(0); // version
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadEncodedInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool CanTeach => true;
|
||||||
|
public override bool ClickTitle => false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,65 +1,47 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class Sculptor : BaseCreature
|
||||||
{
|
{
|
||||||
public class Sculptor : BaseCreature
|
[Constructible]
|
||||||
|
public Sculptor() : base(AIType.AI_Animal, FightMode.None)
|
||||||
{
|
{
|
||||||
[Constructible]
|
InitStats(31, 41, 51);
|
||||||
public Sculptor() : base(AIType.AI_Animal, FightMode.None)
|
|
||||||
|
SetSpeed(0.2, 0.4);
|
||||||
|
SpeechHue = Utility.RandomDyedHue();
|
||||||
|
Title = "the sculptor";
|
||||||
|
Hue = Race.Human.RandomSkinHue();
|
||||||
|
|
||||||
|
if (Female = Utility.RandomBool())
|
||||||
{
|
{
|
||||||
InitStats(31, 41, 51);
|
Body = 0x191;
|
||||||
|
Name = NameList.RandomName("female");
|
||||||
SetSpeed(0.2, 0.4);
|
AddItem(new Kilt(Utility.RandomNeutralHue()));
|
||||||
SpeechHue = Utility.RandomDyedHue();
|
}
|
||||||
Title = "the sculptor";
|
else
|
||||||
Hue = Race.Human.RandomSkinHue();
|
{
|
||||||
|
Body = 0x190;
|
||||||
if (Female = Utility.RandomBool())
|
Name = NameList.RandomName("male");
|
||||||
{
|
AddItem(new LongPants(Utility.RandomNeutralHue()));
|
||||||
Body = 0x191;
|
|
||||||
Name = NameList.RandomName("female");
|
|
||||||
AddItem(new Kilt(Utility.RandomNeutralHue()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Body = 0x190;
|
|
||||||
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 Sculptor(Serial serial)
|
AddItem(new Doublet(Utility.RandomNeutralHue()));
|
||||||
: base(serial)
|
AddItem(new HalfApron());
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool ClickTitle => false;
|
Utility.AssignRandomHair(this);
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
Container pack = new Backpack();
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
pack.DropItem(new Gold(250, 300));
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
pack.Movable = false;
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
AddItem(pack);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool ClickTitle => false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,97 +1,84 @@
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
[SerializationGenerator(0, false)]
|
||||||
|
public partial class SeekerOfAdventure : BaseEscortable
|
||||||
{
|
{
|
||||||
public class SeekerOfAdventure : BaseEscortable
|
private static readonly string[] _dungeons =
|
||||||
{
|
{
|
||||||
private static readonly string[] m_Dungeons =
|
"Covetous", "Deceit", "Despise",
|
||||||
|
"Destard", "Hythloth", "Shame", // Old Code for Pre-ML shards.
|
||||||
|
"Wrong"
|
||||||
|
};
|
||||||
|
|
||||||
|
private static readonly string[] _mlDestinations =
|
||||||
|
{
|
||||||
|
"Cove", "Serpent's Hold", "Jhelom", // ML List
|
||||||
|
"Nujel'm"
|
||||||
|
};
|
||||||
|
|
||||||
|
[Constructible]
|
||||||
|
public SeekerOfAdventure() => Title = "the seeker of adventure";
|
||||||
|
|
||||||
|
public SeekerOfAdventure(Serial serial) : base(serial)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ClickTitle => false; // Do not display 'the seeker of adventure' when single-clicking
|
||||||
|
|
||||||
|
public override string[] GetPossibleDestinations() => Core.ML ? _mlDestinations : _dungeons;
|
||||||
|
|
||||||
|
private static int GetRandomHue()
|
||||||
|
{
|
||||||
|
return Utility.Random(6) switch
|
||||||
{
|
{
|
||||||
"Covetous", "Deceit", "Despise",
|
0 => 0,
|
||||||
"Destard", "Hythloth", "Shame", // Old Code for Pre-ML shards.
|
1 => Utility.RandomBlueHue(),
|
||||||
"Wrong"
|
2 => Utility.RandomGreenHue(),
|
||||||
|
3 => Utility.RandomRedHue(),
|
||||||
|
4 => Utility.RandomYellowHue(),
|
||||||
|
5 => Utility.RandomNeutralHue(),
|
||||||
|
_ => 0
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static readonly string[] m_MLDestinations =
|
public override void InitOutfit()
|
||||||
|
{
|
||||||
|
if (Female)
|
||||||
{
|
{
|
||||||
"Cove", "Serpent's Hold", "Jhelom", // ML List
|
AddItem(new FancyDress(GetRandomHue()));
|
||||||
"Nujel'm"
|
}
|
||||||
};
|
else
|
||||||
|
|
||||||
[Constructible]
|
|
||||||
public SeekerOfAdventure() => Title = "the seeker of adventure";
|
|
||||||
|
|
||||||
public SeekerOfAdventure(Serial serial) : base(serial)
|
|
||||||
{
|
{
|
||||||
|
AddItem(new FancyShirt(GetRandomHue()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool ClickTitle => false; // Do not display 'the seeker of adventure' when single-clicking
|
var lowHue = GetRandomHue();
|
||||||
|
|
||||||
public override string[] GetPossibleDestinations() => Core.ML ? m_MLDestinations : m_Dungeons;
|
AddItem(new ShortPants(lowHue));
|
||||||
|
|
||||||
private static int GetRandomHue()
|
if (Female)
|
||||||
{
|
{
|
||||||
return Utility.Random(6) switch
|
AddItem(new ThighBoots(lowHue));
|
||||||
{
|
}
|
||||||
0 => 0,
|
else
|
||||||
1 => Utility.RandomBlueHue(),
|
{
|
||||||
2 => Utility.RandomGreenHue(),
|
AddItem(new Boots(lowHue));
|
||||||
3 => Utility.RandomRedHue(),
|
|
||||||
4 => Utility.RandomYellowHue(),
|
|
||||||
5 => Utility.RandomNeutralHue(),
|
|
||||||
_ => 0
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void InitOutfit()
|
if (!Female)
|
||||||
{
|
{
|
||||||
if (Female)
|
AddItem(new BodySash(lowHue));
|
||||||
{
|
|
||||||
AddItem(new FancyDress(GetRandomHue()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddItem(new FancyShirt(GetRandomHue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
var 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 override void Serialize(IGenericWriter writer)
|
AddItem(new Cloak(GetRandomHue()));
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
AddItem(new Longsword());
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
Utility.AssignRandomHair(this);
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
PackGold(100, 150);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,440 +1,495 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using ModernUO.Serialization;
|
||||||
using Server.Gumps;
|
using Server.Gumps;
|
||||||
using Server.Items;
|
using Server.Items;
|
||||||
using Server.Network;
|
using Server.Network;
|
||||||
using Server.Prompts;
|
using Server.Prompts;
|
||||||
|
|
||||||
namespace Server.Mobiles
|
namespace Server.Mobiles;
|
||||||
|
|
||||||
|
public interface ITownCrierEntryList
|
||||||
{
|
{
|
||||||
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 GlobalTownCrierEntryList Instance => m_Instance ??= new GlobalTownCrierEntryList();
|
||||||
|
|
||||||
|
public bool IsEmpty => Entries == null || Entries.Count == 0;
|
||||||
|
|
||||||
|
public List<TownCrierEntry> Entries { get; private set; }
|
||||||
|
|
||||||
|
public TownCrierEntry GetRandomEntry()
|
||||||
{
|
{
|
||||||
List<TownCrierEntry> Entries { get; }
|
for (var i = (Entries?.Count ?? 0) - 1; i >= 0; --i)
|
||||||
TownCrierEntry GetRandomEntry();
|
{
|
||||||
TownCrierEntry AddEntry(string[] lines, TimeSpan duration);
|
if (i >= Entries!.Count)
|
||||||
void RemoveEntry(TownCrierEntry entry);
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tce = Entries[i];
|
||||||
|
|
||||||
|
if (tce.Expired)
|
||||||
|
{
|
||||||
|
RemoveEntry(tce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Entries?.RandomElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GlobalTownCrierEntryList : ITownCrierEntryList
|
public TownCrierEntry AddEntry(string[] lines, TimeSpan duration)
|
||||||
{
|
{
|
||||||
private static GlobalTownCrierEntryList m_Instance;
|
Entries ??= new List<TownCrierEntry>();
|
||||||
|
|
||||||
public static GlobalTownCrierEntryList Instance => m_Instance ??= new GlobalTownCrierEntryList();
|
var tce = new TownCrierEntry(lines, duration);
|
||||||
|
|
||||||
public bool IsEmpty => Entries == null || Entries.Count == 0;
|
Entries.Add(tce);
|
||||||
|
|
||||||
public List<TownCrierEntry> Entries { get; private set; }
|
var instances = TownCrier.Instances;
|
||||||
|
|
||||||
public TownCrierEntry GetRandomEntry()
|
for (var i = 0; i < instances.Count; ++i)
|
||||||
{
|
{
|
||||||
for (var i = (Entries?.Count ?? 0) - 1; i >= 0; --i)
|
instances[i].ForceBeginAutoShout();
|
||||||
{
|
|
||||||
if (i >= Entries!.Count)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tce = Entries[i];
|
|
||||||
|
|
||||||
if (tce.Expired)
|
|
||||||
{
|
|
||||||
RemoveEntry(tce);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Entries?.RandomElement();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TownCrierEntry AddEntry(string[] lines, TimeSpan duration)
|
return tce;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveEntry(TownCrierEntry tce)
|
||||||
|
{
|
||||||
|
if (Entries == null)
|
||||||
{
|
{
|
||||||
Entries ??= new List<TownCrierEntry>();
|
return;
|
||||||
|
|
||||||
var tce = new TownCrierEntry(lines, duration);
|
|
||||||
|
|
||||||
Entries.Add(tce);
|
|
||||||
|
|
||||||
var instances = TownCrier.Instances;
|
|
||||||
|
|
||||||
for (var i = 0; i < instances.Count; ++i)
|
|
||||||
{
|
|
||||||
instances[i].ForceBeginAutoShout();
|
|
||||||
}
|
|
||||||
|
|
||||||
return tce;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveEntry(TownCrierEntry tce)
|
Entries.Remove(tce);
|
||||||
|
|
||||||
|
if (Entries.Count == 0)
|
||||||
{
|
{
|
||||||
if (Entries == null)
|
Entries = null;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Entries.Remove(tce);
|
|
||||||
|
|
||||||
if (Entries.Count == 0)
|
|
||||||
{
|
|
||||||
Entries = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Initialize()
|
|
||||||
{
|
|
||||||
CommandSystem.Register("TownCriers", AccessLevel.GameMaster, 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 class TownCrierEntry
|
public static void Initialize()
|
||||||
{
|
{
|
||||||
public TownCrierEntry(string[] lines, TimeSpan duration)
|
CommandSystem.Register("TownCriers", AccessLevel.GameMaster, TownCriers_OnCommand);
|
||||||
{
|
|
||||||
Lines = lines;
|
|
||||||
|
|
||||||
ExpireTime = Core.Now + duration.Clamp(TimeSpan.Zero, TimeSpan.FromDays(365));
|
|
||||||
}
|
|
||||||
|
|
||||||
public string[] Lines { get; }
|
|
||||||
|
|
||||||
public DateTime ExpireTime { get; }
|
|
||||||
|
|
||||||
public bool Expired => Core.Now >= ExpireTime;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TownCrierDurationPrompt : Prompt
|
[Usage("TownCriers"), Description("Manages the global town crier list.")]
|
||||||
|
public static void TownCriers_OnCommand(CommandEventArgs e)
|
||||||
{
|
{
|
||||||
private readonly ITownCrierEntryList m_Owner;
|
e.Mobile.SendGump(new TownCrierGump(e.Mobile, Instance));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public TownCrierDurationPrompt(ITownCrierEntryList owner) => m_Owner = owner;
|
public class TownCrierEntry
|
||||||
|
{
|
||||||
|
public TownCrierEntry(string[] lines, TimeSpan duration)
|
||||||
|
{
|
||||||
|
Lines = lines;
|
||||||
|
|
||||||
public override void OnResponse(Mobile from, string text)
|
ExpireTime = Core.Now + duration.Clamp(TimeSpan.Zero, TimeSpan.FromDays(365));
|
||||||
|
}
|
||||||
|
|
||||||
|
public string[] Lines { get; }
|
||||||
|
|
||||||
|
public DateTime ExpireTime { get; }
|
||||||
|
|
||||||
|
public bool Expired => Core.Now >= ExpireTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TownCrierDurationPrompt : Prompt
|
||||||
|
{
|
||||||
|
private readonly ITownCrierEntryList m_Owner;
|
||||||
|
|
||||||
|
public TownCrierDurationPrompt(ITownCrierEntryList owner) => m_Owner = owner;
|
||||||
|
|
||||||
|
public override void OnResponse(Mobile from, string text)
|
||||||
|
{
|
||||||
|
if (!TimeSpan.TryParse(text, out var ts))
|
||||||
{
|
{
|
||||||
if (!TimeSpan.TryParse(text, out var ts))
|
from.SendMessage("Value was not properly formatted. Use: <hours:minutes:seconds>");
|
||||||
{
|
|
||||||
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: {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));
|
from.SendGump(new TownCrierGump(from, m_Owner));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ts < TimeSpan.Zero)
|
||||||
|
{
|
||||||
|
ts = TimeSpan.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
from.SendMessage($"Duration set to: {ts}");
|
||||||
|
from.SendMessage("Enter the first line to shout:");
|
||||||
|
|
||||||
|
from.Prompt = new TownCrierLinesPrompt(m_Owner, null, new List<string>(), ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TownCrierLinesPrompt : Prompt
|
public override void OnCancel(Mobile from)
|
||||||
{
|
{
|
||||||
private readonly TimeSpan m_Duration;
|
from.SendLocalizedMessage(502980); // Message entry cancelled.
|
||||||
private readonly TownCrierEntry m_Entry;
|
from.SendGump(new TownCrierGump(from, m_Owner));
|
||||||
private readonly List<string> m_Lines;
|
}
|
||||||
private readonly ITownCrierEntryList m_Owner;
|
}
|
||||||
|
|
||||||
public TownCrierLinesPrompt(ITownCrierEntryList owner, TownCrierEntry entry, List<string> lines, TimeSpan duration)
|
public class TownCrierLinesPrompt : Prompt
|
||||||
|
{
|
||||||
|
private readonly TimeSpan m_Duration;
|
||||||
|
private readonly TownCrierEntry m_Entry;
|
||||||
|
private readonly List<string> m_Lines;
|
||||||
|
private readonly ITownCrierEntryList m_Owner;
|
||||||
|
|
||||||
|
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 = owner;
|
m_Owner.RemoveEntry(m_Entry);
|
||||||
m_Entry = entry;
|
|
||||||
m_Lines = lines;
|
|
||||||
m_Duration = duration;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnResponse(Mobile from, string text)
|
if (m_Lines.Count > 0)
|
||||||
{
|
{
|
||||||
m_Lines.Add(text);
|
m_Owner.AddEntry(m_Lines.ToArray(), m_Duration);
|
||||||
|
from.SendMessage("Message has been set.");
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
public override void OnCancel(Mobile from)
|
|
||||||
{
|
{
|
||||||
if (m_Entry != null)
|
if (m_Entry != null)
|
||||||
{
|
{
|
||||||
m_Owner.RemoveEntry(m_Entry);
|
from.SendMessage("Message deleted.");
|
||||||
}
|
|
||||||
|
|
||||||
if (m_Lines.Count > 0)
|
|
||||||
{
|
|
||||||
m_Owner.AddEntry(m_Lines.ToArray(), m_Duration);
|
|
||||||
from.SendMessage("Message has been set.");
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_Entry != null)
|
from.SendLocalizedMessage(502980); // Message entry cancelled.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
from.SendGump(new TownCrierGump(from, m_Owner));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TownCrierGump : Gump
|
||||||
|
{
|
||||||
|
private readonly Mobile m_From;
|
||||||
|
private readonly ITownCrierEntryList m_Owner;
|
||||||
|
|
||||||
|
public TownCrierGump(Mobile from, ITownCrierEntryList owner) : base(50, 50)
|
||||||
|
{
|
||||||
|
m_From = from;
|
||||||
|
m_Owner = owner;
|
||||||
|
|
||||||
|
from.CloseGump<TownCrierGump>();
|
||||||
|
|
||||||
|
AddPage(0);
|
||||||
|
|
||||||
|
var entries = owner.Entries;
|
||||||
|
|
||||||
|
owner.GetRandomEntry(); // force expiration checks
|
||||||
|
|
||||||
|
var count = entries?.Count ?? 0;
|
||||||
|
|
||||||
|
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>");
|
||||||
|
|
||||||
|
AddButton(300 - 8 - 30, 8, 0xFAB, 0xFAD, 1);
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
AddHtml(8, 30, 284, 20, "<basefont color=#FFFFFF>The crier has no news.</basefont>");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (var i = 0; i < entries!.Count; ++i)
|
||||||
|
{
|
||||||
|
var tce = entries[i];
|
||||||
|
|
||||||
|
var toExpire = Utility.Max(tce.ExpireTime - Core.Now, TimeSpan.Zero);
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
|
sb.Append("[Expires: ");
|
||||||
|
|
||||||
|
if (toExpire.TotalHours >= 1)
|
||||||
{
|
{
|
||||||
from.SendMessage("Message deleted.");
|
sb.Append((int)toExpire.TotalHours);
|
||||||
|
sb.Append(':');
|
||||||
|
sb.Append(toExpire.Minutes.ToString("D2"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
from.SendLocalizedMessage(502980); // Message entry cancelled.
|
sb.Append(toExpire.Minutes);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
from.SendGump(new TownCrierGump(from, m_Owner));
|
sb.Append(':');
|
||||||
}
|
sb.Append(toExpire.Seconds.ToString("D2"));
|
||||||
}
|
|
||||||
|
|
||||||
public class TownCrierGump : Gump
|
sb.Append("] ");
|
||||||
{
|
|
||||||
private readonly Mobile m_From;
|
|
||||||
private readonly ITownCrierEntryList m_Owner;
|
|
||||||
|
|
||||||
public TownCrierGump(Mobile from, ITownCrierEntryList owner) : base(50, 50)
|
for (var j = 0; j < tce.Lines.Length; ++j)
|
||||||
{
|
|
||||||
m_From = from;
|
|
||||||
m_Owner = owner;
|
|
||||||
|
|
||||||
from.CloseGump<TownCrierGump>();
|
|
||||||
|
|
||||||
AddPage(0);
|
|
||||||
|
|
||||||
var entries = owner.Entries;
|
|
||||||
|
|
||||||
owner.GetRandomEntry(); // force expiration checks
|
|
||||||
|
|
||||||
var count = entries?.Count ?? 0;
|
|
||||||
|
|
||||||
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>");
|
|
||||||
|
|
||||||
AddButton(300 - 8 - 30, 8, 0xFAB, 0xFAD, 1);
|
|
||||||
|
|
||||||
if (count == 0)
|
|
||||||
{
|
|
||||||
AddHtml(8, 30, 284, 20, "<basefont color=#FFFFFF>The crier has no news.</basefont>");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (var i = 0; i < entries!.Count; ++i)
|
|
||||||
{
|
{
|
||||||
var tce = entries[i];
|
if (j > 0)
|
||||||
|
|
||||||
var toExpire = Utility.Max(tce.ExpireTime - Core.Now, TimeSpan.Zero);
|
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
|
|
||||||
sb.Append("[Expires: ");
|
|
||||||
|
|
||||||
if (toExpire.TotalHours >= 1)
|
|
||||||
{
|
{
|
||||||
sb.Append((int)toExpire.TotalHours);
|
sb.Append("<br>");
|
||||||
sb.Append(':');
|
|
||||||
sb.Append(toExpire.Minutes.ToString("D2"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sb.Append(toExpire.Minutes);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.Append(':');
|
sb.Append(tce.Lines[j]);
|
||||||
sb.Append(toExpire.Seconds.ToString("D2"));
|
|
||||||
|
|
||||||
sb.Append("] ");
|
|
||||||
|
|
||||||
for (var 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);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnResponse(NetState sender, RelayInfo info)
|
AddHtml(8, 35 + i * 85, 254, 80, sb.ToString(), true, true);
|
||||||
{
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
var entries = m_Owner.Entries;
|
|
||||||
var index = info.ButtonID - 2;
|
|
||||||
|
|
||||||
if (index < entries?.Count)
|
AddButton(300 - 8 - 26, 35 + i * 85, 0x15E1, 0x15E5, 2 + i);
|
||||||
{
|
|
||||||
var tce = entries[index];
|
|
||||||
var ts = Utility.Max(tce.ExpireTime - Core.Now, TimeSpan.Zero);
|
|
||||||
|
|
||||||
m_From.SendMessage($"Editing entry #{index + 1}.");
|
|
||||||
m_From.SendMessage("Enter the first line to shout:");
|
|
||||||
m_From.Prompt = new TownCrierLinesPrompt(m_Owner, tce, new List<string>(), ts);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class TownCrier : Mobile, ITownCrierEntryList
|
public override void OnResponse(NetState sender, RelayInfo info)
|
||||||
{
|
{
|
||||||
private Timer _autoShoutTimer;
|
if (info.ButtonID == 1)
|
||||||
private Timer _newsTimer;
|
|
||||||
|
|
||||||
[Constructible]
|
|
||||||
public TownCrier()
|
|
||||||
{
|
{
|
||||||
Instances.Add(this);
|
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)
|
||||||
|
{
|
||||||
|
var entries = m_Owner.Entries;
|
||||||
|
var index = info.ButtonID - 2;
|
||||||
|
|
||||||
InitStats(100, 100, 25);
|
if (index < entries?.Count)
|
||||||
|
|
||||||
Title = "the town crier";
|
|
||||||
Hue = Race.Human.RandomSkinHue();
|
|
||||||
|
|
||||||
if (!Core.AOS)
|
|
||||||
{
|
{
|
||||||
NameHue = 0x35;
|
var tce = entries[index];
|
||||||
|
var ts = Utility.Max(tce.ExpireTime - Core.Now, TimeSpan.Zero);
|
||||||
|
|
||||||
|
m_From.SendMessage($"Editing entry #{index + 1}.");
|
||||||
|
m_From.SendMessage("Enter the first line to shout:");
|
||||||
|
m_From.Prompt = new TownCrierLinesPrompt(m_Owner, tce, new List<string>(), ts);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Female = Utility.RandomBool())
|
[SerializationGenerator(0, false)]
|
||||||
{
|
public partial class TownCrier : Mobile, ITownCrierEntryList
|
||||||
Body = 0x191;
|
{
|
||||||
Name = NameList.RandomName("female");
|
private Timer _autoShoutTimer;
|
||||||
}
|
private Timer _newsTimer;
|
||||||
else
|
|
||||||
{
|
|
||||||
Body = 0x190;
|
|
||||||
Name = NameList.RandomName("male");
|
|
||||||
}
|
|
||||||
|
|
||||||
AddItem(new FancyShirt(Utility.RandomBlueHue()));
|
[Constructible]
|
||||||
|
public TownCrier()
|
||||||
|
{
|
||||||
|
Instances.Add(this);
|
||||||
|
|
||||||
var skirt = Utility.Random(2) switch
|
InitStats(100, 100, 25);
|
||||||
{
|
|
||||||
0 => (Item)new Skirt(),
|
|
||||||
1 => new Kilt(),
|
|
||||||
_ => new Kilt()
|
|
||||||
};
|
|
||||||
|
|
||||||
skirt.Hue = Utility.RandomGreenHue();
|
Title = "the town crier";
|
||||||
|
Hue = Race.Human.RandomSkinHue();
|
||||||
|
|
||||||
AddItem(skirt);
|
if (!Core.AOS)
|
||||||
|
{
|
||||||
AddItem(new FeatheredHat(Utility.RandomGreenHue()));
|
NameHue = 0x35;
|
||||||
|
|
||||||
var boots = Utility.Random(2) switch
|
|
||||||
{
|
|
||||||
0 => (Item)new Boots(),
|
|
||||||
1 => new ThighBoots(),
|
|
||||||
_ => new ThighBoots()
|
|
||||||
};
|
|
||||||
|
|
||||||
AddItem(boots);
|
|
||||||
|
|
||||||
Utility.AssignRandomHair(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TownCrier(Serial serial) : base(serial)
|
if (Female = Utility.RandomBool())
|
||||||
{
|
{
|
||||||
Instances.Add(this);
|
Body = 0x191;
|
||||||
|
Name = NameList.RandomName("female");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Body = 0x190;
|
||||||
|
Name = NameList.RandomName("male");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<TownCrier> Instances { get; } = new();
|
AddItem(new FancyShirt(Utility.RandomBlueHue()));
|
||||||
|
|
||||||
public List<TownCrierEntry> Entries { get; private set; }
|
var skirt = Utility.Random(2) switch
|
||||||
|
|
||||||
public TownCrierEntry GetRandomEntry()
|
|
||||||
{
|
{
|
||||||
var count = Entries?.Count ?? 0;
|
0 => (Item)new Skirt(),
|
||||||
for (var i = count - 1; i >= 0; --i)
|
1 => new Kilt(),
|
||||||
{
|
_ => new Kilt()
|
||||||
if (i >= Entries!.Count)
|
};
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tce = Entries[i];
|
skirt.Hue = Utility.RandomGreenHue();
|
||||||
|
|
||||||
if (tce.Expired)
|
AddItem(skirt);
|
||||||
{
|
|
||||||
RemoveEntry(tce);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var entry = GlobalTownCrierEntryList.Instance.GetRandomEntry();
|
AddItem(new FeatheredHat(Utility.RandomGreenHue()));
|
||||||
if (count > 0 && entry != null && Utility.RandomBool())
|
|
||||||
{
|
|
||||||
return entry;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Entries?.RandomElement();
|
var boots = Utility.Random(2) switch
|
||||||
}
|
|
||||||
|
|
||||||
public TownCrierEntry AddEntry(string[] lines, TimeSpan duration)
|
|
||||||
{
|
{
|
||||||
Entries ??= new List<TownCrierEntry>();
|
0 => (Item)new Boots(),
|
||||||
|
1 => new ThighBoots(),
|
||||||
|
_ => new ThighBoots()
|
||||||
|
};
|
||||||
|
|
||||||
var tce = new TownCrierEntry(lines, duration);
|
AddItem(boots);
|
||||||
|
|
||||||
Entries.Add(tce);
|
Utility.AssignRandomHair(this);
|
||||||
|
}
|
||||||
|
|
||||||
ForceBeginAutoShout();
|
public TownCrier(Serial serial) : base(serial)
|
||||||
|
{
|
||||||
|
Instances.Add(this);
|
||||||
|
}
|
||||||
|
|
||||||
return tce;
|
public static List<TownCrier> Instances { get; } = new();
|
||||||
}
|
|
||||||
|
|
||||||
public void RemoveEntry(TownCrierEntry tce)
|
public List<TownCrierEntry> Entries { get; private set; }
|
||||||
|
|
||||||
|
public TownCrierEntry GetRandomEntry()
|
||||||
|
{
|
||||||
|
var count = Entries?.Count ?? 0;
|
||||||
|
for (var i = count - 1; i >= 0; --i)
|
||||||
{
|
{
|
||||||
if (Entries == null)
|
if (i >= Entries!.Count)
|
||||||
{
|
{
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entries.Remove(tce);
|
var tce = Entries[i];
|
||||||
|
|
||||||
if (Entries.Count == 0)
|
if (tce.Expired)
|
||||||
{
|
{
|
||||||
Entries = null;
|
RemoveEntry(tce);
|
||||||
}
|
|
||||||
|
|
||||||
if (Entries == null && GlobalTownCrierEntryList.Instance.IsEmpty)
|
|
||||||
{
|
|
||||||
_autoShoutTimer?.Stop();
|
|
||||||
_autoShoutTimer = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ForceBeginAutoShout()
|
var entry = GlobalTownCrierEntryList.Instance.GetRandomEntry();
|
||||||
|
if (count > 0 && entry != null && Utility.RandomBool())
|
||||||
{
|
{
|
||||||
_autoShoutTimer ??= Timer.DelayCall(TimeSpan.FromSeconds(5.0), TimeSpan.FromMinutes(1.0), AutoShout_Callback);
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AutoShout_Callback()
|
return Entries?.RandomElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TownCrierEntry AddEntry(string[] lines, TimeSpan duration)
|
||||||
|
{
|
||||||
|
Entries ??= new List<TownCrierEntry>();
|
||||||
|
|
||||||
|
var tce = new TownCrierEntry(lines, duration);
|
||||||
|
|
||||||
|
Entries.Add(tce);
|
||||||
|
|
||||||
|
ForceBeginAutoShout();
|
||||||
|
|
||||||
|
return tce;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveEntry(TownCrierEntry tce)
|
||||||
|
{
|
||||||
|
if (Entries == null)
|
||||||
{
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Entries.Remove(tce);
|
||||||
|
|
||||||
|
if (Entries.Count == 0)
|
||||||
|
{
|
||||||
|
Entries = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Entries == null && GlobalTownCrierEntryList.Instance.IsEmpty)
|
||||||
|
{
|
||||||
|
_autoShoutTimer?.Stop();
|
||||||
|
_autoShoutTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForceBeginAutoShout()
|
||||||
|
{
|
||||||
|
_autoShoutTimer ??= Timer.DelayCall(TimeSpan.FromSeconds(5.0), TimeSpan.FromMinutes(1.0), AutoShout_Callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AutoShout_Callback()
|
||||||
|
{
|
||||||
|
var tce = GetRandomEntry();
|
||||||
|
|
||||||
|
if (tce == null)
|
||||||
|
{
|
||||||
|
_autoShoutTimer.Stop();
|
||||||
|
_autoShoutTimer = null;
|
||||||
|
}
|
||||||
|
else if (_newsTimer == null)
|
||||||
|
{
|
||||||
|
_newsTimer = Timer.DelayCall(
|
||||||
|
TimeSpan.FromSeconds(1.0),
|
||||||
|
TimeSpan.FromSeconds(3.0),
|
||||||
|
tce.Lines.Length,
|
||||||
|
() => ShoutNews_Callback(tce)
|
||||||
|
);
|
||||||
|
|
||||||
|
PublicOverheadMessage(MessageType.Regular, 0x3B2, 502976); // Hear ye! Hear ye!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShoutNews_Callback(TownCrierEntry tce)
|
||||||
|
{
|
||||||
|
var index = _newsTimer.Index;
|
||||||
|
if (index >= tce.Lines.Length)
|
||||||
|
{
|
||||||
|
_newsTimer.Stop();
|
||||||
|
_newsTimer = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PublicOverheadMessage(MessageType.Regular, 0x3B2, false, tce.Lines[index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) => _newsTimer == null && from.Alive && InRange(from, 12);
|
||||||
|
|
||||||
|
public override void OnSpeech(SpeechEventArgs e)
|
||||||
|
{
|
||||||
|
if (_newsTimer == null && e.HasKeyword(0x30) && e.Mobile.Alive && InRange(e.Mobile, 12)) // *news*
|
||||||
|
{
|
||||||
|
Direction = GetDirectionTo(e.Mobile);
|
||||||
|
|
||||||
var tce = GetRandomEntry();
|
var tce = GetRandomEntry();
|
||||||
|
|
||||||
if (tce == null)
|
if (tce == null)
|
||||||
{
|
{
|
||||||
_autoShoutTimer.Stop();
|
PublicOverheadMessage(MessageType.Regular, 0x3B2, 1005643); // I have no news at this time.
|
||||||
_autoShoutTimer = null;
|
|
||||||
}
|
}
|
||||||
else if (_newsTimer == null)
|
else
|
||||||
{
|
{
|
||||||
_newsTimer = Timer.DelayCall(
|
_newsTimer = Timer.DelayCall(
|
||||||
TimeSpan.FromSeconds(1.0),
|
TimeSpan.FromSeconds(1.0),
|
||||||
|
|
@ -443,89 +498,16 @@ namespace Server.Mobiles
|
||||||
() => ShoutNews_Callback(tce)
|
() => ShoutNews_Callback(tce)
|
||||||
);
|
);
|
||||||
|
|
||||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 502976); // Hear ye! Hear ye!
|
PublicOverheadMessage(MessageType.Regular, 0x3B2, 502978); // Some of the latest news!
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ShoutNews_Callback(TownCrierEntry tce)
|
|
||||||
{
|
|
||||||
var index = _newsTimer.Index;
|
|
||||||
if (index >= tce.Lines.Length)
|
|
||||||
{
|
|
||||||
_newsTimer.Stop();
|
|
||||||
_newsTimer = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, false, tce.Lines[index]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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) => _newsTimer == null && from.Alive && InRange(from, 12);
|
|
||||||
|
|
||||||
public override void OnSpeech(SpeechEventArgs e)
|
|
||||||
{
|
|
||||||
if (_newsTimer == null && e.HasKeyword(0x30) && e.Mobile.Alive && InRange(e.Mobile, 12)) // *news*
|
|
||||||
{
|
|
||||||
Direction = GetDirectionTo(e.Mobile);
|
|
||||||
|
|
||||||
var tce = GetRandomEntry();
|
|
||||||
|
|
||||||
if (tce == null)
|
|
||||||
{
|
|
||||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 1005643); // I have no news at this time.
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_newsTimer = Timer.DelayCall(
|
|
||||||
TimeSpan.FromSeconds(1.0),
|
|
||||||
TimeSpan.FromSeconds(3.0),
|
|
||||||
tce.Lines.Length,
|
|
||||||
() => ShoutNews_Callback(tce)
|
|
||||||
);
|
|
||||||
|
|
||||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 502978); // Some of the latest news!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool CanBeDamaged() => false;
|
|
||||||
|
|
||||||
public override void OnDelete()
|
|
||||||
{
|
|
||||||
Instances.Remove(this);
|
|
||||||
base.OnDelete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Serialize(IGenericWriter writer)
|
|
||||||
{
|
|
||||||
base.Serialize(writer);
|
|
||||||
|
|
||||||
writer.Write(0); // version
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Deserialize(IGenericReader reader)
|
|
||||||
{
|
|
||||||
base.Deserialize(reader);
|
|
||||||
|
|
||||||
var version = reader.ReadInt();
|
|
||||||
|
|
||||||
if (Core.AOS && NameHue == 0x35)
|
|
||||||
{
|
|
||||||
NameHue = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool CanBeDamaged() => false;
|
||||||
|
|
||||||
|
public override void OnDelete()
|
||||||
|
{
|
||||||
|
Instances.Remove(this);
|
||||||
|
base.OnDelete();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue