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/email-settings.json
|
||||
/Distribution/Configuration/throttles.json
|
||||
/Distribution/Configuration/tot.json
|
||||
/Distribution/Logs
|
||||
/Distribution/Archives
|
||||
/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 List<MLQuest> MLQuests
|
||||
{
|
||||
get
|
||||
{
|
||||
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 List<MLQuest> MLQuests =>
|
||||
// Assign the quests if we don't have one, and if it is still null, return an empty list
|
||||
(m_MLQuests ??= StaticMLQuester ? MLQuestSystem.FindQuestList(GetType()) : ConstructQuestList()) ?? MLQuestSystem.EmptyList;
|
||||
|
||||
public virtual MonsterAbility[] GetMonsterAbilities() => null;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,65 +1,48 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public Actor() : base(AIType.AI_Animal, FightMode.None)
|
||||
InitStats(31, 41, 51);
|
||||
|
||||
SetSpeed(0.2, 0.4);
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
|
||||
if (Female = Utility.RandomBool())
|
||||
{
|
||||
InitStats(31, 41, 51);
|
||||
|
||||
SetSpeed(0.2, 0.4);
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
|
||||
if (Female = Utility.RandomBool())
|
||||
{
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
AddItem(new FancyDress(Utility.RandomDyedHue()));
|
||||
Title = "the actress";
|
||||
}
|
||||
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);
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
AddItem(new FancyDress(Utility.RandomDyedHue()));
|
||||
Title = "the actress";
|
||||
}
|
||||
else
|
||||
{
|
||||
Body = 0x190;
|
||||
Name = NameList.RandomName("male");
|
||||
AddItem(new LongPants(Utility.RandomNeutralHue()));
|
||||
AddItem(new FancyShirt(Utility.RandomDyedHue()));
|
||||
Title = "the actor";
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
Container pack = new Backpack();
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
pack.DropItem(new Gold(250, 300));
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
pack.Movable = false;
|
||||
|
||||
var version = reader.ReadInt();
|
||||
}
|
||||
AddItem(pack);
|
||||
}
|
||||
|
||||
public override bool ClickTitle => false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,68 +1,50 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public Artist() : base(AIType.AI_Animal, FightMode.None)
|
||||
InitStats(31, 41, 51);
|
||||
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);
|
||||
SetSkill(SkillName.Healing, 36, 68);
|
||||
|
||||
SetSpeed(0.2, 0.4);
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
Title = "the artist";
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
|
||||
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);
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
}
|
||||
else
|
||||
{
|
||||
Body = 0x190;
|
||||
Name = NameList.RandomName("male");
|
||||
}
|
||||
|
||||
public Artist(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
AddItem(new Doublet(Utility.RandomDyedHue()));
|
||||
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)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
pack.DropItem(new Gold(250, 300));
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
pack.Movable = false;
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
}
|
||||
AddItem(pack);
|
||||
}
|
||||
|
||||
public override bool CanTeach => true;
|
||||
|
||||
public override bool ClickTitle => false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,481 +1,464 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ModernUO.Serialization;
|
||||
using Server.Accounting;
|
||||
using Server.ContextMenus;
|
||||
using Server.Items;
|
||||
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]
|
||||
public Banker() : base("the banker")
|
||||
protected override List<SBInfo> SBInfos => m_SBInfos;
|
||||
|
||||
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;
|
||||
|
||||
if (AccountGold.Enabled && m.Account != null)
|
||||
foreach (var g in bank.FindItemsByType<Gold>())
|
||||
{
|
||||
balance = m.Account.GetTotalGold();
|
||||
if (balance >= int.MaxValue)
|
||||
{
|
||||
return int.MaxValue;
|
||||
}
|
||||
balance += g.Amount;
|
||||
gold.Add(g);
|
||||
}
|
||||
|
||||
Container bank = m.FindBankNoCreate();
|
||||
|
||||
if (bank != null)
|
||||
if (balance >= int.MaxValue)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return int.MaxValue;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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.
|
||||
if (AccountGold.Enabled && from.Account?.DepositGold(amount) == true)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = 0; amount > 0 && i < gold.Count; ++i)
|
||||
{
|
||||
if (gold[i].Amount <= amount)
|
||||
{
|
||||
return true;
|
||||
amount -= gold[i].Amount;
|
||||
gold[i].Delete();
|
||||
}
|
||||
|
||||
var box = from.FindBankNoCreate();
|
||||
|
||||
if (box == null)
|
||||
else
|
||||
{
|
||||
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;
|
||||
if (amount < 5000)
|
||||
{
|
||||
item = new Gold(amount);
|
||||
amount = 0;
|
||||
}
|
||||
else if (amount <= 1000000)
|
||||
{
|
||||
item = new BankCheck(amount);
|
||||
amount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = new BankCheck(1000000);
|
||||
amount -= 1000000;
|
||||
}
|
||||
|
||||
if (box.TryDropItem(from, item, false))
|
||||
{
|
||||
items.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.Delete();
|
||||
foreach (var curItem in items)
|
||||
{
|
||||
curItem.Delete();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
amount -= check.Worth;
|
||||
check.Delete();
|
||||
}
|
||||
else
|
||||
{
|
||||
check.Worth -= amount;
|
||||
amount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool Deposit(Mobile from, int amount)
|
||||
{
|
||||
// If for whatever reason the TOL checks fail, we should still try old methods for depositing currency.
|
||||
if (AccountGold.Enabled && from.Account?.DepositGold(amount) == 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.
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
amount = 0;
|
||||
}
|
||||
else if (amount <= 1000000)
|
||||
{
|
||||
item = new BankCheck(amount);
|
||||
amount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
item = new BankCheck(1000000);
|
||||
amount -= 1000000;
|
||||
curItem.Delete();
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
case 0x0000: // *withdraw*
|
||||
if (e.Mobile.Criminal)
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
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.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Say(500389); // I will not do business with a criminal!
|
||||
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)
|
||||
{
|
||||
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)
|
||||
if (!int.TryParse(split[1], out var amount))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (e.Mobile.Criminal)
|
||||
if (!Core.ML && amount > 5000 || Core.ML && amount > 60000)
|
||||
{
|
||||
Say(500389); // I will not do business with a criminal!
|
||||
break;
|
||||
Say(500381); // Thou canst not withdraw so much at one time!
|
||||
}
|
||||
|
||||
var split = e.Speech.Split(' ');
|
||||
|
||||
if (split.Length >= 2)
|
||||
else if (pack?.Deleted != false || !(pack.TotalWeight < pack.MaxWeight) ||
|
||||
!(pack.TotalItems < pack.MaxItems))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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!
|
||||
Say(500384); // Ah, art thou trying to fool me? Thou hast not so much gold!
|
||||
}
|
||||
else
|
||||
{
|
||||
var check = new BankCheck(amount);
|
||||
pack.DropItem(new Gold(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(),
|
||||
""
|
||||
);
|
||||
}
|
||||
Say(1010005); // Thou hast withdrawn gold from thy account.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case 0x0001: // *balance*
|
||||
{
|
||||
e.Handled = true;
|
||||
|
||||
if (e.Mobile.Criminal)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
base.AddCustomContextEntries(from, list);
|
||||
list.Add(new OpenBankEntry(this));
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
base.AddCustomContextEntries(from, list);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1,93 +1,76 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public BrideGroom()
|
||||
if (Female)
|
||||
{
|
||||
if (Female)
|
||||
{
|
||||
Title = "the bride";
|
||||
}
|
||||
else
|
||||
{
|
||||
Title = "the groom";
|
||||
}
|
||||
Title = "the bride";
|
||||
}
|
||||
|
||||
public BrideGroom(Serial serial) : base(serial)
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
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();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,75 +1,58 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public EscortableMage()
|
||||
{
|
||||
Title = "the mage";
|
||||
Title = "the mage";
|
||||
|
||||
SetSkill(SkillName.EvalInt, 80.0, 100.0);
|
||||
SetSkill(SkillName.Inscribe, 80.0, 100.0);
|
||||
SetSkill(SkillName.Magery, 80.0, 100.0);
|
||||
SetSkill(SkillName.Meditation, 80.0, 100.0);
|
||||
SetSkill(SkillName.MagicResist, 80.0, 100.0);
|
||||
SetSkill(SkillName.EvalInt, 80.0, 100.0);
|
||||
SetSkill(SkillName.Inscribe, 80.0, 100.0);
|
||||
SetSkill(SkillName.Magery, 80.0, 100.0);
|
||||
SetSkill(SkillName.Meditation, 80.0, 100.0);
|
||||
SetSkill(SkillName.MagicResist, 80.0, 100.0);
|
||||
}
|
||||
|
||||
public override bool CanTeach => 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;
|
||||
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();
|
||||
}
|
||||
PackGold(200, 250);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,74 +1,56 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public Gypsy() : base(AIType.AI_Animal, FightMode.None)
|
||||
InitStats(31, 41, 51);
|
||||
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);
|
||||
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())
|
||||
{
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
AddItem(new Kilt(Utility.RandomDyedHue()));
|
||||
AddItem(new Shirt(Utility.RandomDyedHue()));
|
||||
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);
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
AddItem(new Kilt(Utility.RandomDyedHue()));
|
||||
AddItem(new Shirt(Utility.RandomDyedHue()));
|
||||
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";
|
||||
}
|
||||
|
||||
public Gypsy(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
AddItem(new Bandana(Utility.RandomDyedHue()));
|
||||
AddItem(new Dagger());
|
||||
|
||||
public override bool CanTeach => true;
|
||||
public override bool ClickTitle => false;
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
Container pack = new Backpack();
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
pack.DropItem(new Gold(250, 300));
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
pack.Movable = false;
|
||||
|
||||
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;
|
||||
|
||||
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]
|
||||
public HarborMaster() : base(AIType.AI_Animal, FightMode.None)
|
||||
InitStats(31, 41, 51);
|
||||
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);
|
||||
SetSkill(SkillName.Mining, 36, 68);
|
||||
|
||||
SetSpeed(0.2, 0.4);
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
Blessed = true;
|
||||
|
||||
if (Female = Utility.RandomBool())
|
||||
{
|
||||
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);
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
Title = "the Harbor Mistress";
|
||||
}
|
||||
else
|
||||
{
|
||||
Body = 0x190;
|
||||
Name = NameList.RandomName("male");
|
||||
Title = "the Harbor Master";
|
||||
}
|
||||
|
||||
public HarborMaster(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
AddItem(new Shirt(Utility.RandomDyedHue()));
|
||||
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)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
pack.DropItem(new Gold(250, 300));
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
pack.Movable = false;
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
}
|
||||
AddItem(pack);
|
||||
}
|
||||
|
||||
public override bool CanTeach => false;
|
||||
|
||||
public override bool ClickTitle => false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,90 +1,72 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public Merchant()
|
||||
Title = "the 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";
|
||||
SetSkill(SkillName.ItemID, 55.0, 78.0);
|
||||
SetSkill(SkillName.ArmsLore, 55, 78);
|
||||
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 Merchant(Serial serial)
|
||||
: base(serial)
|
||||
var lowHue = GetRandomHue();
|
||||
|
||||
AddItem(new ThighBoots());
|
||||
|
||||
if (Female)
|
||||
{
|
||||
AddItem(new FancyDress(lowHue));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new FancyShirt(lowHue));
|
||||
}
|
||||
|
||||
public override bool CanTeach => true;
|
||||
public override bool ClickTitle => false; // Do not display 'the merchant' when single-clicking
|
||||
AddItem(new LongPants(lowHue));
|
||||
|
||||
private static int GetRandomHue()
|
||||
if (!Female)
|
||||
{
|
||||
return Utility.Random(6) switch
|
||||
{
|
||||
0 => 0,
|
||||
1 => Utility.RandomBlueHue(),
|
||||
2 => Utility.RandomGreenHue(),
|
||||
3 => Utility.RandomRedHue(),
|
||||
4 => Utility.RandomYellowHue(),
|
||||
5 => Utility.RandomNeutralHue(),
|
||||
_ => 0
|
||||
};
|
||||
AddItem(new BodySash(lowHue));
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
if (Female)
|
||||
{
|
||||
AddItem(new PlainDress());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new Shirt(GetRandomHue()));
|
||||
}
|
||||
// if (!Female)
|
||||
// AddItem( new Longsword() );
|
||||
|
||||
var lowHue = GetRandomHue();
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
AddItem(new ThighBoots());
|
||||
|
||||
if (Female)
|
||||
{
|
||||
AddItem(new FancyDress(lowHue));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new FancyShirt(lowHue));
|
||||
}
|
||||
|
||||
AddItem(new LongPants(lowHue));
|
||||
|
||||
if (!Female)
|
||||
{
|
||||
AddItem(new BodySash(lowHue));
|
||||
}
|
||||
|
||||
// if (!Female)
|
||||
// AddItem( new Longsword() );
|
||||
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
PackGold(200, 250);
|
||||
}
|
||||
|
||||
public 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();
|
||||
}
|
||||
PackGold(200, 250);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,76 +1,59 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public Messenger() => Title = "the messenger";
|
||||
|
||||
public Messenger(Serial serial) : base(serial)
|
||||
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 PlainDress());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new Shirt(GetRandomHue()));
|
||||
}
|
||||
|
||||
public override bool CanTeach => true;
|
||||
public override bool ClickTitle => false; // Do not display 'the messenger' when single-clicking
|
||||
var lowHue = GetRandomHue();
|
||||
|
||||
private static int GetRandomHue()
|
||||
AddItem(new ShortPants(lowHue));
|
||||
|
||||
if (Female)
|
||||
{
|
||||
return Utility.Random(6) switch
|
||||
{
|
||||
1 => Utility.RandomBlueHue(),
|
||||
2 => Utility.RandomGreenHue(),
|
||||
3 => Utility.RandomRedHue(),
|
||||
4 => Utility.RandomYellowHue(),
|
||||
5 => Utility.RandomNeutralHue(),
|
||||
_ => 0
|
||||
};
|
||||
AddItem(new Boots(lowHue));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new Shoes(lowHue));
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
if (Female)
|
||||
{
|
||||
AddItem(new PlainDress());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new Shirt(GetRandomHue()));
|
||||
}
|
||||
var randomHair = Utility.Random(4);
|
||||
HairItemID = randomHair == 4 ? 0x203B : 0x2048 + randomHair;
|
||||
|
||||
var lowHue = GetRandomHue();
|
||||
HairHue = Race.RandomHairHue();
|
||||
|
||||
AddItem(new ShortPants(lowHue));
|
||||
|
||||
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();
|
||||
}
|
||||
PackGold(200, 250);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 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 NpcGuild NpcGuild => NpcGuild.MerchantsGuild;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,78 +1,61 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public Ninja() : base(AIType.AI_Melee, FightMode.Aggressor)
|
||||
Title = "the ninja";
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
SetSkill(SkillName.Fencing, 64.0, 80.0);
|
||||
SetSkill(SkillName.Macing, 64.0, 80.0);
|
||||
SetSkill(SkillName.Ninjitsu, 60.0, 80.0);
|
||||
SetSkill(SkillName.Parry, 64.0, 80.0);
|
||||
SetSkill(SkillName.Tactics, 64.0, 85.0);
|
||||
SetSkill(SkillName.Swords, 64.0, 85.0);
|
||||
|
||||
SetSpeed(0.2, 0.4);
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
|
||||
if (Female = Utility.RandomBool())
|
||||
{
|
||||
Title = "the ninja";
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
SetSkill(SkillName.Fencing, 64.0, 80.0);
|
||||
SetSkill(SkillName.Macing, 64.0, 80.0);
|
||||
SetSkill(SkillName.Ninjitsu, 60.0, 80.0);
|
||||
SetSkill(SkillName.Parry, 64.0, 80.0);
|
||||
SetSkill(SkillName.Tactics, 64.0, 85.0);
|
||||
SetSkill(SkillName.Swords, 64.0, 85.0);
|
||||
|
||||
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);
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
}
|
||||
else
|
||||
{
|
||||
Body = 0x190;
|
||||
Name = NameList.RandomName("male");
|
||||
}
|
||||
|
||||
public Ninja(Serial serial) : base(serial)
|
||||
if (!Female)
|
||||
{
|
||||
AddItem(new LeatherNinjaHood());
|
||||
}
|
||||
|
||||
public override bool CanTeach => true;
|
||||
public override bool ClickTitle => false;
|
||||
AddItem(new LeatherNinjaPants());
|
||||
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);
|
||||
|
||||
writer.WriteEncodedInt(0); // version
|
||||
Utility.AssignRandomFacialHair(this, hairHue);
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadEncodedInt();
|
||||
}
|
||||
PackGold(250, 300);
|
||||
}
|
||||
|
||||
public override bool CanTeach => true;
|
||||
public override bool ClickTitle => false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,92 +1,75 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public Noble()
|
||||
{
|
||||
Title = "the noble";
|
||||
Title = "the noble";
|
||||
|
||||
SetSkill(SkillName.Parry, 80.0, 100.0);
|
||||
SetSkill(SkillName.Swords, 80.0, 100.0);
|
||||
SetSkill(SkillName.Tactics, 80.0, 100.0);
|
||||
SetSkill(SkillName.Parry, 80.0, 100.0);
|
||||
SetSkill(SkillName.Swords, 80.0, 100.0);
|
||||
SetSkill(SkillName.Tactics, 80.0, 100.0);
|
||||
}
|
||||
|
||||
public override bool CanTeach => 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;
|
||||
public override bool ClickTitle => false; // Do not display 'the noble' when single-clicking
|
||||
|
||||
private static int GetRandomHue()
|
||||
if (!Female)
|
||||
{
|
||||
return Utility.Random(6) switch
|
||||
{
|
||||
1 => Utility.RandomBlueHue(),
|
||||
2 => Utility.RandomGreenHue(),
|
||||
3 => Utility.RandomRedHue(),
|
||||
4 => Utility.RandomYellowHue(),
|
||||
5 => Utility.RandomNeutralHue(),
|
||||
_ => 0
|
||||
};
|
||||
AddItem(new BodySash(lowHue));
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
AddItem(new Cloak(GetRandomHue()));
|
||||
|
||||
if (!Female)
|
||||
{
|
||||
if (Female)
|
||||
{
|
||||
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);
|
||||
AddItem(new Longsword());
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
}
|
||||
PackGold(200, 250);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,82 +1,65 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public Peasant() => Title = "the peasant";
|
||||
|
||||
public Peasant(Serial serial) : base(serial)
|
||||
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 PlainDress());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new Shirt(GetRandomHue()));
|
||||
}
|
||||
|
||||
public override bool CanTeach => true;
|
||||
public override bool ClickTitle => false; // Do not display 'the peasant' when single-clicking
|
||||
var lowHue = GetRandomHue();
|
||||
|
||||
private static int GetRandomHue()
|
||||
AddItem(new ShortPants(lowHue));
|
||||
|
||||
if (Female)
|
||||
{
|
||||
return Utility.Random(6) switch
|
||||
{
|
||||
0 => 0,
|
||||
1 => Utility.RandomBlueHue(),
|
||||
2 => Utility.RandomGreenHue(),
|
||||
3 => Utility.RandomRedHue(),
|
||||
4 => Utility.RandomYellowHue(),
|
||||
5 => Utility.RandomNeutralHue(),
|
||||
_ => 0
|
||||
};
|
||||
AddItem(new Boots(lowHue));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new Shoes(lowHue));
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
{
|
||||
if (Female)
|
||||
{
|
||||
AddItem(new PlainDress());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new Shirt(GetRandomHue()));
|
||||
}
|
||||
// if (!Female)
|
||||
// AddItem( new BodySash( lowHue ) );
|
||||
|
||||
var lowHue = GetRandomHue();
|
||||
// AddItem( new Cloak( GetRandomHue() ) );
|
||||
|
||||
AddItem(new ShortPants(lowHue));
|
||||
// if (!Female)
|
||||
// AddItem( new Longsword() );
|
||||
|
||||
if (Female)
|
||||
{
|
||||
AddItem(new Boots(lowHue));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new Shoes(lowHue));
|
||||
}
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
// 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)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
}
|
||||
PackGold(200, 250);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,88 +1,70 @@
|
|||
using Server.Engines.MLQuests;
|
||||
using ModernUO.Serialization;
|
||||
using Server.Engines.MLQuests;
|
||||
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]
|
||||
public Prisoner()
|
||||
{
|
||||
Title = Female ? "the noblewoman" : "the nobleman";
|
||||
Title = Female ? "the noblewoman" : "the nobleman";
|
||||
|
||||
CantWalk = true;
|
||||
IsPrisoner = true;
|
||||
CantWalk = 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)
|
||||
: base(serial)
|
||||
if (Utility.RandomBool())
|
||||
{
|
||||
AddItem(new Boots());
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new ThighBoots());
|
||||
}
|
||||
|
||||
public override bool CanTeach => true;
|
||||
public override bool ClickTitle => false;
|
||||
Utility.AssignRandomHair(this);
|
||||
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)
|
||||
{
|
||||
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();
|
||||
Say(502268); // Quickly, I beg thee! Unlock my chains! If thou dost look at me close thou canst see them.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,113 +1,116 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public Samurai() : base(AIType.AI_Melee, FightMode.Aggressor)
|
||||
Title = "the samurai";
|
||||
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
SetSkill(SkillName.ArmsLore, 64.0, 80.0);
|
||||
SetSkill(SkillName.Bushido, 64.0, 85.0);
|
||||
SetSkill(SkillName.Parry, 64.0, 80.0);
|
||||
SetSkill(SkillName.Swords, 64.0, 85.0);
|
||||
|
||||
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);
|
||||
|
||||
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())
|
||||
{
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
}
|
||||
else
|
||||
{
|
||||
Body = 0x190;
|
||||
Name = NameList.RandomName("male");
|
||||
}
|
||||
|
||||
switch (Utility.Random(3))
|
||||
{
|
||||
case 0:
|
||||
switch (Utility.Random(3))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
AddItem(new Lajatang());
|
||||
break;
|
||||
case 1:
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
AddItem(new Wakizashi());
|
||||
break;
|
||||
case 2:
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
AddItem(new NoDachi());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (Utility.Random(3))
|
||||
{
|
||||
case 0:
|
||||
switch (Utility.Random(3))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
AddItem(new LeatherSuneate());
|
||||
break;
|
||||
case 1:
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
AddItem(new PlateSuneate());
|
||||
break;
|
||||
case 2:
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
AddItem(new StuddedHaidate());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (Utility.Random(4))
|
||||
{
|
||||
case 0:
|
||||
switch (Utility.Random(4))
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
AddItem(new LeatherJingasa());
|
||||
break;
|
||||
case 1:
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
AddItem(new ChainHatsuburi());
|
||||
break;
|
||||
case 2:
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
AddItem(new HeavyPlateJingasa());
|
||||
break;
|
||||
case 3:
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
AddItem(new DecorativePlateKabuto());
|
||||
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;
|
||||
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();
|
||||
}
|
||||
PackGold(250, 300);
|
||||
}
|
||||
|
||||
public override bool CanTeach => true;
|
||||
public override bool ClickTitle => false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,65 +1,47 @@
|
|||
using ModernUO.Serialization;
|
||||
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]
|
||||
public Sculptor() : base(AIType.AI_Animal, FightMode.None)
|
||||
InitStats(31, 41, 51);
|
||||
|
||||
SetSpeed(0.2, 0.4);
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
Title = "the sculptor";
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
|
||||
if (Female = Utility.RandomBool())
|
||||
{
|
||||
InitStats(31, 41, 51);
|
||||
|
||||
SetSpeed(0.2, 0.4);
|
||||
SpeechHue = Utility.RandomDyedHue();
|
||||
Title = "the sculptor";
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
|
||||
if (Female = Utility.RandomBool())
|
||||
{
|
||||
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);
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
AddItem(new Kilt(Utility.RandomNeutralHue()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Body = 0x190;
|
||||
Name = NameList.RandomName("male");
|
||||
AddItem(new LongPants(Utility.RandomNeutralHue()));
|
||||
}
|
||||
|
||||
public Sculptor(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
AddItem(new Doublet(Utility.RandomNeutralHue()));
|
||||
AddItem(new HalfApron());
|
||||
|
||||
public override bool ClickTitle => false;
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
Container pack = new Backpack();
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
pack.DropItem(new Gold(250, 300));
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
pack.Movable = false;
|
||||
|
||||
var version = reader.ReadInt();
|
||||
}
|
||||
AddItem(pack);
|
||||
}
|
||||
|
||||
public override bool ClickTitle => false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,97 +1,84 @@
|
|||
using ModernUO.Serialization;
|
||||
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",
|
||||
"Destard", "Hythloth", "Shame", // Old Code for Pre-ML shards.
|
||||
"Wrong"
|
||||
0 => 0,
|
||||
1 => Utility.RandomBlueHue(),
|
||||
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
|
||||
"Nujel'm"
|
||||
};
|
||||
|
||||
[Constructible]
|
||||
public SeekerOfAdventure() => Title = "the seeker of adventure";
|
||||
|
||||
public SeekerOfAdventure(Serial serial) : base(serial)
|
||||
AddItem(new FancyDress(GetRandomHue()));
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
{
|
||||
0 => 0,
|
||||
1 => Utility.RandomBlueHue(),
|
||||
2 => Utility.RandomGreenHue(),
|
||||
3 => Utility.RandomRedHue(),
|
||||
4 => Utility.RandomYellowHue(),
|
||||
5 => Utility.RandomNeutralHue(),
|
||||
_ => 0
|
||||
};
|
||||
AddItem(new ThighBoots(lowHue));
|
||||
}
|
||||
else
|
||||
{
|
||||
AddItem(new Boots(lowHue));
|
||||
}
|
||||
|
||||
public override void InitOutfit()
|
||||
if (!Female)
|
||||
{
|
||||
if (Female)
|
||||
{
|
||||
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);
|
||||
AddItem(new BodySash(lowHue));
|
||||
}
|
||||
|
||||
public override void Serialize(IGenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
AddItem(new Cloak(GetRandomHue()));
|
||||
|
||||
writer.Write(0); // version
|
||||
}
|
||||
AddItem(new Longsword());
|
||||
|
||||
public override void Deserialize(IGenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
var version = reader.ReadInt();
|
||||
}
|
||||
PackGold(100, 150);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,440 +1,495 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using ModernUO.Serialization;
|
||||
using Server.Gumps;
|
||||
using Server.Items;
|
||||
using Server.Network;
|
||||
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; }
|
||||
TownCrierEntry GetRandomEntry();
|
||||
TownCrierEntry AddEntry(string[] lines, TimeSpan duration);
|
||||
void RemoveEntry(TownCrierEntry entry);
|
||||
for (var i = (Entries?.Count ?? 0) - 1; i >= 0; --i)
|
||||
{
|
||||
if (i >= Entries!.Count)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (i >= Entries!.Count)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var tce = Entries[i];
|
||||
|
||||
if (tce.Expired)
|
||||
{
|
||||
RemoveEntry(tce);
|
||||
}
|
||||
}
|
||||
|
||||
return Entries?.RandomElement();
|
||||
instances[i].ForceBeginAutoShout();
|
||||
}
|
||||
|
||||
public TownCrierEntry AddEntry(string[] lines, TimeSpan duration)
|
||||
return tce;
|
||||
}
|
||||
|
||||
public void RemoveEntry(TownCrierEntry tce)
|
||||
{
|
||||
if (Entries == null)
|
||||
{
|
||||
Entries ??= new List<TownCrierEntry>();
|
||||
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
public void RemoveEntry(TownCrierEntry tce)
|
||||
Entries.Remove(tce);
|
||||
|
||||
if (Entries.Count == 0)
|
||||
{
|
||||
if (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));
|
||||
Entries = null;
|
||||
}
|
||||
}
|
||||
|
||||
public class TownCrierEntry
|
||||
public static void Initialize()
|
||||
{
|
||||
public TownCrierEntry(string[] lines, TimeSpan duration)
|
||||
{
|
||||
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;
|
||||
CommandSystem.Register("TownCriers", AccessLevel.GameMaster, TownCriers_OnCommand);
|
||||
}
|
||||
|
||||
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.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.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 class TownCrierLinesPrompt : Prompt
|
||||
public override void OnCancel(Mobile from)
|
||||
{
|
||||
private readonly TimeSpan m_Duration;
|
||||
private readonly TownCrierEntry m_Entry;
|
||||
private readonly List<string> m_Lines;
|
||||
private readonly ITownCrierEntryList m_Owner;
|
||||
from.SendLocalizedMessage(502980); // Message entry cancelled.
|
||||
from.SendGump(new TownCrierGump(from, 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_Entry = entry;
|
||||
m_Lines = lines;
|
||||
m_Duration = duration;
|
||||
m_Owner.RemoveEntry(m_Entry);
|
||||
}
|
||||
|
||||
public override void OnResponse(Mobile from, string text)
|
||||
if (m_Lines.Count > 0)
|
||||
{
|
||||
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);
|
||||
m_Owner.AddEntry(m_Lines.ToArray(), m_Duration);
|
||||
from.SendMessage("Message has been set.");
|
||||
}
|
||||
|
||||
public override void OnCancel(Mobile from)
|
||||
else
|
||||
{
|
||||
if (m_Entry != null)
|
||||
{
|
||||
m_Owner.RemoveEntry(m_Entry);
|
||||
}
|
||||
|
||||
if (m_Lines.Count > 0)
|
||||
{
|
||||
m_Owner.AddEntry(m_Lines.ToArray(), m_Duration);
|
||||
from.SendMessage("Message has been set.");
|
||||
from.SendMessage("Message deleted.");
|
||||
}
|
||||
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
|
||||
{
|
||||
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
|
||||
{
|
||||
private readonly Mobile m_From;
|
||||
private readonly ITownCrierEntryList m_Owner;
|
||||
sb.Append("] ");
|
||||
|
||||
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)
|
||||
for (var j = 0; j < tce.Lines.Length; ++j)
|
||||
{
|
||||
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)
|
||||
if (j > 0)
|
||||
{
|
||||
sb.Append((int)toExpire.TotalHours);
|
||||
sb.Append(':');
|
||||
sb.Append(toExpire.Minutes.ToString("D2"));
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(toExpire.Minutes);
|
||||
sb.Append("<br>");
|
||||
}
|
||||
|
||||
sb.Append(':');
|
||||
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);
|
||||
sb.Append(tce.Lines[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 1)
|
||||
{
|
||||
m_From.SendMessage("Enter the duration for the new message. Format: <hours:minutes:seconds>");
|
||||
m_From.Prompt = new TownCrierDurationPrompt(m_Owner);
|
||||
}
|
||||
else if (info.ButtonID > 1)
|
||||
{
|
||||
var entries = m_Owner.Entries;
|
||||
var index = info.ButtonID - 2;
|
||||
AddHtml(8, 35 + i * 85, 254, 80, sb.ToString(), true, true);
|
||||
|
||||
if (index < entries?.Count)
|
||||
{
|
||||
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);
|
||||
}
|
||||
AddButton(300 - 8 - 26, 35 + i * 85, 0x15E1, 0x15E5, 2 + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class TownCrier : Mobile, ITownCrierEntryList
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
private Timer _autoShoutTimer;
|
||||
private Timer _newsTimer;
|
||||
|
||||
[Constructible]
|
||||
public TownCrier()
|
||||
if (info.ButtonID == 1)
|
||||
{
|
||||
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);
|
||||
|
||||
Title = "the town crier";
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
|
||||
if (!Core.AOS)
|
||||
if (index < entries?.Count)
|
||||
{
|
||||
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())
|
||||
{
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
}
|
||||
else
|
||||
{
|
||||
Body = 0x190;
|
||||
Name = NameList.RandomName("male");
|
||||
}
|
||||
[SerializationGenerator(0, false)]
|
||||
public partial class TownCrier : Mobile, ITownCrierEntryList
|
||||
{
|
||||
private Timer _autoShoutTimer;
|
||||
private Timer _newsTimer;
|
||||
|
||||
AddItem(new FancyShirt(Utility.RandomBlueHue()));
|
||||
[Constructible]
|
||||
public TownCrier()
|
||||
{
|
||||
Instances.Add(this);
|
||||
|
||||
var skirt = Utility.Random(2) switch
|
||||
{
|
||||
0 => (Item)new Skirt(),
|
||||
1 => new Kilt(),
|
||||
_ => new Kilt()
|
||||
};
|
||||
InitStats(100, 100, 25);
|
||||
|
||||
skirt.Hue = Utility.RandomGreenHue();
|
||||
Title = "the town crier";
|
||||
Hue = Race.Human.RandomSkinHue();
|
||||
|
||||
AddItem(skirt);
|
||||
|
||||
AddItem(new FeatheredHat(Utility.RandomGreenHue()));
|
||||
|
||||
var boots = Utility.Random(2) switch
|
||||
{
|
||||
0 => (Item)new Boots(),
|
||||
1 => new ThighBoots(),
|
||||
_ => new ThighBoots()
|
||||
};
|
||||
|
||||
AddItem(boots);
|
||||
|
||||
Utility.AssignRandomHair(this);
|
||||
if (!Core.AOS)
|
||||
{
|
||||
NameHue = 0x35;
|
||||
}
|
||||
|
||||
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; }
|
||||
|
||||
public TownCrierEntry GetRandomEntry()
|
||||
var skirt = Utility.Random(2) switch
|
||||
{
|
||||
var count = Entries?.Count ?? 0;
|
||||
for (var i = count - 1; i >= 0; --i)
|
||||
{
|
||||
if (i >= Entries!.Count)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
0 => (Item)new Skirt(),
|
||||
1 => new Kilt(),
|
||||
_ => new Kilt()
|
||||
};
|
||||
|
||||
var tce = Entries[i];
|
||||
skirt.Hue = Utility.RandomGreenHue();
|
||||
|
||||
if (tce.Expired)
|
||||
{
|
||||
RemoveEntry(tce);
|
||||
}
|
||||
}
|
||||
AddItem(skirt);
|
||||
|
||||
var entry = GlobalTownCrierEntryList.Instance.GetRandomEntry();
|
||||
if (count > 0 && entry != null && Utility.RandomBool())
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
AddItem(new FeatheredHat(Utility.RandomGreenHue()));
|
||||
|
||||
return Entries?.RandomElement();
|
||||
}
|
||||
|
||||
public TownCrierEntry AddEntry(string[] lines, TimeSpan duration)
|
||||
var boots = Utility.Random(2) switch
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (Entries == null && GlobalTownCrierEntryList.Instance.IsEmpty)
|
||||
{
|
||||
_autoShoutTimer?.Stop();
|
||||
_autoShoutTimer = null;
|
||||
RemoveEntry(tce);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
if (tce == null)
|
||||
{
|
||||
_autoShoutTimer.Stop();
|
||||
_autoShoutTimer = null;
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 1005643); // I have no news at this time.
|
||||
}
|
||||
else if (_newsTimer == null)
|
||||
else
|
||||
{
|
||||
_newsTimer = Timer.DelayCall(
|
||||
TimeSpan.FromSeconds(1.0),
|
||||
|
|
@ -443,89 +498,16 @@ namespace Server.Mobiles
|
|||
() => 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();
|
||||
|
||||
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;
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 502978); // Some of the latest news!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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