fix: Stages faction code for serialization conversion (#1835)

This commit is contained in:
Kamron Batman 2024-06-16 11:53:15 -07:00 committed by GitHub
parent 20596e52fa
commit 221312be4c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
43 changed files with 6234 additions and 6364 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,154 +1,153 @@
using System;
namespace Server.Factions
namespace Server.Factions;
public interface IFactionItem
{
public interface IFactionItem
FactionItem FactionItemState { get; set; }
}
public class FactionItem
{
public static readonly TimeSpan ExpirationPeriod = TimeSpan.FromDays(21.0);
public FactionItem(Item item, Faction faction)
{
FactionItem FactionItemState { get; set; }
Item = item;
Faction = faction;
}
public class FactionItem
public FactionItem(IGenericReader reader, Faction faction)
{
public static readonly TimeSpan ExpirationPeriod = TimeSpan.FromDays(21.0);
var version = reader.ReadEncodedInt();
public FactionItem(Item item, Faction faction)
switch (version)
{
Item = item;
Faction = faction;
}
public FactionItem(IGenericReader reader, Faction faction)
{
var version = reader.ReadEncodedInt();
switch (version)
{
case 0:
{
Item = reader.ReadEntity<Item>();
Expiration = reader.ReadDateTime();
break;
}
}
Faction = faction;
}
public Item Item { get; }
public Faction Faction { get; }
public DateTime Expiration { get; private set; }
public bool HasExpired
{
get
{
if (Item?.Deleted != false)
case 0:
{
return true;
Item = reader.ReadEntity<Item>();
Expiration = reader.ReadDateTime();
break;
}
return Expiration != DateTime.MinValue && Core.Now >= Expiration;
}
}
public void StartExpiration()
Faction = faction;
}
public Item Item { get; }
public Faction Faction { get; }
public DateTime Expiration { get; private set; }
public bool HasExpired
{
get
{
Expiration = Core.Now + ExpirationPeriod;
if (Item?.Deleted != false)
{
return true;
}
return Expiration != DateTime.MinValue && Core.Now >= Expiration;
}
}
public void StartExpiration()
{
Expiration = Core.Now + ExpirationPeriod;
}
public void CheckAttach()
{
if (!HasExpired)
{
Attach();
}
else
{
Detach();
}
}
public void Attach()
{
if (Item is IFactionItem item)
{
item.FactionItemState = this;
}
public void CheckAttach()
Faction?.State.FactionItems.Add(this);
}
public void Detach()
{
if (Item is IFactionItem item)
{
if (!HasExpired)
{
Attach();
}
else
{
Detach();
}
item.FactionItemState = null;
}
public void Attach()
if (Faction?.State.FactionItems.Contains(this) == true)
{
if (Item is IFactionItem item)
Faction.State.FactionItems.Remove(this);
}
}
public void Serialize(IGenericWriter writer)
{
writer.WriteEncodedInt(0);
writer.Write(Item);
writer.Write(Expiration);
}
public static int GetMaxWearables(Mobile mob)
{
var pl = PlayerState.Find(mob);
return pl == null ? 0 :
pl.Faction.IsCommander(mob) ? 9 : pl.Rank.MaxWearables;
}
public static FactionItem Find(Item item)
{
if (item is IFactionItem factionItem)
{
var state = factionItem.FactionItemState;
if (state?.HasExpired == true)
{
item.FactionItemState = this;
state.Detach();
state = null;
}
Faction?.State.FactionItems.Add(this);
return state;
}
public void Detach()
return null;
}
public static Item Imbue(Item item, Faction faction, bool expire, int hue)
{
if (item is not IFactionItem)
{
if (Item is IFactionItem item)
{
item.FactionItemState = null;
}
if (Faction?.State.FactionItems.Contains(this) == true)
{
Faction.State.FactionItems.Remove(this);
}
}
public void Serialize(IGenericWriter writer)
{
writer.WriteEncodedInt(0);
writer.Write(Item);
writer.Write(Expiration);
}
public static int GetMaxWearables(Mobile mob)
{
var pl = PlayerState.Find(mob);
return pl == null ? 0 :
pl.Faction.IsCommander(mob) ? 9 : pl.Rank.MaxWearables;
}
public static FactionItem Find(Item item)
{
if (item is IFactionItem factionItem)
{
var state = factionItem.FactionItemState;
if (state?.HasExpired == true)
{
state.Detach();
state = null;
}
return state;
}
return null;
}
public static Item Imbue(Item item, Faction faction, bool expire, int hue)
{
if (item is not IFactionItem)
{
return item;
}
var state = Find(item);
if (state == null)
{
state = new FactionItem(item, faction);
state.Attach();
}
if (expire)
{
state.StartExpiration();
}
item.Hue = hue;
return item;
}
var state = Find(item);
if (state == null)
{
state = new FactionItem(item, faction);
state.Attach();
}
if (expire)
{
state.StartExpiration();
}
item.Hue = hue;
return item;
}
}

View file

@ -1,309 +1,308 @@
using System;
using System.Collections.Generic;
namespace Server.Factions
namespace Server.Factions;
public class FactionState
{
public class FactionState
private const int BroadcastsPerPeriod = 2;
private static readonly TimeSpan BroadcastPeriod = TimeSpan.FromHours(1.0);
private readonly Faction m_Faction;
private readonly DateTime[] m_LastBroadcasts = new DateTime[BroadcastsPerPeriod];
private Mobile m_Commander;
public FactionState(Faction faction)
{
private const int BroadcastsPerPeriod = 2;
private static readonly TimeSpan BroadcastPeriod = TimeSpan.FromHours(1.0);
private readonly Faction m_Faction;
m_Faction = faction;
Tithe = 50;
Members = [];
Election = new Election(faction);
FactionItems = [];
Traps = [];
}
private readonly DateTime[] m_LastBroadcasts = new DateTime[BroadcastsPerPeriod];
private Mobile m_Commander;
public FactionState(IGenericReader reader)
{
var version = reader.ReadEncodedInt();
public FactionState(Faction faction)
switch (version)
{
m_Faction = faction;
Tithe = 50;
Members = new List<PlayerState>();
Election = new Election(faction);
FactionItems = new List<FactionItem>();
Traps = new List<BaseFactionTrap>();
}
public FactionState(IGenericReader reader)
{
var version = reader.ReadEncodedInt();
switch (version)
{
case 5:
{
LastAtrophy = reader.ReadDateTime();
goto case 4;
}
case 4:
{
var count = reader.ReadEncodedInt();
for (var i = 0; i < count; ++i)
{
var time = reader.ReadDateTime();
if (i < m_LastBroadcasts.Length)
{
m_LastBroadcasts[i] = time;
}
}
goto case 3;
}
case 3:
case 2:
case 1:
{
Election = new Election(reader);
goto case 0;
}
case 0:
{
m_Faction = Faction.ReadReference(reader);
m_Commander = reader.ReadEntity<Mobile>();
if (version < 5)
{
LastAtrophy = Core.Now;
}
if (version < 4)
{
var time = reader.ReadDateTime();
if (m_LastBroadcasts.Length > 0)
{
m_LastBroadcasts[0] = time;
}
}
Tithe = reader.ReadEncodedInt();
Silver = reader.ReadEncodedInt();
var memberCount = reader.ReadEncodedInt();
Members = new List<PlayerState>();
for (var i = 0; i < memberCount; ++i)
{
var pl = new PlayerState(reader, m_Faction, Members);
if (pl.Mobile != null)
{
Members.Add(pl);
}
}
m_Faction.State = this;
m_Faction.ZeroRankOffset = Members.Count;
Members.Sort();
for (var i = Members.Count - 1; i >= 0; i--)
{
var player = Members[i];
if (player.KillPoints <= 0)
{
m_Faction.ZeroRankOffset = i;
}
else
{
player.RankIndex = i;
}
}
FactionItems = new List<FactionItem>();
if (version >= 2)
{
var factionItemCount = reader.ReadEncodedInt();
for (var i = 0; i < factionItemCount; ++i)
{
var factionItem = new FactionItem(reader, m_Faction);
Timer.StartTimer(factionItem.CheckAttach); // sandbox attachment
}
}
Traps = new List<BaseFactionTrap>();
if (version >= 3)
{
var factionTrapCount = reader.ReadEncodedInt();
for (var i = 0; i < factionTrapCount; ++i)
{
if (reader.ReadEntity<Item>() is BaseFactionTrap trap && !trap.CheckDecay())
{
Traps.Add(trap);
}
}
}
break;
}
}
if (version < 1)
{
Election = new Election(m_Faction);
}
}
public DateTime LastAtrophy { get; set; }
public bool FactionMessageReady
{
get
{
for (var i = 0; i < m_LastBroadcasts.Length; ++i)
case 5:
{
if (Core.Now >= m_LastBroadcasts[i] + BroadcastPeriod)
{
return true;
}
LastAtrophy = reader.ReadDateTime();
goto case 4;
}
case 4:
{
var count = reader.ReadEncodedInt();
return false;
}
for (var i = 0; i < count; ++i)
{
var time = reader.ReadDateTime();
if (i < m_LastBroadcasts.Length)
{
m_LastBroadcasts[i] = time;
}
}
goto case 3;
}
case 3:
case 2:
case 1:
{
Election = new Election(reader);
goto case 0;
}
case 0:
{
m_Faction = Faction.ReadReference(reader);
m_Commander = reader.ReadEntity<Mobile>();
if (version < 5)
{
LastAtrophy = Core.Now;
}
if (version < 4)
{
var time = reader.ReadDateTime();
if (m_LastBroadcasts.Length > 0)
{
m_LastBroadcasts[0] = time;
}
}
Tithe = reader.ReadEncodedInt();
Silver = reader.ReadEncodedInt();
var memberCount = reader.ReadEncodedInt();
Members = [];
for (var i = 0; i < memberCount; ++i)
{
var pl = new PlayerState(reader, m_Faction, Members);
if (pl.Mobile != null)
{
Members.Add(pl);
}
}
m_Faction.State = this;
m_Faction.ZeroRankOffset = Members.Count;
Members.Sort();
for (var i = Members.Count - 1; i >= 0; i--)
{
var player = Members[i];
if (player.KillPoints <= 0)
{
m_Faction.ZeroRankOffset = i;
}
else
{
player.RankIndex = i;
}
}
FactionItems = [];
if (version >= 2)
{
var factionItemCount = reader.ReadEncodedInt();
for (var i = 0; i < factionItemCount; ++i)
{
var factionItem = new FactionItem(reader, m_Faction);
Timer.StartTimer(factionItem.CheckAttach); // sandbox attachment
}
}
Traps = [];
if (version >= 3)
{
var factionTrapCount = reader.ReadEncodedInt();
for (var i = 0; i < factionTrapCount; ++i)
{
if (reader.ReadEntity<Item>() is BaseFactionTrap trap && !trap.CheckDecay())
{
Traps.Add(trap);
}
}
}
break;
}
}
public bool IsAtrophyReady => Core.Now >= LastAtrophy + TimeSpan.FromHours(47.0);
public List<FactionItem> FactionItems { get; set; }
public List<BaseFactionTrap> Traps { get; set; }
public Election Election { get; set; }
public Mobile Commander
if (version < 1)
{
get => m_Commander;
set
{
m_Commander?.InvalidateProperties();
m_Commander = value;
if (m_Commander != null)
{
m_Commander.SendLocalizedMessage(1042227); // You have been elected Commander of your faction
m_Commander.InvalidateProperties();
var pl = PlayerState.Find(m_Commander);
if (pl?.Finance != null)
{
pl.Finance.Finance = null;
}
if (pl?.Sheriff != null)
{
pl.Sheriff.Sheriff = null;
}
}
}
Election = new Election(m_Faction);
}
}
public int Tithe { get; set; }
public DateTime LastAtrophy { get; set; }
public int Silver { get; set; }
public List<PlayerState> Members { get; set; }
public int CheckAtrophy()
{
if (Core.Now < LastAtrophy + TimeSpan.FromHours(47.0))
{
return 0;
}
var distrib = 0;
LastAtrophy = Core.Now;
var members = new List<PlayerState>(Members);
for (var i = 0; i < members.Count; ++i)
{
var ps = members[i];
if (ps.IsActive)
{
ps.IsActive = false;
continue;
}
if (ps.KillPoints > 0)
{
var atrophy = (ps.KillPoints + 9) / 10;
ps.KillPoints -= atrophy;
distrib += atrophy;
}
}
return distrib;
}
public void RegisterBroadcast()
public bool FactionMessageReady
{
get
{
for (var i = 0; i < m_LastBroadcasts.Length; ++i)
{
if (Core.Now >= m_LastBroadcasts[i] + BroadcastPeriod)
{
m_LastBroadcasts[i] = Core.Now;
break;
return true;
}
}
return false;
}
}
public bool IsAtrophyReady => Core.Now >= LastAtrophy + TimeSpan.FromHours(47.0);
public List<FactionItem> FactionItems { get; set; }
public List<BaseFactionTrap> Traps { get; set; }
public Election Election { get; set; }
public Mobile Commander
{
get => m_Commander;
set
{
m_Commander?.InvalidateProperties();
m_Commander = value;
if (m_Commander != null)
{
m_Commander.SendLocalizedMessage(1042227); // You have been elected Commander of your faction
m_Commander.InvalidateProperties();
var pl = PlayerState.Find(m_Commander);
if (pl?.Finance != null)
{
pl.Finance.Finance = null;
}
if (pl?.Sheriff != null)
{
pl.Sheriff.Sheriff = null;
}
}
}
}
public void Serialize(IGenericWriter writer)
public int Tithe { get; set; }
public int Silver { get; set; }
public List<PlayerState> Members { get; set; }
public int CheckAtrophy()
{
if (Core.Now < LastAtrophy + TimeSpan.FromHours(47.0))
{
writer.WriteEncodedInt(5); // version
return 0;
}
writer.Write(LastAtrophy);
var distrib = 0;
LastAtrophy = Core.Now;
writer.WriteEncodedInt(m_LastBroadcasts.Length);
var members = new List<PlayerState>(Members);
for (var i = 0; i < m_LastBroadcasts.Length; ++i)
for (var i = 0; i < members.Count; ++i)
{
var ps = members[i];
if (ps.IsActive)
{
writer.Write(m_LastBroadcasts[i]);
ps.IsActive = false;
continue;
}
Election.Serialize(writer);
Faction.WriteReference(writer, m_Faction);
writer.Write(m_Commander);
writer.WriteEncodedInt(Tithe);
writer.WriteEncodedInt(Silver);
writer.WriteEncodedInt(Members.Count);
for (var i = 0; i < Members.Count; ++i)
if (ps.KillPoints > 0)
{
var pl = Members[i];
pl.Serialize(writer);
var atrophy = (ps.KillPoints + 9) / 10;
ps.KillPoints -= atrophy;
distrib += atrophy;
}
}
writer.WriteEncodedInt(FactionItems.Count);
return distrib;
}
for (var i = 0; i < FactionItems.Count; ++i)
public void RegisterBroadcast()
{
for (var i = 0; i < m_LastBroadcasts.Length; ++i)
{
if (Core.Now >= m_LastBroadcasts[i] + BroadcastPeriod)
{
FactionItems[i].Serialize(writer);
}
writer.WriteEncodedInt(Traps.Count);
for (var i = 0; i < Traps.Count; ++i)
{
writer.Write(Traps[i]);
m_LastBroadcasts[i] = Core.Now;
break;
}
}
}
public void Serialize(IGenericWriter writer)
{
writer.WriteEncodedInt(5); // version
writer.Write(LastAtrophy);
writer.WriteEncodedInt(m_LastBroadcasts.Length);
for (var i = 0; i < m_LastBroadcasts.Length; ++i)
{
writer.Write(m_LastBroadcasts[i]);
}
Election.Serialize(writer);
Faction.WriteReference(writer, m_Faction);
writer.Write(m_Commander);
writer.WriteEncodedInt(Tithe);
writer.WriteEncodedInt(Silver);
writer.WriteEncodedInt(Members.Count);
for (var i = 0; i < Members.Count; ++i)
{
var pl = Members[i];
pl.Serialize(writer);
}
writer.WriteEncodedInt(FactionItems.Count);
for (var i = 0; i < FactionItems.Count; ++i)
{
FactionItems[i].Serialize(writer);
}
writer.WriteEncodedInt(Traps.Count);
for (var i = 0; i < Traps.Count; ++i)
{
writer.Write(Traps[i]);
}
}
}

View file

@ -1,100 +1,99 @@
using System;
namespace Server.Factions
namespace Server.Factions;
public static class Generator
{
public static class Generator
public static void Configure()
{
public static void Configure()
CommandSystem.Register("GenerateFactions", AccessLevel.Developer, GenerateFactions_OnCommand);
}
[Usage("GenerateFactions")]
[Aliases("FactionGen", "GenFactions")]
[Description("Enables and generates factions.")]
public static void GenerateFactions_OnCommand(CommandEventArgs e)
{
var from = e.Mobile;
FactionSystem.Enable();
var factions = Faction.Factions;
foreach (var faction in factions)
{
CommandSystem.Register("GenerateFactions", AccessLevel.Developer, GenerateFactions_OnCommand);
Generate(faction);
from.SendMessage($"Generated {faction}");
}
[Usage("GenerateFactions")]
[Aliases("FactionGen", "GenFactions")]
[Description("Enables and generates factions.")]
public static void GenerateFactions_OnCommand(CommandEventArgs e)
var towns = Town.Towns;
foreach (var town in towns)
{
var from = e.Mobile;
FactionSystem.Enable();
var factions = Faction.Factions;
foreach (var faction in factions)
{
Generate(faction);
from.SendMessage($"Generated {faction}");
}
var towns = Town.Towns;
foreach (var town in towns)
{
Generate(town);
from.SendMessage($"Generated {town}");
}
from.SendMessage("Faction generation completed.");
Generate(town);
from.SendMessage($"Generated {town}");
}
public static void Generate(Town town)
from.SendMessage("Faction generation completed.");
}
public static void Generate(Town town)
{
var facet = Faction.Facet;
var def = town.Definition;
if (!CheckExistence(def.Monolith, facet, typeof(TownMonolith)))
{
var facet = Faction.Facet;
var def = town.Definition;
if (!CheckExistence(def.Monolith, facet, typeof(TownMonolith)))
{
var mono = new TownMonolith(town);
mono.MoveToWorld(def.Monolith, facet);
mono.Sigil = new Sigil(town);
}
if (!CheckExistence(def.TownStone, facet, typeof(TownStone)))
{
new TownStone(town).MoveToWorld(def.TownStone, facet);
}
var mono = new TownMonolith(town);
mono.MoveToWorld(def.Monolith, facet);
mono.Sigil = new Sigil(town);
}
public static void Generate(Faction faction)
if (!CheckExistence(def.TownStone, facet, typeof(TownStone)))
{
var facet = Faction.Facet;
var towns = Town.Towns;
var stronghold = faction.Definition.Stronghold;
if (!CheckExistence(stronghold.JoinStone, facet, typeof(JoinStone)))
{
new JoinStone(faction).MoveToWorld(stronghold.JoinStone, facet);
}
if (!CheckExistence(stronghold.FactionStone, facet, typeof(FactionStone)))
{
new FactionStone(faction).MoveToWorld(stronghold.FactionStone, facet);
}
for (var i = 0; i < stronghold.Monoliths.Length; ++i)
{
var monolith = stronghold.Monoliths[i];
if (!CheckExistence(monolith, facet, typeof(StrongholdMonolith)))
{
new StrongholdMonolith(towns[i], faction).MoveToWorld(monolith, facet);
}
}
}
private static bool CheckExistence(Point3D loc, Map facet, Type type)
{
foreach (var item in facet.GetItemsAt(loc))
{
if (type.IsInstanceOfType(item))
{
return true;
}
}
return false;
new TownStone(town).MoveToWorld(def.TownStone, facet);
}
}
}
public static void Generate(Faction faction)
{
var facet = Faction.Facet;
var towns = Town.Towns;
var stronghold = faction.Definition.Stronghold;
if (!CheckExistence(stronghold.JoinStone, facet, typeof(JoinStone)))
{
new JoinStone(faction).MoveToWorld(stronghold.JoinStone, facet);
}
if (!CheckExistence(stronghold.FactionStone, facet, typeof(FactionStone)))
{
new FactionStone(faction).MoveToWorld(stronghold.FactionStone, facet);
}
for (var i = 0; i < stronghold.Monoliths.Length; ++i)
{
var monolith = stronghold.Monoliths[i];
if (!CheckExistence(monolith, facet, typeof(StrongholdMonolith)))
{
new StrongholdMonolith(towns[i], faction).MoveToWorld(monolith, facet);
}
}
}
private static bool CheckExistence(Point3D loc, Map facet, Type type)
{
foreach (var item in facet.GetItemsAt(loc))
{
if (type.IsInstanceOfType(item))
{
return true;
}
}
return false;
}
}

View file

@ -1,29 +1,28 @@
using System.Collections.Generic;
namespace Server.Factions
namespace Server.Factions;
public class GuardList
{
public class GuardList
public GuardList(GuardDefinition definition)
{
public GuardList(GuardDefinition definition)
Definition = definition;
Guards = [];
}
public GuardDefinition Definition { get; }
public List<BaseFactionGuard> Guards { get; }
public BaseFactionGuard Construct()
{
try
{
Definition = definition;
Guards = new List<BaseFactionGuard>();
return Definition.Type.CreateInstance<BaseFactionGuard>();
}
public GuardDefinition Definition { get; }
public List<BaseFactionGuard> Guards { get; }
public BaseFactionGuard Construct()
catch
{
try
{
return Definition.Type.CreateInstance<BaseFactionGuard>();
}
catch
{
return null;
}
return null;
}
}
}
}

View file

@ -1,189 +1,188 @@
using Server.Mobiles;
namespace Server.Factions
namespace Server.Factions;
public static class Keywords
{
public static class Keywords
public static void Initialize()
{
public static void Initialize()
{
EventSink.Speech += EventSink_Speech;
}
EventSink.Speech += EventSink_Speech;
}
private static void ShowScore_Sandbox(PlayerState pl)
{
pl?.Mobile.PublicOverheadMessage(
MessageType.Regular,
pl.Mobile.SpeechHue,
true,
pl.KillPoints.ToString("N0")
);
}
private static void ShowScore_Sandbox(PlayerState pl)
{
pl?.Mobile.PublicOverheadMessage(
MessageType.Regular,
pl.Mobile.SpeechHue,
true,
pl.KillPoints.ToString("N0")
);
}
private static void EventSink_Speech(SpeechEventArgs e)
{
var from = e.Mobile;
var keywords = e.Keywords;
private static void EventSink_Speech(SpeechEventArgs e)
{
var from = e.Mobile;
var keywords = e.Keywords;
for (var i = 0; i < keywords.Length; ++i)
for (var i = 0; i < keywords.Length; ++i)
{
switch (keywords[i])
{
switch (keywords[i])
{
case 0x00E4: // *i wish to access the city treasury*
{
var town = Town.FromRegion(from.Region);
case 0x00E4: // *i wish to access the city treasury*
{
var town = Town.FromRegion(from.Region);
if (town?.IsFinance(from) != true || !from.Alive)
if (town?.IsFinance(from) != true || !from.Alive)
{
break;
}
if (FactionGump.Exists(from))
{
from.SendLocalizedMessage(1042160); // You already have a faction menu open.
}
else if (town.Owner != null && from is PlayerMobile mobile)
{
mobile.SendGump(new FinanceGump(mobile, town.Owner, town));
}
break;
}
case 0x0ED: // *i am sheriff*
{
var town = Town.FromRegion(from.Region);
if (town?.IsSheriff(from) != true || !from.Alive)
{
break;
}
if (FactionGump.Exists(from))
{
from.SendLocalizedMessage(1042160); // You already have a faction menu open.
}
else if (town.Owner != null)
{
from.SendGump(new SheriffGump((PlayerMobile)from, town.Owner, town));
}
break;
}
case 0x00EF: // *you are fired*
{
var town = Town.FromRegion(from.Region);
if (town == null)
{
break;
}
if (town.IsFinance(from) || town.IsSheriff(from))
{
town.BeginOrderFiring(from);
}
break;
}
case 0x00E5: // *i wish to resign as finance minister*
{
var pl = PlayerState.Find(from);
if (pl?.Finance != null)
{
pl.Finance.Finance = null;
from.SendLocalizedMessage(1005081); // You have been fired as Finance Minister
}
break;
}
case 0x00EE: // *i wish to resign as sheriff*
{
var pl = PlayerState.Find(from);
if (pl?.Sheriff != null)
{
pl.Sheriff.Sheriff = null;
from.SendLocalizedMessage(1010270); // You have been fired as Sheriff
}
break;
}
case 0x00E9: // *what is my faction term status*
{
var pl = PlayerState.Find(from);
if (pl?.IsLeaving == true)
{
if (Faction.CheckLeaveTimer(from))
{
break;
}
if (FactionGump.Exists(from))
var remaining = pl.Leaving + Faction.LeavePeriod - Core.Now;
if (remaining.TotalDays >= 1)
{
from.SendLocalizedMessage(1042160); // You already have a faction menu open.
// Your term of service will come to an end in ~1_DAYS~ days.
from.SendLocalizedMessage(1042743, remaining.TotalDays.ToString("N0"));
}
else if (town.Owner != null && from is PlayerMobile mobile)
else if (remaining.TotalHours >= 1)
{
mobile.SendGump(new FinanceGump(mobile, town.Owner, town));
}
break;
}
case 0x0ED: // *i am sheriff*
{
var town = Town.FromRegion(from.Region);
if (town?.IsSheriff(from) != true || !from.Alive)
{
break;
}
if (FactionGump.Exists(from))
{
from.SendLocalizedMessage(1042160); // You already have a faction menu open.
}
else if (town.Owner != null)
{
from.SendGump(new SheriffGump((PlayerMobile)from, town.Owner, town));
}
break;
}
case 0x00EF: // *you are fired*
{
var town = Town.FromRegion(from.Region);
if (town == null)
{
break;
}
if (town.IsFinance(from) || town.IsSheriff(from))
{
town.BeginOrderFiring(from);
}
break;
}
case 0x00E5: // *i wish to resign as finance minister*
{
var pl = PlayerState.Find(from);
if (pl?.Finance != null)
{
pl.Finance.Finance = null;
from.SendLocalizedMessage(1005081); // You have been fired as Finance Minister
}
break;
}
case 0x00EE: // *i wish to resign as sheriff*
{
var pl = PlayerState.Find(from);
if (pl?.Sheriff != null)
{
pl.Sheriff.Sheriff = null;
from.SendLocalizedMessage(1010270); // You have been fired as Sheriff
}
break;
}
case 0x00E9: // *what is my faction term status*
{
var pl = PlayerState.Find(from);
if (pl?.IsLeaving == true)
{
if (Faction.CheckLeaveTimer(from))
{
break;
}
var remaining = pl.Leaving + Faction.LeavePeriod - Core.Now;
if (remaining.TotalDays >= 1)
{
// Your term of service will come to an end in ~1_DAYS~ days.
from.SendLocalizedMessage(1042743, remaining.TotalDays.ToString("N0"));
}
else if (remaining.TotalHours >= 1)
{
// Your term of service will come to an end in ~1_HOURS~ hours.
from.SendLocalizedMessage(1042741, remaining.TotalHours.ToString("N0"));
}
else
{
// Your term of service will come to an end in less than one hour.
from.SendLocalizedMessage(1042742);
}
}
else if (pl != null)
{
// You are not in the process of quitting the faction.
from.SendLocalizedMessage(1042233);
}
break;
}
case 0x00EA: // *message faction*
{
var faction = Faction.Find(from);
if (faction?.IsCommander(from) != true)
{
break;
}
if (from.AccessLevel == AccessLevel.Player && !faction.FactionMessageReady)
{
// The required time has not yet passed since the last message was sent
from.SendLocalizedMessage(1010264);
// Your term of service will come to an end in ~1_HOURS~ hours.
from.SendLocalizedMessage(1042741, remaining.TotalHours.ToString("N0"));
}
else
{
faction.BeginBroadcast(from);
// Your term of service will come to an end in less than one hour.
from.SendLocalizedMessage(1042742);
}
break;
}
case 0x00EC: // *showscore*
else if (pl != null)
{
var pl = PlayerState.Find(from);
if (pl != null)
{
Timer.StartTimer(() => ShowScore_Sandbox(pl));
}
break;
// You are not in the process of quitting the faction.
from.SendLocalizedMessage(1042233);
}
case 0x0178: // i honor your leadership
break;
}
case 0x00EA: // *message faction*
{
var faction = Faction.Find(from);
if (faction?.IsCommander(from) != true)
{
Faction.Find(from)?.BeginHonorLeadership(from);
break;
}
}
if (from.AccessLevel == AccessLevel.Player && !faction.FactionMessageReady)
{
// The required time has not yet passed since the last message was sent
from.SendLocalizedMessage(1010264);
}
else
{
faction.BeginBroadcast(from);
}
break;
}
case 0x00EC: // *showscore*
{
var pl = PlayerState.Find(from);
if (pl != null)
{
Timer.StartTimer(() => ShowScore_Sandbox(pl));
}
break;
}
case 0x0178: // i honor your leadership
{
Faction.Find(from)?.BeginHonorLeadership(from);
break;
}
}
}
}
}
}

View file

@ -1,123 +1,118 @@
namespace Server.Factions
using System.Runtime.CompilerServices;
namespace Server.Factions;
public enum MerchantTitle
{
public enum MerchantTitle
{
None,
Scribe,
Carpenter,
Blacksmith,
Bowyer,
Tailor
}
public class MerchantTitleInfo
{
public MerchantTitleInfo(
SkillName skill, double requirement, TextDefinition title, TextDefinition label,
TextDefinition assigned
)
{
Skill = skill;
Requirement = requirement;
Title = title;
Label = label;
Assigned = assigned;
}
public SkillName Skill { get; }
public double Requirement { get; }
public TextDefinition Title { get; }
public TextDefinition Label { get; }
public TextDefinition Assigned { get; }
}
public static class MerchantTitles
{
public static MerchantTitleInfo[] Info { get; } =
{
new(
SkillName.Inscribe,
90.0,
1060773, // Scribe
1011468, // SCRIBE
1010121 // You now have the faction title of scribe
),
new(
SkillName.Carpentry,
90.0,
1060774, // Carpenter
1011469, // CARPENTER
1010122 // You now have the faction title of carpenter
),
new(
SkillName.Tinkering,
90.0,
1022984, // Tinker
1011470, // TINKER
1010123 // You now have the faction title of tinker
),
new(
SkillName.Blacksmith,
90.0,
1023016, // Blacksmith
1011471, // BLACKSMITH
1010124 // You now have the faction title of blacksmith
),
new(
SkillName.Fletching,
90.0,
1023022, // Bowyer
1011472, // BOWYER
1010125 // You now have the faction title of Bowyer
),
new(
SkillName.Tailoring,
90.0,
1022982, // Tailor
1018300, // TAILOR
1042162 // You now have the faction title of Tailor
)
};
public static MerchantTitleInfo GetInfo(MerchantTitle title)
{
var idx = (int)title - 1;
if (idx >= 0 && idx < Info.Length)
{
return Info[idx];
}
return null;
}
public static bool HasMerchantQualifications(Mobile mob)
{
for (var i = 0; i < Info.Length; ++i)
{
if (IsQualified(mob, Info[i]))
{
return true;
}
}
return false;
}
public static bool IsQualified(Mobile mob, MerchantTitle title) => IsQualified(mob, GetInfo(title));
public static bool IsQualified(Mobile mob, MerchantTitleInfo info)
{
if (mob == null || info == null)
{
return false;
}
return mob.Skills[info.Skill].Value >= info.Requirement;
}
}
None,
Scribe,
Carpenter,
Blacksmith,
Bowyer,
Tailor
}
public class MerchantTitleInfo
{
public MerchantTitleInfo(
SkillName skill, double requirement, TextDefinition title, TextDefinition label,
TextDefinition assigned
)
{
Skill = skill;
Requirement = requirement;
Title = title;
Label = label;
Assigned = assigned;
}
public SkillName Skill { get; }
public double Requirement { get; }
public TextDefinition Title { get; }
public TextDefinition Label { get; }
public TextDefinition Assigned { get; }
}
public static class MerchantTitles
{
public static MerchantTitleInfo[] Info { get; } =
[
new MerchantTitleInfo(
SkillName.Inscribe,
90.0,
1060773, // Scribe
1011468, // SCRIBE
1010121 // You now have the faction title of scribe
),
new MerchantTitleInfo(
SkillName.Carpentry,
90.0,
1060774, // Carpenter
1011469, // CARPENTER
1010122 // You now have the faction title of carpenter
),
new MerchantTitleInfo(
SkillName.Tinkering,
90.0,
1022984, // Tinker
1011470, // TINKER
1010123 // You now have the faction title of tinker
),
new MerchantTitleInfo(
SkillName.Blacksmith,
90.0,
1023016, // Blacksmith
1011471, // BLACKSMITH
1010124 // You now have the faction title of blacksmith
),
new MerchantTitleInfo(
SkillName.Fletching,
90.0,
1023022, // Bowyer
1011472, // BOWYER
1010125 // You now have the faction title of Bowyer
),
new MerchantTitleInfo(
SkillName.Tailoring,
90.0,
1022982, // Tailor
1018300, // TAILOR
1042162 // You now have the faction title of Tailor
)
];
public static MerchantTitleInfo GetInfo(MerchantTitle title)
{
var idx = (int)title - 1;
if (idx >= 0 && idx < Info.Length)
{
return Info[idx];
}
return null;
}
public static bool HasMerchantQualifications(Mobile mob)
{
for (var i = 0; i < Info.Length; ++i)
{
if (IsQualified(mob, Info[i]))
{
return true;
}
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsQualified(Mobile mob, MerchantTitle title) => IsQualified(mob, GetInfo(title));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsQualified(Mobile mob, MerchantTitleInfo info) => mob?.Skills[info.Skill].Value >= info?.Requirement;
}

View file

@ -2,133 +2,174 @@ using System;
using System.Collections.Generic;
using Server.Mobiles;
namespace Server.Factions
namespace Server.Factions;
public class PlayerState : IComparable<PlayerState>
{
public class PlayerState : IComparable<PlayerState>
private Town m_Finance;
private bool m_InvalidateRank = true;
private int m_KillPoints;
private MerchantTitle m_MerchantTitle;
private RankDefinition m_Rank;
private int m_RankIndex = -1;
private Town m_Sheriff;
public PlayerState(Mobile mob, Faction faction, List<PlayerState> owner)
{
private Town m_Finance;
Mobile = mob;
Faction = faction;
Owner = owner;
private bool m_InvalidateRank = true;
private int m_KillPoints;
private MerchantTitle m_MerchantTitle;
private RankDefinition m_Rank;
private int m_RankIndex = -1;
Attach();
Invalidate();
}
private Town m_Sheriff;
public PlayerState(IGenericReader reader, Faction faction, List<PlayerState> owner)
{
Faction = faction;
Owner = owner;
public PlayerState(Mobile mob, Faction faction, List<PlayerState> owner)
var version = reader.ReadEncodedInt();
switch (version)
{
Mobile = mob;
Faction = faction;
Owner = owner;
case 1:
{
IsActive = reader.ReadBool();
LastHonorTime = reader.ReadDateTime();
goto case 0;
}
case 0:
{
Mobile = reader.ReadEntity<Mobile>();
Attach();
m_KillPoints = reader.ReadEncodedInt();
m_MerchantTitle = (MerchantTitle)reader.ReadEncodedInt();
Leaving = reader.ReadDateTime();
break;
}
}
Attach();
}
public Mobile Mobile { get; }
public Faction Faction { get; }
public List<PlayerState> Owner { get; }
public MerchantTitle MerchantTitle
{
get => m_MerchantTitle;
set
{
m_MerchantTitle = value;
Invalidate();
}
}
public PlayerState(IGenericReader reader, Faction faction, List<PlayerState> owner)
public Town Sheriff
{
get => m_Sheriff;
set
{
Faction = faction;
Owner = owner;
var version = reader.ReadEncodedInt();
switch (version)
{
case 1:
{
IsActive = reader.ReadBool();
LastHonorTime = reader.ReadDateTime();
goto case 0;
}
case 0:
{
Mobile = reader.ReadEntity<Mobile>();
m_KillPoints = reader.ReadEncodedInt();
m_MerchantTitle = (MerchantTitle)reader.ReadEncodedInt();
Leaving = reader.ReadDateTime();
break;
}
}
Attach();
m_Sheriff = value;
Invalidate();
}
}
public Mobile Mobile { get; }
public Faction Faction { get; }
public List<PlayerState> Owner { get; }
public MerchantTitle MerchantTitle
public Town Finance
{
get => m_Finance;
set
{
get => m_MerchantTitle;
set
{
m_MerchantTitle = value;
Invalidate();
}
m_Finance = value;
Invalidate();
}
}
public Town Sheriff
public List<SilverGivenEntry> SilverGiven { get; private set; }
public int KillPoints
{
get => m_KillPoints;
set
{
get => m_Sheriff;
set
if (m_KillPoints != value)
{
m_Sheriff = value;
Invalidate();
}
}
public Town Finance
{
get => m_Finance;
set
{
m_Finance = value;
Invalidate();
}
}
public List<SilverGivenEntry> SilverGiven { get; private set; }
public int KillPoints
{
get => m_KillPoints;
set
{
if (m_KillPoints != value)
if (value > m_KillPoints)
{
if (value > m_KillPoints)
if (m_KillPoints <= 0)
{
if (value <= 0)
{
m_KillPoints = value;
Invalidate();
return;
}
Owner.Remove(this);
Owner.Insert(Faction.ZeroRankOffset, this);
m_RankIndex = Faction.ZeroRankOffset;
Faction.ZeroRankOffset++;
}
while (m_RankIndex - 1 >= 0)
{
var p = Owner[m_RankIndex - 1];
if (value > p.KillPoints)
{
Owner[m_RankIndex] = p;
Owner[m_RankIndex - 1] = this;
RankIndex--;
p.RankIndex++;
}
else
{
break;
}
}
}
else
{
if (value <= 0)
{
if (m_KillPoints <= 0)
{
if (value <= 0)
{
m_KillPoints = value;
Invalidate();
return;
}
Owner.Remove(this);
Owner.Insert(Faction.ZeroRankOffset, this);
m_RankIndex = Faction.ZeroRankOffset;
Faction.ZeroRankOffset++;
m_KillPoints = value;
Invalidate();
return;
}
while (m_RankIndex - 1 >= 0)
while (m_RankIndex + 1 < Faction.ZeroRankOffset)
{
var p = Owner[m_RankIndex - 1];
if (value > p.KillPoints)
var p = Owner[m_RankIndex + 1];
Owner[m_RankIndex + 1] = this;
Owner[m_RankIndex] = p;
RankIndex++;
p.RankIndex--;
}
m_RankIndex = -1;
Faction.ZeroRankOffset--;
}
else
{
while (m_RankIndex + 1 < Faction.ZeroRankOffset)
{
var p = Owner[m_RankIndex + 1];
if (value < p.KillPoints)
{
Owner[m_RankIndex + 1] = this;
Owner[m_RankIndex] = p;
Owner[m_RankIndex - 1] = this;
RankIndex--;
p.RankIndex++;
RankIndex++;
p.RankIndex--;
}
else
{
@ -136,173 +177,131 @@ namespace Server.Factions
}
}
}
else
{
if (value <= 0)
{
if (m_KillPoints <= 0)
{
m_KillPoints = value;
Invalidate();
return;
}
while (m_RankIndex + 1 < Faction.ZeroRankOffset)
{
var p = Owner[m_RankIndex + 1];
Owner[m_RankIndex + 1] = this;
Owner[m_RankIndex] = p;
RankIndex++;
p.RankIndex--;
}
m_RankIndex = -1;
Faction.ZeroRankOffset--;
}
else
{
while (m_RankIndex + 1 < Faction.ZeroRankOffset)
{
var p = Owner[m_RankIndex + 1];
if (value < p.KillPoints)
{
Owner[m_RankIndex + 1] = this;
Owner[m_RankIndex] = p;
RankIndex++;
p.RankIndex--;
}
else
{
break;
}
}
}
}
m_KillPoints = value;
Invalidate();
}
}
}
public int RankIndex
{
get => m_RankIndex;
set
{
if (m_RankIndex != value)
{
m_RankIndex = value;
m_InvalidateRank = true;
}
}
}
public RankDefinition Rank
{
get
{
if (m_InvalidateRank)
{
var ranks = Faction.Definition.Ranks;
int percent;
if (Owner.Count == 1)
{
percent = 1000;
}
else if (m_RankIndex == -1)
{
percent = 0;
}
else
{
percent = (Faction.ZeroRankOffset - m_RankIndex) * 1000 / Faction.ZeroRankOffset;
}
for (var i = 0; i < ranks.Length; i++)
{
var check = ranks[i];
if (percent >= check.Required)
{
m_Rank = check;
m_InvalidateRank = false;
break;
}
}
Invalidate();
}
return m_Rank;
m_KillPoints = value;
Invalidate();
}
}
public DateTime LastHonorTime { get; set; }
public DateTime Leaving { get; set; }
public bool IsLeaving => Leaving > DateTime.MinValue;
public bool IsActive { get; set; }
public int CompareTo(PlayerState ps) => (ps?.m_KillPoints ?? 0) - m_KillPoints;
public bool CanGiveSilverTo(Mobile mob)
{
for (var i = 0; i < SilverGiven?.Count; ++i)
{
var sge = SilverGiven[i];
if (sge.IsExpired)
{
SilverGiven.RemoveAt(i--);
}
else if (sge.GivenTo == mob)
{
return false;
}
}
return true;
}
public void OnGivenSilverTo(Mobile mob)
{
SilverGiven ??= new List<SilverGivenEntry>();
SilverGiven.Add(new SilverGivenEntry(mob));
}
public void Invalidate()
{
(Mobile as PlayerMobile)?.InvalidateProperties();
}
public void Attach()
{
if (Mobile is PlayerMobile mobile)
{
mobile.FactionPlayerState = this;
}
}
public void Serialize(IGenericWriter writer)
{
writer.WriteEncodedInt(1); // version
writer.Write(IsActive);
writer.Write(LastHonorTime);
writer.Write(Mobile);
writer.WriteEncodedInt(m_KillPoints);
writer.WriteEncodedInt((int)m_MerchantTitle);
writer.Write(Leaving);
}
public static PlayerState Find(Mobile mob) => mob is PlayerMobile mobile ? mobile.FactionPlayerState : null;
}
}
public int RankIndex
{
get => m_RankIndex;
set
{
if (m_RankIndex != value)
{
m_RankIndex = value;
m_InvalidateRank = true;
}
}
}
public RankDefinition Rank
{
get
{
if (m_InvalidateRank)
{
var ranks = Faction.Definition.Ranks;
int percent;
if (Owner.Count == 1)
{
percent = 1000;
}
else if (m_RankIndex == -1)
{
percent = 0;
}
else
{
percent = (Faction.ZeroRankOffset - m_RankIndex) * 1000 / Faction.ZeroRankOffset;
}
for (var i = 0; i < ranks.Length; i++)
{
var check = ranks[i];
if (percent >= check.Required)
{
m_Rank = check;
m_InvalidateRank = false;
break;
}
}
Invalidate();
}
return m_Rank;
}
}
public DateTime LastHonorTime { get; set; }
public DateTime Leaving { get; set; }
public bool IsLeaving => Leaving > DateTime.MinValue;
public bool IsActive { get; set; }
public int CompareTo(PlayerState ps) => (ps?.m_KillPoints ?? 0) - m_KillPoints;
public bool CanGiveSilverTo(Mobile mob)
{
for (var i = 0; i < SilverGiven?.Count; ++i)
{
var sge = SilverGiven[i];
if (sge.IsExpired)
{
SilverGiven.RemoveAt(i--);
}
else if (sge.GivenTo == mob)
{
return false;
}
}
return true;
}
public void OnGivenSilverTo(Mobile mob)
{
SilverGiven ??= [];
SilverGiven.Add(new SilverGivenEntry(mob));
}
public void Invalidate()
{
(Mobile as PlayerMobile)?.InvalidateProperties();
}
public void Attach()
{
if (Mobile is PlayerMobile mobile)
{
mobile.FactionPlayerState = this;
}
}
public void Serialize(IGenericWriter writer)
{
writer.WriteEncodedInt(1); // version
writer.Write(IsActive);
writer.Write(LastHonorTime);
writer.Write(Mobile);
writer.WriteEncodedInt(m_KillPoints);
writer.WriteEncodedInt((int)m_MerchantTitle);
writer.Write(Leaving);
}
public static PlayerState Find(Mobile mob) => mob is PlayerMobile mobile ? mobile.FactionPlayerState : null;
}

View file

@ -1,85 +1,84 @@
using System;
using System.Collections.Generic;
namespace Server.Factions
namespace Server.Factions;
public static class Reflector
{
public static class Reflector
private static List<Town> m_Towns;
private static List<Faction> m_Factions;
public static List<Town> Towns
{
private static List<Town> m_Towns;
private static List<Faction> m_Factions;
public static List<Town> Towns
get
{
get
if (m_Towns == null)
{
if (m_Towns == null)
{
ProcessTypes();
}
return m_Towns;
ProcessTypes();
}
return m_Towns;
}
}
public static List<Faction> Factions
public static List<Faction> Factions
{
get
{
get
if (m_Factions == null)
{
if (m_Factions == null)
{
ProcessTypes();
}
return m_Factions;
ProcessTypes();
}
return m_Factions;
}
}
private static object Construct(Type type)
private static object Construct(Type type)
{
try
{
try
{
return type.CreateInstance<object>();
}
catch
{
return null;
}
return type.CreateInstance<object>();
}
private static void ProcessTypes()
catch
{
m_Factions = new List<Faction>();
m_Towns = new List<Town>();
return null;
}
}
var asms = AssemblyHandler.Assemblies;
private static void ProcessTypes()
{
m_Factions = [];
m_Towns = [];
for (var i = 0; i < asms.Length; ++i)
var asms = AssemblyHandler.Assemblies;
for (var i = 0; i < asms.Length; ++i)
{
var asm = asms[i];
var tc = AssemblyHandler.GetTypeCache(asm);
var types = tc.Types;
for (var j = 0; j < types.Length; ++j)
{
var asm = asms[i];
var tc = AssemblyHandler.GetTypeCache(asm);
var types = tc.Types;
var type = types[j];
for (var j = 0; j < types.Length; ++j)
if (type.IsSubclassOf(typeof(Faction)))
{
var type = types[j];
if (type.IsSubclassOf(typeof(Faction)))
if (Construct(type) is Faction faction)
{
if (Construct(type) is Faction faction)
{
Faction.Factions.Add(faction);
}
Faction.Factions.Add(faction);
}
else if (type.IsSubclassOf(typeof(Town)))
}
else if (type.IsSubclassOf(typeof(Town)))
{
if (Construct(type) is Town town)
{
if (Construct(type) is Town town)
{
Town.Towns.Add(town);
}
Town.Towns.Add(town);
}
}
}
}
}
}
}

View file

@ -1,21 +1,20 @@
using System;
namespace Server.Factions
namespace Server.Factions;
public class SilverGivenEntry
{
public class SilverGivenEntry
public static readonly TimeSpan ExpirePeriod = TimeSpan.FromHours(3.0);
public SilverGivenEntry(Mobile givenTo)
{
public static readonly TimeSpan ExpirePeriod = TimeSpan.FromHours(3.0);
public SilverGivenEntry(Mobile givenTo)
{
GivenTo = givenTo;
TimeOfGift = Core.Now;
}
public Mobile GivenTo { get; }
public DateTime TimeOfGift { get; }
public bool IsExpired => TimeOfGift + ExpirePeriod < Core.Now;
GivenTo = givenTo;
TimeOfGift = Core.Now;
}
}
public Mobile GivenTo { get; }
public DateTime TimeOfGift { get; }
public bool IsExpired => TimeOfGift + ExpirePeriod < Core.Now;
}

View file

@ -1,45 +1,44 @@
using Server.Mobiles;
using Server.Regions;
namespace Server.Factions
namespace Server.Factions;
public class StrongholdRegion : BaseRegion
{
public class StrongholdRegion : BaseRegion
public StrongholdRegion(Faction faction) : base(
faction.Definition.FriendlyName,
Faction.Facet,
DefaultPriority,
faction.Definition.Stronghold.Area
)
{
public StrongholdRegion(Faction faction) : base(
faction.Definition.FriendlyName,
Faction.Facet,
DefaultPriority,
faction.Definition.Stronghold.Area
)
{
Faction = faction;
Faction = faction;
Register();
}
public Faction Faction { get; set; }
public override bool OnMoveInto(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation)
{
if (!base.OnMoveInto(m, d, newLocation, oldLocation))
{
return false;
}
if (m.AccessLevel >= AccessLevel.Counselor || Contains(oldLocation))
{
return true;
}
if (m is PlayerMobile pm && pm.DuelContext != null)
{
pm.SendMessage("You may not enter this area while participating in a duel or a tournament.");
return false;
}
return Faction.Find(m, true, true) != null;
}
public override bool AllowHousing(Mobile from, Point3D p) => false;
Register();
}
}
public Faction Faction { get; set; }
public override bool OnMoveInto(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation)
{
if (!base.OnMoveInto(m, d, newLocation, oldLocation))
{
return false;
}
if (m.AccessLevel >= AccessLevel.Counselor || Contains(oldLocation))
{
return true;
}
if (m is PlayerMobile pm && pm.DuelContext != null)
{
pm.SendMessage("You may not enter this area while participating in a duel or a tournament.");
return false;
}
return Faction.Find(m, true, true) != null;
}
public override bool AllowHousing(Mobile from, Point3D p) => false;
}

File diff suppressed because it is too large Load diff

View file

@ -1,140 +1,139 @@
using System;
namespace Server.Factions
namespace Server.Factions;
public class TownState
{
public class TownState
private Mobile m_Finance;
private Mobile m_Sheriff;
public TownState(Town town) => Town = town;
public TownState(IGenericReader reader)
{
private Mobile m_Finance;
private Mobile m_Sheriff;
var version = reader.ReadEncodedInt();
public TownState(Town town) => Town = town;
public TownState(IGenericReader reader)
switch (version)
{
var version = reader.ReadEncodedInt();
switch (version)
{
case 3:
{
LastIncome = reader.ReadDateTime();
goto case 2;
}
case 2:
{
Tax = reader.ReadEncodedInt();
LastTaxChange = reader.ReadDateTime();
goto case 1;
}
case 1:
{
Silver = reader.ReadEncodedInt();
goto case 0;
}
case 0:
{
Town = Town.ReadReference(reader);
Owner = Faction.ReadReference(reader);
m_Sheriff = reader.ReadEntity<Mobile>();
m_Finance = reader.ReadEntity<Mobile>();
Town.State = this;
break;
}
}
}
public Town Town { get; set; }
public Faction Owner { get; set; }
public Mobile Sheriff
{
get => m_Sheriff;
set
{
if (m_Sheriff != null)
case 3:
{
var pl = PlayerState.Find(m_Sheriff);
LastIncome = reader.ReadDateTime();
if (pl != null)
{
pl.Sheriff = null;
}
goto case 2;
}
m_Sheriff = value;
if (m_Sheriff != null)
case 2:
{
var pl = PlayerState.Find(m_Sheriff);
Tax = reader.ReadEncodedInt();
LastTaxChange = reader.ReadDateTime();
if (pl != null)
{
pl.Sheriff = Town;
}
goto case 1;
}
}
}
public Mobile Finance
{
get => m_Finance;
set
{
if (m_Finance != null)
case 1:
{
var pl = PlayerState.Find(m_Finance);
Silver = reader.ReadEncodedInt();
if (pl != null)
{
pl.Finance = null;
}
goto case 0;
}
m_Finance = value;
if (m_Finance != null)
case 0:
{
var pl = PlayerState.Find(m_Finance);
Town = Town.ReadReference(reader);
Owner = Faction.ReadReference(reader);
if (pl != null)
{
pl.Finance = Town;
}
m_Sheriff = reader.ReadEntity<Mobile>();
m_Finance = reader.ReadEntity<Mobile>();
Town.State = this;
break;
}
}
}
public int Silver { get; set; }
public int Tax { get; set; }
public DateTime LastTaxChange { get; set; }
public DateTime LastIncome { get; set; }
public void Serialize(IGenericWriter writer)
{
writer.WriteEncodedInt(3); // version
writer.Write(LastIncome);
writer.WriteEncodedInt(Tax);
writer.Write(LastTaxChange);
writer.WriteEncodedInt(Silver);
Town.WriteReference(writer, Town);
Faction.WriteReference(writer, Owner);
writer.Write(m_Sheriff);
writer.Write(m_Finance);
}
}
}
public Town Town { get; set; }
public Faction Owner { get; set; }
public Mobile Sheriff
{
get => m_Sheriff;
set
{
if (m_Sheriff != null)
{
var pl = PlayerState.Find(m_Sheriff);
if (pl != null)
{
pl.Sheriff = null;
}
}
m_Sheriff = value;
if (m_Sheriff != null)
{
var pl = PlayerState.Find(m_Sheriff);
if (pl != null)
{
pl.Sheriff = Town;
}
}
}
}
public Mobile Finance
{
get => m_Finance;
set
{
if (m_Finance != null)
{
var pl = PlayerState.Find(m_Finance);
if (pl != null)
{
pl.Finance = null;
}
}
m_Finance = value;
if (m_Finance != null)
{
var pl = PlayerState.Find(m_Finance);
if (pl != null)
{
pl.Finance = Town;
}
}
}
}
public int Silver { get; set; }
public int Tax { get; set; }
public DateTime LastTaxChange { get; set; }
public DateTime LastIncome { get; set; }
public void Serialize(IGenericWriter writer)
{
writer.WriteEncodedInt(3); // version
writer.Write(LastIncome);
writer.WriteEncodedInt(Tax);
writer.Write(LastTaxChange);
writer.WriteEncodedInt(Silver);
Town.WriteReference(writer, Town);
Faction.WriteReference(writer, Owner);
writer.Write(m_Sheriff);
writer.Write(m_Finance);
}
}

View file

@ -1,29 +1,28 @@
using System.Collections.Generic;
namespace Server.Factions
namespace Server.Factions;
public class VendorList
{
public class VendorList
public VendorList(VendorDefinition definition)
{
public VendorList(VendorDefinition definition)
Definition = definition;
Vendors = [];
}
public VendorDefinition Definition { get; }
public List<BaseFactionVendor> Vendors { get; }
public BaseFactionVendor Construct(Town town, Faction faction)
{
try
{
Definition = definition;
Vendors = new List<BaseFactionVendor>();
return Definition.Type.CreateInstance<BaseFactionVendor>(town, faction);
}
public VendorDefinition Definition { get; }
public List<BaseFactionVendor> Vendors { get; }
public BaseFactionVendor Construct(Town town, Faction faction)
catch
{
try
{
return Definition.Type.CreateInstance<BaseFactionVendor>(town, faction);
}
catch
{
return null;
}
return null;
}
}
}
}

View file

@ -25,37 +25,17 @@ namespace Server.Factions
public static FactionItemDefinition Identify(Item item)
{
if (item is BaseArmor armor)
return item switch
{
if (CraftResources.GetType(armor.Resource) == CraftResourceType.Leather)
{
return m_LeatherArmor;
}
return m_MetalArmor;
}
if (item is BaseRanged)
{
return m_RangedWeapon;
}
if (item is BaseWeapon)
{
return m_Weapon;
}
if (item is BaseClothing)
{
return m_Clothing;
}
if (item is SpellScroll)
{
return m_Scroll;
}
return null;
BaseArmor armor => CraftResources.GetType(armor.Resource) == CraftResourceType.Leather
? m_LeatherArmor
: m_MetalArmor,
BaseRanged => m_RangedWeapon,
BaseWeapon => m_Weapon,
BaseClothing => m_Clothing,
SpellScroll => m_Scroll,
_ => null
};
}
}
}

View file

@ -3,131 +3,130 @@ using Server.Gumps;
using Server.Mobiles;
using Server.Network;
namespace Server.Factions
namespace Server.Factions;
public class ElectionGump : FactionGump
{
public class ElectionGump : FactionGump
private readonly Election m_Election;
private readonly PlayerMobile m_From;
public ElectionGump(PlayerMobile from, Election election) : base(50, 50)
{
private readonly Election m_Election;
private readonly PlayerMobile m_From;
m_From = from;
m_Election = election;
public ElectionGump(PlayerMobile from, Election election) : base(50, 50)
AddPage(0);
AddBackground(0, 0, 420, 180, 5054);
AddBackground(10, 10, 400, 160, 3000);
AddHtmlText(20, 20, 380, 20, election.Faction.Definition.Header, false, false);
// NOTE: Gump not entirely OSI-accurate, intentionally so
switch (election.State)
{
m_From = from;
m_Election = election;
case ElectionState.Pending:
{
var toGo = election.LastStateTime + Election.PendingPeriod - Core.Now;
var days = (int)(toGo.TotalDays + 0.5);
AddPage(0);
AddHtmlLocalized(20, 40, 380, 20, 1038034); // A new election campaign is pending
AddBackground(0, 0, 420, 180, 5054);
AddBackground(10, 10, 400, 160, 3000);
AddHtmlText(20, 20, 380, 20, election.Faction.Definition.Header, false, false);
// NOTE: Gump not entirely OSI-accurate, intentionally so
switch (election.State)
{
case ElectionState.Pending:
if (days > 0)
{
var toGo = election.LastStateTime + Election.PendingPeriod - Core.Now;
var days = (int)(toGo.TotalDays + 0.5);
AddHtmlLocalized(20, 40, 380, 20, 1038034); // A new election campaign is pending
if (days > 0)
{
AddHtmlLocalized(20, 60, 280, 20, 1018062); // Days until next election :
AddLabel(300, 60, 0, days.ToString());
}
else
{
AddHtmlLocalized(20, 60, 280, 20, 1018059); // Election campaigning begins tonight.
}
break;
}
case ElectionState.Campaign:
{
var toGo = election.LastStateTime + Election.CampaignPeriod - Core.Now;
var days = (int)(toGo.TotalDays + 0.5);
AddHtmlLocalized(20, 40, 380, 20, 1018058); // There is an election campaign in progress.
if (days > 0)
{
AddHtmlLocalized(20, 60, 280, 20, 1038033); // Days to go:
AddLabel(300, 60, 0, days.ToString());
}
else
{
AddHtmlLocalized(20, 60, 280, 20, 1018061); // Campaign in progress. Voting begins tonight.
}
if (m_Election.CanBeCandidate(m_From))
{
AddButton(20, 110, 4005, 4007, 2);
AddHtmlLocalized(55, 110, 350, 20, 1011427); // CAMPAIGN FOR LEADERSHIP
}
else
{
var pl = PlayerState.Find(m_From);
if (pl == null || pl.Rank.Rank < Election.CandidateRank)
{
AddHtmlLocalized(20, 100, 380, 20, 1010118); // You must have a higher rank to run for office
}
}
break;
}
case ElectionState.Election:
{
var toGo = election.LastStateTime + Election.VotingPeriod - Core.Now;
var days = (int)Math.Ceiling(toGo.TotalDays);
AddHtmlLocalized(20, 40, 380, 20, 1018060); // There is an election vote in progress.
AddHtmlLocalized(20, 60, 280, 20, 1038033);
AddHtmlLocalized(20, 60, 280, 20, 1018062); // Days until next election :
AddLabel(300, 60, 0, days.ToString());
AddHtmlLocalized(55, 100, 380, 20, 1011428); // VOTE FOR LEADERSHIP
AddButton(20, 100, 4005, 4007, 1);
break;
}
}
else
{
AddHtmlLocalized(20, 60, 280, 20, 1018059); // Election campaigning begins tonight.
}
AddButton(20, 140, 4005, 4007, 0);
AddHtmlLocalized(55, 140, 350, 20, 1011012); // CANCEL
break;
}
case ElectionState.Campaign:
{
var toGo = election.LastStateTime + Election.CampaignPeriod - Core.Now;
var days = (int)(toGo.TotalDays + 0.5);
AddHtmlLocalized(20, 40, 380, 20, 1018058); // There is an election campaign in progress.
if (days > 0)
{
AddHtmlLocalized(20, 60, 280, 20, 1038033); // Days to go:
AddLabel(300, 60, 0, days.ToString());
}
else
{
AddHtmlLocalized(20, 60, 280, 20, 1018061); // Campaign in progress. Voting begins tonight.
}
if (m_Election.CanBeCandidate(m_From))
{
AddButton(20, 110, 4005, 4007, 2);
AddHtmlLocalized(55, 110, 350, 20, 1011427); // CAMPAIGN FOR LEADERSHIP
}
else
{
var pl = PlayerState.Find(m_From);
if (pl == null || pl.Rank.Rank < Election.CandidateRank)
{
AddHtmlLocalized(20, 100, 380, 20, 1010118); // You must have a higher rank to run for office
}
}
break;
}
case ElectionState.Election:
{
var toGo = election.LastStateTime + Election.VotingPeriod - Core.Now;
var days = (int)Math.Ceiling(toGo.TotalDays);
AddHtmlLocalized(20, 40, 380, 20, 1018060); // There is an election vote in progress.
AddHtmlLocalized(20, 60, 280, 20, 1038033);
AddLabel(300, 60, 0, days.ToString());
AddHtmlLocalized(55, 100, 380, 20, 1011428); // VOTE FOR LEADERSHIP
AddButton(20, 100, 4005, 4007, 1);
break;
}
}
public override void OnResponse(NetState sender, in RelayInfo info)
AddButton(20, 140, 4005, 4007, 0);
AddHtmlLocalized(55, 140, 350, 20, 1011012); // CANCEL
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
switch (info.ButtonID)
{
switch (info.ButtonID)
{
case 0: // back
case 0: // back
{
m_From.SendGump(new FactionStoneGump(m_From, m_Election.Faction));
break;
}
case 1: // vote
{
if (m_Election.State == ElectionState.Election)
{
m_From.SendGump(new FactionStoneGump(m_From, m_Election.Faction));
break;
m_From.SendGump(new VoteGump(m_From, m_Election));
}
case 1: // vote
{
if (m_Election.State == ElectionState.Election)
{
m_From.SendGump(new VoteGump(m_From, m_Election));
}
break;
}
case 2: // campaign
break;
}
case 2: // campaign
{
if (m_Election.CanBeCandidate(m_From))
{
if (m_Election.CanBeCandidate(m_From))
{
m_Election.AddCandidate(m_From);
}
break;
m_Election.AddCandidate(m_From);
}
}
break;
}
}
}
}

View file

@ -3,202 +3,201 @@ using System.Net;
using Server.Gumps;
using Server.Network;
namespace Server.Factions
namespace Server.Factions;
public class ElectionManagementGump : Gump
{
public class ElectionManagementGump : Gump
public const int LabelColor = 0xFFFFFF;
private readonly Candidate m_Candidate;
private readonly Election m_Election;
private readonly int m_Page;
public ElectionManagementGump(Election election, Candidate candidate = null, int page = 0) : base(40, 40)
{
public const int LabelColor = 0xFFFFFF;
private readonly Candidate m_Candidate;
m_Election = election;
m_Candidate = candidate;
m_Page = page;
private readonly Election m_Election;
private readonly int m_Page;
AddPage(0);
public ElectionManagementGump(Election election, Candidate candidate = null, int page = 0) : base(40, 40)
if (candidate != null)
{
m_Election = election;
m_Candidate = candidate;
m_Page = page;
AddBackground(0, 0, 448, 354, 9270);
AddAlphaRegion(10, 10, 428, 334);
AddPage(0);
AddHtml(10, 10, 428, 20, "Candidate Management".Center(LabelColor));
if (candidate != null)
AddHtml(45, 35, 100, 20, "Player Name:".Color(LabelColor));
AddHtml(145, 35, 100, 20, (candidate.Mobile == null ? "null" : candidate.Mobile.Name).Color(LabelColor));
AddHtml(45, 55, 100, 20, "Vote Count:".Color(LabelColor));
AddHtml(145, 55, 100, 20, candidate.Votes.ToString().Color(LabelColor));
AddButton(12, 73, 4005, 4007, 1);
AddHtml(45, 75, 100, 20, "Drop Candidate".Color(LabelColor));
AddImageTiled(13, 99, 422, 242, 9264);
AddImageTiled(14, 100, 420, 240, 9274);
AddAlphaRegion(14, 100, 420, 240);
AddHtml(14, 100, 420, 20, "Voters".Center(LabelColor));
if (page > 0)
{
AddBackground(0, 0, 448, 354, 9270);
AddAlphaRegion(10, 10, 428, 334);
AddHtml(10, 10, 428, 20, "Candidate Management".Center(LabelColor));
AddHtml(45, 35, 100, 20, "Player Name:".Color(LabelColor));
AddHtml(145, 35, 100, 20, (candidate.Mobile == null ? "null" : candidate.Mobile.Name).Color(LabelColor));
AddHtml(45, 55, 100, 20, "Vote Count:".Color(LabelColor));
AddHtml(145, 55, 100, 20, candidate.Votes.ToString().Color(LabelColor));
AddButton(12, 73, 4005, 4007, 1);
AddHtml(45, 75, 100, 20, "Drop Candidate".Color(LabelColor));
AddImageTiled(13, 99, 422, 242, 9264);
AddImageTiled(14, 100, 420, 240, 9274);
AddAlphaRegion(14, 100, 420, 240);
AddHtml(14, 100, 420, 20, "Voters".Center(LabelColor));
if (page > 0)
{
AddButton(397, 104, 0x15E3, 0x15E7, 2);
}
else
{
AddImage(397, 104, 0x25EA);
}
if ((page + 1) * 10 < candidate.Voters.Count)
{
AddButton(414, 104, 0x15E1, 0x15E5, 3);
}
else
{
AddImage(414, 104, 0x25E6);
}
AddHtml(14, 120, 30, 20, "DEL".Center(LabelColor));
AddHtml(47, 120, 150, 20, "Name".Color(LabelColor));
AddHtml(195, 120, 100, 20, "Address".Center(LabelColor));
AddHtml(295, 120, 80, 20, "Time".Center(LabelColor));
AddHtml(355, 120, 60, 20, "Legit".Center(LabelColor));
var idx = 0;
for (var i = page * 10; i >= 0 && i < candidate.Voters.Count && i < (page + 1) * 10; ++i, ++idx)
{
var voter = candidate.Voters[i];
AddButton(13, 138 + idx * 20, 4002, 4004, 4 + i);
var fields = voter.AcquireFields();
var x = 45;
for (var j = 0; j < fields.Length; ++j)
{
var obj = fields[j];
if (obj is Mobile mobile)
{
AddHtml(x + 2, 140 + idx * 20, 150, 20, mobile.Name.Color(LabelColor));
x += 150;
}
else if (obj is IPAddress)
{
AddHtml(x, 140 + idx * 20, 100, 20, obj.ToString().Center(LabelColor));
x += 100;
}
else if (obj is DateTime time)
{
AddHtml(
x,
140 + idx * 20,
80,
20,
FormatTimeSpan(time - election.LastStateTime).Center(LabelColor)
);
x += 80;
}
else if (obj is int i1)
{
AddHtml(x, 140 + idx * 20, 60, 20, $"{i1}%".Center(LabelColor));
x += 60;
}
}
}
AddButton(397, 104, 0x15E3, 0x15E7, 2);
}
else
{
AddBackground(0, 0, 288, 334, 9270);
AddAlphaRegion(10, 10, 268, 314);
AddImage(397, 104, 0x25EA);
}
AddHtml(10, 10, 268, 20, "Election Management".Center(LabelColor));
if ((page + 1) * 10 < candidate.Voters.Count)
{
AddButton(414, 104, 0x15E1, 0x15E5, 3);
}
else
{
AddImage(414, 104, 0x25E6);
}
AddHtml(45, 35, 100, 20, "Current State:".Color(LabelColor));
AddHtml(145, 35, 100, 20, election.State.ToString().Color(LabelColor));
AddHtml(14, 120, 30, 20, "DEL".Center(LabelColor));
AddHtml(47, 120, 150, 20, "Name".Color(LabelColor));
AddHtml(195, 120, 100, 20, "Address".Center(LabelColor));
AddHtml(295, 120, 80, 20, "Time".Center(LabelColor));
AddHtml(355, 120, 60, 20, "Legit".Center(LabelColor));
AddButton(12, 53, 4005, 4007, 1);
AddHtml(45, 55, 100, 20, "Transition Time:".Color(LabelColor));
AddHtml(145, 55, 100, 20, FormatTimeSpan(election.NextStateTime).Color(LabelColor));
var idx = 0;
AddImageTiled(13, 79, 262, 242, 9264);
AddImageTiled(14, 80, 260, 240, 9274);
AddAlphaRegion(14, 80, 260, 240);
for (var i = page * 10; i >= 0 && i < candidate.Voters.Count && i < (page + 1) * 10; ++i, ++idx)
{
var voter = candidate.Voters[i];
AddHtml(14, 80, 260, 20, "Candidates".Center(LabelColor));
AddHtml(14, 100, 30, 20, "-->".Center(LabelColor));
AddHtml(47, 100, 150, 20, "Name".Color(LabelColor));
AddHtml(195, 100, 80, 20, "Votes".Center(LabelColor));
AddButton(13, 138 + idx * 20, 4002, 4004, 4 + i);
for (var i = 0; i < election.Candidates.Count; ++i)
var fields = voter.AcquireFields();
var x = 45;
for (var j = 0; j < fields.Length; ++j)
{
var cd = election.Candidates[i];
var mob = cd.Mobile;
var obj = fields[j];
if (mob == null)
if (obj is Mobile mobile)
{
continue;
AddHtml(x + 2, 140 + idx * 20, 150, 20, mobile.Name.Color(LabelColor));
x += 150;
}
else if (obj is IPAddress)
{
AddHtml(x, 140 + idx * 20, 100, 20, obj.ToString().Center(LabelColor));
x += 100;
}
else if (obj is DateTime time)
{
AddHtml(
x,
140 + idx * 20,
80,
20,
FormatTimeSpan(time - election.LastStateTime).Center(LabelColor)
);
x += 80;
}
else if (obj is int i1)
{
AddHtml(x, 140 + idx * 20, 60, 20, $"{i1}%".Center(LabelColor));
x += 60;
}
AddButton(13, 118 + i * 20, 4005, 4007, 2 + i);
AddHtml(47, 120 + i * 20, 150, 20, mob.Name.Color(LabelColor));
AddHtml(195, 120 + i * 20, 80, 20, cd.Votes.ToString().Center(LabelColor));
}
}
}
public static string FormatTimeSpan(TimeSpan ts) =>
$"{ts.Days:D2}:{ts.Hours % 24:D2}:{ts.Minutes % 60:D2}:{ts.Seconds % 60:D2}";
public override void OnResponse(NetState sender, in RelayInfo info)
else
{
var from = sender.Mobile;
var bid = info.ButtonID;
AddBackground(0, 0, 288, 334, 9270);
AddAlphaRegion(10, 10, 268, 314);
if (m_Candidate == null)
AddHtml(10, 10, 268, 20, "Election Management".Center(LabelColor));
AddHtml(45, 35, 100, 20, "Current State:".Color(LabelColor));
AddHtml(145, 35, 100, 20, election.State.ToString().Color(LabelColor));
AddButton(12, 53, 4005, 4007, 1);
AddHtml(45, 55, 100, 20, "Transition Time:".Color(LabelColor));
AddHtml(145, 55, 100, 20, FormatTimeSpan(election.NextStateTime).Color(LabelColor));
AddImageTiled(13, 79, 262, 242, 9264);
AddImageTiled(14, 80, 260, 240, 9274);
AddAlphaRegion(14, 80, 260, 240);
AddHtml(14, 80, 260, 20, "Candidates".Center(LabelColor));
AddHtml(14, 100, 30, 20, "-->".Center(LabelColor));
AddHtml(47, 100, 150, 20, "Name".Color(LabelColor));
AddHtml(195, 100, 80, 20, "Votes".Center(LabelColor));
for (var i = 0; i < election.Candidates.Count; ++i)
{
if (bid > 1)
var cd = election.Candidates[i];
var mob = cd.Mobile;
if (mob == null)
{
bid -= 2;
if (bid < m_Election.Candidates.Count)
{
from.SendGump(new ElectionManagementGump(m_Election, m_Election.Candidates[bid]));
}
continue;
}
}
else if (bid == 0)
{
from.SendGump(new ElectionManagementGump(m_Election));
}
else if (bid == 1)
{
m_Election.RemoveCandidate(m_Candidate.Mobile);
from.SendGump(new ElectionManagementGump(m_Election));
}
else if (bid == 2 && m_Page > 0)
{
from.SendGump(new ElectionManagementGump(m_Election, m_Candidate, m_Page - 1));
}
else if (bid == 3 && (m_Page + 1) * 10 < m_Candidate.Voters.Count)
{
from.SendGump(new ElectionManagementGump(m_Election, m_Candidate, m_Page + 1));
}
else
{
bid -= 4;
if (bid >= 0 && bid < m_Candidate.Voters.Count)
{
m_Candidate.Voters.RemoveAt(bid);
from.SendGump(new ElectionManagementGump(m_Election, m_Candidate, m_Page));
}
AddButton(13, 118 + i * 20, 4005, 4007, 2 + i);
AddHtml(47, 120 + i * 20, 150, 20, mob.Name.Color(LabelColor));
AddHtml(195, 120 + i * 20, 80, 20, cd.Votes.ToString().Center(LabelColor));
}
}
}
}
public static string FormatTimeSpan(TimeSpan ts) =>
$"{ts.Days:D2}:{ts.Hours % 24:D2}:{ts.Minutes % 60:D2}:{ts.Seconds % 60:D2}";
public override void OnResponse(NetState sender, in RelayInfo info)
{
var from = sender.Mobile;
var bid = info.ButtonID;
if (m_Candidate == null)
{
if (bid > 1)
{
bid -= 2;
if (bid < m_Election.Candidates.Count)
{
from.SendGump(new ElectionManagementGump(m_Election, m_Election.Candidates[bid]));
}
}
}
else if (bid == 0)
{
from.SendGump(new ElectionManagementGump(m_Election));
}
else if (bid == 1)
{
m_Election.RemoveCandidate(m_Candidate.Mobile);
from.SendGump(new ElectionManagementGump(m_Election));
}
else if (bid == 2 && m_Page > 0)
{
from.SendGump(new ElectionManagementGump(m_Election, m_Candidate, m_Page - 1));
}
else if (bid == 3 && (m_Page + 1) * 10 < m_Candidate.Voters.Count)
{
from.SendGump(new ElectionManagementGump(m_Election, m_Candidate, m_Page + 1));
}
else
{
bid -= 4;
if (bid >= 0 && bid < m_Candidate.Voters.Count)
{
m_Candidate.Voters.RemoveAt(bid);
from.SendGump(new ElectionManagementGump(m_Election, m_Candidate, m_Page));
}
}
}
}

View file

@ -1,44 +1,43 @@
using Server.Gumps;
namespace Server.Factions
namespace Server.Factions;
public abstract class FactionGump : Gump
{
public abstract class FactionGump : Gump
public FactionGump(int x, int y) : base(x, y)
{
public FactionGump(int x, int y) : base(x, y)
}
public virtual int ButtonTypes => 10;
public int ToButtonID(int type, int index) => 1 + index * ButtonTypes + type;
public bool FromButtonID(int buttonID, out int type, out int index)
{
var offset = buttonID - 1;
if (offset >= 0)
{
type = offset % ButtonTypes;
index = offset / ButtonTypes;
return true;
}
public virtual int ButtonTypes => 10;
type = index = 0;
return false;
}
public int ToButtonID(int type, int index) => 1 + index * ButtonTypes + type;
public static bool Exists(Mobile mob) => mob.HasGump<FactionGump>();
public bool FromButtonID(int buttonID, out int type, out int index)
public void AddHtmlText(int x, int y, int width, int height, TextDefinition text, bool back, bool scroll)
{
if (text?.Number > 0)
{
var offset = buttonID - 1;
if (offset >= 0)
{
type = offset % ButtonTypes;
index = offset / ButtonTypes;
return true;
}
type = index = 0;
return false;
AddHtmlLocalized(x, y, width, height, text.Number, back, scroll);
}
public static bool Exists(Mobile mob) => mob.HasGump<FactionGump>();
public void AddHtmlText(int x, int y, int width, int height, TextDefinition text, bool back, bool scroll)
else if (text?.String != null)
{
if (text?.Number > 0)
{
AddHtmlLocalized(x, y, width, height, text.Number, back, scroll);
}
else if (text?.String != null)
{
AddHtml(x, y, width, height, text.String, back, scroll);
}
AddHtml(x, y, width, height, text.String, back, scroll);
}
}
}
}

View file

@ -3,112 +3,111 @@ using Server.Gumps;
using Server.Items;
using Server.Network;
namespace Server.Factions
namespace Server.Factions;
public class FactionImbueGump : FactionGump
{
public class FactionImbueGump : FactionGump
private readonly CraftSystem m_CraftSystem;
private readonly FactionItemDefinition m_Definition;
private readonly Faction m_Faction;
private readonly Item m_Item;
private readonly Mobile m_Mobile;
private readonly TextDefinition m_Notice;
private readonly BaseTool m_Tool;
public FactionImbueGump(
int quality, Item item, Mobile from, CraftSystem craftSystem, BaseTool tool, TextDefinition notice,
int availableSilver, Faction faction, FactionItemDefinition def
) : base(100, 200)
{
private readonly CraftSystem m_CraftSystem;
m_Item = item;
m_Mobile = from;
m_Faction = faction;
m_CraftSystem = craftSystem;
m_Tool = tool;
m_Notice = notice;
m_Definition = def;
private readonly FactionItemDefinition m_Definition;
private readonly Faction m_Faction;
private readonly Item m_Item;
private readonly Mobile m_Mobile;
private readonly TextDefinition m_Notice;
private readonly BaseTool m_Tool;
AddPage(0);
public FactionImbueGump(
int quality, Item item, Mobile from, CraftSystem craftSystem, BaseTool tool, TextDefinition notice,
int availableSilver, Faction faction, FactionItemDefinition def
) : base(100, 200)
AddBackground(0, 0, 320, 270, 5054);
AddBackground(10, 10, 300, 250, 3000);
AddHtmlLocalized(20, 20, 210, 25, 1011569); // Imbue with Faction properties?
AddHtmlLocalized(20, 60, 170, 25, 1018302); // Item quality:
AddHtmlLocalized(175, 60, 100, 25, 1018305 - quality); // Exceptional, Average, Low
AddHtmlLocalized(20, 80, 170, 25, 1011572); // Item Cost :
AddLabel(175, 80, 0x34, def.SilverCost.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 100, 170, 25, 1011573); // Your Silver :
AddLabel(175, 100, 0x34, availableSilver.ToString("N0")); // NOTE: Added 'N0'
AddRadio(20, 140, 210, 211, true, 1);
AddLabel(55, 140, m_Faction.Definition.HuePrimary - 1, "*****");
AddHtmlLocalized(150, 140, 150, 25, 1011570); // Primary Color
AddRadio(20, 160, 210, 211, false, 2);
AddLabel(55, 160, m_Faction.Definition.HueSecondary - 1, "*****");
AddHtmlLocalized(150, 160, 150, 25, 1011571); // Secondary Color
AddHtmlLocalized(55, 200, 200, 25, 1011011); // CONTINUE
AddButton(20, 200, 4005, 4007, 1);
AddHtmlLocalized(55, 230, 200, 25, 1011012); // CANCEL
AddButton(20, 230, 4005, 4007, 0);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (info.ButtonID == 1)
{
m_Item = item;
m_Mobile = from;
m_Faction = faction;
m_CraftSystem = craftSystem;
m_Tool = tool;
m_Notice = notice;
m_Definition = def;
var pack = m_Mobile.Backpack;
AddPage(0);
AddBackground(0, 0, 320, 270, 5054);
AddBackground(10, 10, 300, 250, 3000);
AddHtmlLocalized(20, 20, 210, 25, 1011569); // Imbue with Faction properties?
AddHtmlLocalized(20, 60, 170, 25, 1018302); // Item quality:
AddHtmlLocalized(175, 60, 100, 25, 1018305 - quality); // Exceptional, Average, Low
AddHtmlLocalized(20, 80, 170, 25, 1011572); // Item Cost :
AddLabel(175, 80, 0x34, def.SilverCost.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 100, 170, 25, 1011573); // Your Silver :
AddLabel(175, 100, 0x34, availableSilver.ToString("N0")); // NOTE: Added 'N0'
AddRadio(20, 140, 210, 211, true, 1);
AddLabel(55, 140, m_Faction.Definition.HuePrimary - 1, "*****");
AddHtmlLocalized(150, 140, 150, 25, 1011570); // Primary Color
AddRadio(20, 160, 210, 211, false, 2);
AddLabel(55, 160, m_Faction.Definition.HueSecondary - 1, "*****");
AddHtmlLocalized(150, 160, 150, 25, 1011571); // Secondary Color
AddHtmlLocalized(55, 200, 200, 25, 1011011); // CONTINUE
AddButton(20, 200, 4005, 4007, 1);
AddHtmlLocalized(55, 230, 200, 25, 1011012); // CANCEL
AddButton(20, 230, 4005, 4007, 0);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (info.ButtonID == 1)
if (pack != null && m_Item.IsChildOf(pack))
{
var pack = m_Mobile.Backpack;
if (pack != null && m_Item.IsChildOf(pack))
if (pack.ConsumeTotal(typeof(Silver), m_Definition.SilverCost))
{
if (pack.ConsumeTotal(typeof(Silver), m_Definition.SilverCost))
int hue;
if (m_Item is SpellScroll)
{
int hue;
if (m_Item is SpellScroll)
{
hue = 0;
}
else if (info.IsSwitched(1))
{
hue = m_Faction.Definition.HuePrimary;
}
else
{
hue = m_Faction.Definition.HueSecondary;
}
FactionItem.Imbue(m_Item, m_Faction, true, hue);
hue = 0;
}
else if (info.IsSwitched(1))
{
hue = m_Faction.Definition.HuePrimary;
}
else
{
m_Mobile.SendLocalizedMessage(1042204); // You do not have enough silver.
hue = m_Faction.Definition.HueSecondary;
}
}
}
if (m_Tool?.Deleted == false && m_Tool.UsesRemaining > 0)
{
m_Mobile.SendGump(new CraftGump(m_Mobile, m_CraftSystem, m_Tool, m_Notice));
}
else if (m_Notice != null)
{
if (m_Notice.Number > 0)
{
m_Mobile.SendLocalizedMessage(m_Notice.Number);
FactionItem.Imbue(m_Item, m_Faction, true, hue);
}
else
{
m_Mobile.SendMessage(m_Notice.String);
m_Mobile.SendLocalizedMessage(1042204); // You do not have enough silver.
}
}
}
if (m_Tool?.Deleted == false && m_Tool.UsesRemaining > 0)
{
m_Mobile.SendGump(new CraftGump(m_Mobile, m_CraftSystem, m_Tool, m_Notice));
}
else if (m_Notice != null)
{
if (m_Notice.Number > 0)
{
m_Mobile.SendLocalizedMessage(m_Notice.Number);
}
else
{
m_Mobile.SendMessage(m_Notice.String);
}
}
}
}
}

View file

@ -2,364 +2,363 @@ using Server.Gumps;
using Server.Mobiles;
using Server.Network;
namespace Server.Factions
namespace Server.Factions;
public class FactionStoneGump : FactionGump
{
public class FactionStoneGump : FactionGump
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
public FactionStoneGump(PlayerMobile from, Faction faction) : base(20, 30)
{
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
m_From = from;
m_Faction = faction;
public FactionStoneGump(PlayerMobile from, Faction faction) : base(20, 30)
AddPage(0);
AddBackground(0, 0, 550, 440, 5054);
AddBackground(10, 10, 530, 420, 3000);
AddPage(1);
AddHtmlText(20, 30, 510, 20, faction.Definition.Header, false, false);
AddHtmlLocalized(20, 60, 100, 20, 1011429); // Led By :
AddHtml(125, 60, 200, 20, faction.Commander != null ? faction.Commander.Name : "Nobody");
AddHtmlLocalized(20, 80, 100, 20, 1011457); // Tithe rate :
if (faction.Tithe >= 0 && faction.Tithe <= 100 && faction.Tithe % 10 == 0)
{
m_From = from;
m_Faction = faction;
AddHtmlLocalized(125, 80, 350, 20, 1011480 + faction.Tithe / 10);
}
else
{
AddHtml(125, 80, 350, 20, $"{faction.Tithe}%");
}
AddPage(0);
AddHtmlLocalized(20, 100, 100, 20, 1011458); // Traps placed :
AddHtml(125, 100, 50, 20, faction.Traps.Count.ToString());
AddBackground(0, 0, 550, 440, 5054);
AddBackground(10, 10, 530, 420, 3000);
AddHtmlLocalized(55, 225, 200, 20, 1011428); // VOTE FOR LEADERSHIP
AddButton(20, 225, 4005, 4007, ToButtonID(0, 0));
AddPage(1);
AddHtmlLocalized(55, 150, 100, 20, 1011430); // CITY STATUS
AddButton(20, 150, 4005, 4007, 0, GumpButtonType.Page, 2);
AddHtmlText(20, 30, 510, 20, faction.Definition.Header, false, false);
AddHtmlLocalized(55, 175, 100, 20, 1011444); // STATISTICS
AddButton(20, 175, 4005, 4007, 0, GumpButtonType.Page, 4);
AddHtmlLocalized(20, 60, 100, 20, 1011429); // Led By :
AddHtml(125, 60, 200, 20, faction.Commander != null ? faction.Commander.Name : "Nobody");
var isMerchantQualified = MerchantTitles.HasMerchantQualifications(from);
AddHtmlLocalized(20, 80, 100, 20, 1011457); // Tithe rate :
if (faction.Tithe >= 0 && faction.Tithe <= 100 && faction.Tithe % 10 == 0)
var pl = PlayerState.Find(from);
if (pl != null && pl.MerchantTitle != MerchantTitle.None)
{
AddHtmlLocalized(55, 200, 250, 20, 1011460); // UNDECLARE FACTION MERCHANT
AddButton(20, 200, 4005, 4007, ToButtonID(1, 0));
}
else if (isMerchantQualified)
{
AddHtmlLocalized(55, 200, 250, 20, 1011459); // DECLARE FACTION MERCHANT
AddButton(20, 200, 4005, 4007, 0, GumpButtonType.Page, 5);
}
else
{
AddHtmlLocalized(55, 200, 250, 20, 1011467); // MERCHANT OPTIONS
AddImage(20, 200, 4020);
}
AddHtmlLocalized(55, 250, 300, 20, 1011461); // COMMANDER OPTIONS
if (faction.IsCommander(from))
{
AddButton(20, 250, 4005, 4007, 0, GumpButtonType.Page, 6);
}
else
{
AddImage(20, 250, 4020);
}
AddHtmlLocalized(55, 275, 300, 20, 1011426); // LEAVE THIS FACTION
AddButton(20, 275, 4005, 4007, ToButtonID(0, 1));
AddHtmlLocalized(55, 300, 200, 20, 1011441); // EXIT
AddButton(20, 300, 4005, 4007, 0);
AddPage(2);
AddHtmlLocalized(20, 30, 250, 20, 1011430); // CITY STATUS
var towns = Town.Towns;
for (var i = 0; i < towns.Count; ++i)
{
var town = towns[i];
AddHtmlText(40, 55 + i * 30, 150, 20, town.Definition.TownName, false, false);
if (town.Owner == null)
{
AddHtmlLocalized(125, 80, 350, 20, 1011480 + faction.Tithe / 10);
AddHtmlLocalized(200, 55 + i * 30, 150, 20, 1011462); // : Neutral
}
else
{
AddHtml(125, 80, 350, 20, $"{faction.Tithe}%");
AddHtmlLocalized(200, 55 + i * 30, 150, 20, town.Owner.Definition.OwnerLabel);
BaseMonolith monolith = town.Monolith;
AddImage(20, 60 + i * 30, monolith?.Sigil?.IsPurifying == true ? 0x938 : 0x939);
}
}
AddHtmlLocalized(20, 100, 100, 20, 1011458); // Traps placed :
AddHtml(125, 100, 50, 20, faction.Traps.Count.ToString());
AddImage(20, 300, 2361);
AddHtmlLocalized(45, 295, 300, 20, 1011491); // sigil may be recaptured
AddHtmlLocalized(55, 225, 200, 20, 1011428); // VOTE FOR LEADERSHIP
AddButton(20, 225, 4005, 4007, ToButtonID(0, 0));
AddImage(20, 320, 2360);
AddHtmlLocalized(45, 315, 300, 20, 1011492); // sigil may not be recaptured
AddHtmlLocalized(55, 150, 100, 20, 1011430); // CITY STATUS
AddButton(20, 150, 4005, 4007, 0, GumpButtonType.Page, 2);
AddHtmlLocalized(55, 350, 100, 20, 1011447); // BACK
AddButton(20, 350, 4005, 4007, 0, GumpButtonType.Page, 1);
AddHtmlLocalized(55, 175, 100, 20, 1011444); // STATISTICS
AddButton(20, 175, 4005, 4007, 0, GumpButtonType.Page, 4);
AddPage(4);
var isMerchantQualified = MerchantTitles.HasMerchantQualifications(from);
AddHtmlLocalized(20, 30, 150, 20, 1011444); // STATISTICS
var pl = PlayerState.Find(from);
AddHtmlLocalized(20, 100, 100, 20, 1011445); // Name :
AddHtml(120, 100, 150, 20, from.Name);
if (pl != null && pl.MerchantTitle != MerchantTitle.None)
AddHtmlLocalized(20, 130, 100, 20, 1018064); // score :
AddHtml(120, 130, 100, 20, (pl?.KillPoints ?? 0).ToString());
AddHtmlLocalized(20, 160, 100, 20, 1011446); // Rank :
AddHtml(120, 160, 100, 20, (pl?.Rank.Rank ?? 0).ToString());
AddHtmlLocalized(55, 250, 100, 20, 1011447); // BACK
AddButton(20, 250, 4005, 4007, 0, GumpButtonType.Page, 1);
if ((pl == null || pl.MerchantTitle == MerchantTitle.None) && isMerchantQualified)
{
AddPage(5);
AddHtmlLocalized(20, 30, 250, 20, 1011467); // MERCHANT OPTIONS
AddHtmlLocalized(20, 80, 300, 20, 1011473); // Select the title you wish to display
var infos = MerchantTitles.Info;
for (var i = 0; i < infos.Length; ++i)
{
AddHtmlLocalized(55, 200, 250, 20, 1011460); // UNDECLARE FACTION MERCHANT
AddButton(20, 200, 4005, 4007, ToButtonID(1, 0));
}
else if (isMerchantQualified)
{
AddHtmlLocalized(55, 200, 250, 20, 1011459); // DECLARE FACTION MERCHANT
AddButton(20, 200, 4005, 4007, 0, GumpButtonType.Page, 5);
}
else
{
AddHtmlLocalized(55, 200, 250, 20, 1011467); // MERCHANT OPTIONS
AddImage(20, 200, 4020);
}
var info = infos[i];
AddHtmlLocalized(55, 250, 300, 20, 1011461); // COMMANDER OPTIONS
if (faction.IsCommander(from))
{
AddButton(20, 250, 4005, 4007, 0, GumpButtonType.Page, 6);
}
else
{
AddImage(20, 250, 4020);
}
AddHtmlLocalized(55, 275, 300, 20, 1011426); // LEAVE THIS FACTION
AddButton(20, 275, 4005, 4007, ToButtonID(0, 1));
AddHtmlLocalized(55, 300, 200, 20, 1011441); // EXIT
AddButton(20, 300, 4005, 4007, 0);
AddPage(2);
AddHtmlLocalized(20, 30, 250, 20, 1011430); // CITY STATUS
var towns = Town.Towns;
for (var i = 0; i < towns.Count; ++i)
{
var town = towns[i];
AddHtmlText(40, 55 + i * 30, 150, 20, town.Definition.TownName, false, false);
if (town.Owner == null)
if (MerchantTitles.IsQualified(from, info))
{
AddHtmlLocalized(200, 55 + i * 30, 150, 20, 1011462); // : Neutral
AddButton(20, 100 + i * 30, 4005, 4007, ToButtonID(1, i + 1));
}
else
{
AddHtmlLocalized(200, 55 + i * 30, 150, 20, town.Owner.Definition.OwnerLabel);
BaseMonolith monolith = town.Monolith;
AddImage(20, 60 + i * 30, monolith?.Sigil?.IsPurifying == true ? 0x938 : 0x939);
AddImage(20, 100 + i * 30, 4020);
}
AddHtmlText(55, 100 + i * 30, 200, 20, info.Label, false, false);
}
AddImage(20, 300, 2361);
AddHtmlLocalized(45, 295, 300, 20, 1011491); // sigil may be recaptured
AddHtmlLocalized(55, 340, 100, 20, 1011447); // BACK
AddButton(20, 340, 4005, 4007, 0, GumpButtonType.Page, 1);
}
AddImage(20, 320, 2360);
AddHtmlLocalized(45, 315, 300, 20, 1011492); // sigil may not be recaptured
if (faction.IsCommander(from))
{
AddPage(6);
AddHtmlLocalized(55, 350, 100, 20, 1011447); // BACK
AddButton(20, 350, 4005, 4007, 0, GumpButtonType.Page, 1);
AddHtmlLocalized(20, 30, 200, 20, 1011461); // COMMANDER OPTIONS
AddPage(4);
AddHtmlLocalized(20, 30, 150, 20, 1011444); // STATISTICS
AddHtmlLocalized(20, 100, 100, 20, 1011445); // Name :
AddHtml(120, 100, 150, 20, from.Name);
AddHtmlLocalized(20, 130, 100, 20, 1018064); // score :
AddHtml(120, 130, 100, 20, (pl?.KillPoints ?? 0).ToString());
AddHtmlLocalized(20, 160, 100, 20, 1011446); // Rank :
AddHtml(120, 160, 100, 20, (pl?.Rank.Rank ?? 0).ToString());
AddHtmlLocalized(55, 250, 100, 20, 1011447); // BACK
AddButton(20, 250, 4005, 4007, 0, GumpButtonType.Page, 1);
if ((pl == null || pl.MerchantTitle == MerchantTitle.None) && isMerchantQualified)
AddHtmlLocalized(20, 70, 120, 20, 1011457); // Tithe rate :
if (faction.Tithe >= 0 && faction.Tithe <= 100 && faction.Tithe % 10 == 0)
{
AddPage(5);
AddHtmlLocalized(140, 70, 250, 20, 1011480 + faction.Tithe / 10);
}
else
{
AddHtml(140, 70, 250, 20, $"{faction.Tithe}%");
}
AddHtmlLocalized(20, 30, 250, 20, 1011467); // MERCHANT OPTIONS
AddHtmlLocalized(20, 100, 120, 20, 1011474); // Silver available :
AddHtml(140, 100, 50, 20, faction.Silver.ToString("N0")); // NOTE: Added 'N0' formatting
AddHtmlLocalized(20, 80, 300, 20, 1011473); // Select the title you wish to display
AddHtmlLocalized(55, 130, 200, 20, 1011478); // CHANGE TITHE RATE
AddButton(20, 130, 4005, 4007, 0, GumpButtonType.Page, 8);
var infos = MerchantTitles.Info;
AddHtmlLocalized(55, 160, 200, 20, 1018301); // TRANSFER SILVER
if (faction.Silver >= 10000)
{
AddButton(20, 160, 4005, 4007, 0, GumpButtonType.Page, 7);
}
else
{
AddImage(20, 160, 4020);
}
for (var i = 0; i < infos.Length; ++i)
AddHtmlLocalized(55, 310, 100, 20, 1011447); // BACK
AddButton(20, 310, 4005, 4007, 0, GumpButtonType.Page, 1);
if (faction.Silver >= 10000)
{
AddPage(7);
AddHtmlLocalized(20, 30, 250, 20, 1011476); // TOWN FINANCE
AddHtmlLocalized(20, 50, 400, 20, 1011477); // Select a town to transfer 10000 silver to
for (var i = 0; i < towns.Count; ++i)
{
var info = infos[i];
var town = towns[i];
if (MerchantTitles.IsQualified(from, info))
AddHtmlText(55, 75 + i * 30, 200, 20, town.Definition.TownName, false, false);
if (town.Owner == faction)
{
AddButton(20, 100 + i * 30, 4005, 4007, ToButtonID(1, i + 1));
AddButton(20, 75 + i * 30, 4005, 4007, ToButtonID(2, i));
}
else
{
AddImage(20, 100 + i * 30, 4020);
AddImage(20, 75 + i * 30, 4020);
}
AddHtmlText(55, 100 + i * 30, 200, 20, info.Label, false, false);
}
AddHtmlLocalized(55, 340, 100, 20, 1011447); // BACK
AddButton(20, 340, 4005, 4007, 0, GumpButtonType.Page, 1);
}
if (faction.IsCommander(from))
{
AddPage(6);
AddHtmlLocalized(20, 30, 200, 20, 1011461); // COMMANDER OPTIONS
AddHtmlLocalized(20, 70, 120, 20, 1011457); // Tithe rate :
if (faction.Tithe >= 0 && faction.Tithe <= 100 && faction.Tithe % 10 == 0)
{
AddHtmlLocalized(140, 70, 250, 20, 1011480 + faction.Tithe / 10);
}
else
{
AddHtml(140, 70, 250, 20, $"{faction.Tithe}%");
}
AddHtmlLocalized(20, 100, 120, 20, 1011474); // Silver available :
AddHtml(140, 100, 50, 20, faction.Silver.ToString("N0")); // NOTE: Added 'N0' formatting
AddHtmlLocalized(55, 130, 200, 20, 1011478); // CHANGE TITHE RATE
AddButton(20, 130, 4005, 4007, 0, GumpButtonType.Page, 8);
AddHtmlLocalized(55, 160, 200, 20, 1018301); // TRANSFER SILVER
if (faction.Silver >= 10000)
{
AddButton(20, 160, 4005, 4007, 0, GumpButtonType.Page, 7);
}
else
{
AddImage(20, 160, 4020);
}
AddHtmlLocalized(55, 310, 100, 20, 1011447); // BACK
AddButton(20, 310, 4005, 4007, 0, GumpButtonType.Page, 1);
}
if (faction.Silver >= 10000)
AddPage(8);
AddHtmlLocalized(20, 30, 400, 20, 1011479); // Select the % for the new tithe rate
var y = 55;
for (var i = 0; i <= 10; ++i)
{
if (i == 5)
{
AddPage(7);
AddHtmlLocalized(20, 30, 250, 20, 1011476); // TOWN FINANCE
AddHtmlLocalized(20, 50, 400, 20, 1011477); // Select a town to transfer 10000 silver to
for (var i = 0; i < towns.Count; ++i)
{
var town = towns[i];
AddHtmlText(55, 75 + i * 30, 200, 20, town.Definition.TownName, false, false);
if (town.Owner == faction)
{
AddButton(20, 75 + i * 30, 4005, 4007, ToButtonID(2, i));
}
else
{
AddImage(20, 75 + i * 30, 4020);
}
}
AddHtmlLocalized(55, 310, 100, 20, 1011447); // BACK
AddButton(20, 310, 4005, 4007, 0, GumpButtonType.Page, 1);
y += 5;
}
AddPage(8);
AddHtmlLocalized(55, y, 300, 20, 1011480 + i);
AddButton(20, y, 4005, 4007, ToButtonID(3, i));
AddHtmlLocalized(20, 30, 400, 20, 1011479); // Select the % for the new tithe rate
y += 20;
var y = 55;
for (var i = 0; i <= 10; ++i)
if (i == 5)
{
if (i == 5)
{
y += 5;
}
AddHtmlLocalized(55, y, 300, 20, 1011480 + i);
AddButton(20, y, 4005, 4007, ToButtonID(3, i));
y += 20;
if (i == 5)
{
y += 5;
}
y += 5;
}
AddHtmlLocalized(55, 310, 300, 20, 1011447); // BACK
AddButton(20, 310, 4005, 4007, 0, GumpButtonType.Page, 1);
}
}
public override int ButtonTypes => 4;
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (!FromButtonID(info.ButtonID, out var type, out var index))
{
return;
}
switch (type)
{
case 0: // general
{
switch (index)
{
case 0: // vote
{
m_From.SendGump(new ElectionGump(m_From, m_Faction.Election));
break;
}
case 1: // leave
{
m_From.SendGump(new LeaveFactionGump(m_From, m_Faction));
break;
}
}
break;
}
case 1: // merchant title
{
if (index >= 0 && index <= MerchantTitles.Info.Length)
{
var pl = PlayerState.Find(m_From);
var newTitle = (MerchantTitle)index;
var mti = MerchantTitles.GetInfo(newTitle);
if (mti == null)
{
m_From.SendLocalizedMessage(1010120); // Your merchant title has been removed
if (pl != null)
{
pl.MerchantTitle = newTitle;
}
}
else if (MerchantTitles.IsQualified(m_From, mti))
{
m_From.SendLocalizedMessage(mti.Assigned);
if (pl != null)
{
pl.MerchantTitle = newTitle;
}
}
}
break;
}
case 2: // transfer silver
{
if (!m_Faction.IsCommander(m_From))
{
return;
}
var towns = Town.Towns;
if (index >= 0 && index < towns.Count)
{
var town = towns[index];
if (town.Owner == m_Faction)
{
if (m_Faction.Silver >= 10000)
{
m_Faction.Silver -= 10000;
town.Silver += 10000;
// 10k in silver has been received by:
m_From.SendLocalizedMessage(1042726, true, $" {town.Definition.FriendlyName}");
}
}
}
break;
}
case 3: // change tithe
{
if (!m_Faction.IsCommander(m_From))
{
return;
}
if (index >= 0 && index <= 10)
{
m_Faction.Tithe = index * 10;
}
break;
}
}
AddHtmlLocalized(55, 310, 300, 20, 1011447); // BACK
AddButton(20, 310, 4005, 4007, 0, GumpButtonType.Page, 1);
}
}
}
public override int ButtonTypes => 4;
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (!FromButtonID(info.ButtonID, out var type, out var index))
{
return;
}
switch (type)
{
case 0: // general
{
switch (index)
{
case 0: // vote
{
m_From.SendGump(new ElectionGump(m_From, m_Faction.Election));
break;
}
case 1: // leave
{
m_From.SendGump(new LeaveFactionGump(m_From, m_Faction));
break;
}
}
break;
}
case 1: // merchant title
{
if (index >= 0 && index <= MerchantTitles.Info.Length)
{
var pl = PlayerState.Find(m_From);
var newTitle = (MerchantTitle)index;
var mti = MerchantTitles.GetInfo(newTitle);
if (mti == null)
{
m_From.SendLocalizedMessage(1010120); // Your merchant title has been removed
if (pl != null)
{
pl.MerchantTitle = newTitle;
}
}
else if (MerchantTitles.IsQualified(m_From, mti))
{
m_From.SendLocalizedMessage(mti.Assigned);
if (pl != null)
{
pl.MerchantTitle = newTitle;
}
}
}
break;
}
case 2: // transfer silver
{
if (!m_Faction.IsCommander(m_From))
{
return;
}
var towns = Town.Towns;
if (index >= 0 && index < towns.Count)
{
var town = towns[index];
if (town.Owner == m_Faction)
{
if (m_Faction.Silver >= 10000)
{
m_Faction.Silver -= 10000;
town.Silver += 10000;
// 10k in silver has been received by:
m_From.SendLocalizedMessage(1042726, true, $" {town.Definition.FriendlyName}");
}
}
}
break;
}
case 3: // change tithe
{
if (!m_Faction.IsCommander(m_From))
{
return;
}
if (index >= 0 && index <= 10)
{
m_Faction.Tithe = index * 10;
}
break;
}
}
}
}

View file

@ -3,294 +3,293 @@ using Server.Mobiles;
using Server.Multis;
using Server.Network;
namespace Server.Factions
namespace Server.Factions;
public class FinanceGump : FactionGump
{
public class FinanceGump : FactionGump
private static readonly int[] m_PriceOffsets =
{
private static readonly int[] m_PriceOffsets =
-30, -25, -20, -15, -10, -5,
+50, +100, +150, +200, +250, +300
};
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
private readonly Town m_Town;
public FinanceGump(PlayerMobile from, Faction faction, Town town) : base(50, 50)
{
m_From = from;
m_Faction = faction;
m_Town = town;
AddPage(0);
AddBackground(0, 0, 320, 410, 5054);
AddBackground(10, 10, 300, 390, 3000);
AddPage(1);
AddHtmlLocalized(20, 30, 260, 25, 1011541); // FINANCE MINISTER
AddHtmlLocalized(55, 90, 200, 25, 1011539); // CHANGE PRICES
AddButton(20, 90, 4005, 4007, 0, GumpButtonType.Page, 2);
AddHtmlLocalized(55, 120, 200, 25, 1011540); // BUY SHOPKEEPERS
AddButton(20, 120, 4005, 4007, 0, GumpButtonType.Page, 3);
AddHtmlLocalized(55, 150, 200, 25, 1011495); // VIEW FINANCES
AddButton(20, 150, 4005, 4007, 0, GumpButtonType.Page, 4);
AddHtmlLocalized(55, 360, 200, 25, 1011441); // EXIT
AddButton(20, 360, 4005, 4007, 0);
AddPage(2);
AddHtmlLocalized(20, 30, 200, 25, 1011539); // CHANGE PRICES
for (var i = 0; i < m_PriceOffsets.Length; ++i)
{
-30, -25, -20, -15, -10, -5,
+50, +100, +150, +200, +250, +300
};
var ofs = m_PriceOffsets[i];
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
private readonly Town m_Town;
var x = 20 + i / 6 * 150;
var y = 90 + i % 6 * 30;
public FinanceGump(PlayerMobile from, Faction faction, Town town) : base(50, 50)
{
m_From = from;
m_Faction = faction;
m_Town = town;
AddRadio(x, y, 208, 209, town.Tax == ofs, i + 1);
AddPage(0);
AddBackground(0, 0, 320, 410, 5054);
AddBackground(10, 10, 300, 390, 3000);
AddPage(1);
AddHtmlLocalized(20, 30, 260, 25, 1011541); // FINANCE MINISTER
AddHtmlLocalized(55, 90, 200, 25, 1011539); // CHANGE PRICES
AddButton(20, 90, 4005, 4007, 0, GumpButtonType.Page, 2);
AddHtmlLocalized(55, 120, 200, 25, 1011540); // BUY SHOPKEEPERS
AddButton(20, 120, 4005, 4007, 0, GumpButtonType.Page, 3);
AddHtmlLocalized(55, 150, 200, 25, 1011495); // VIEW FINANCES
AddButton(20, 150, 4005, 4007, 0, GumpButtonType.Page, 4);
AddHtmlLocalized(55, 360, 200, 25, 1011441); // EXIT
AddButton(20, 360, 4005, 4007, 0);
AddPage(2);
AddHtmlLocalized(20, 30, 200, 25, 1011539); // CHANGE PRICES
for (var i = 0; i < m_PriceOffsets.Length; ++i)
if (ofs < 0)
{
var ofs = m_PriceOffsets[i];
var x = 20 + i / 6 * 150;
var y = 90 + i % 6 * 30;
AddRadio(x, y, 208, 209, town.Tax == ofs, i + 1);
if (ofs < 0)
{
AddLabel(x + 35, y, 0x26, $"- {-ofs}%");
}
else
{
AddLabel(x + 35, y, 0x12A, $"+ {ofs}%");
}
AddLabel(x + 35, y, 0x26, $"- {-ofs}%");
}
AddRadio(20, 270, 208, 209, town.Tax == 0, 0);
AddHtmlLocalized(55, 270, 90, 25, 1011542); // normal
AddHtmlLocalized(55, 330, 200, 25, 1011509); // Set Prices
AddButton(20, 330, 4005, 4007, ToButtonID(0, 0));
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 1);
AddPage(3);
AddHtmlLocalized(20, 30, 200, 25, 1011540); // BUY SHOPKEEPERS
var vendorLists = town.VendorLists;
for (var i = 0; i < vendorLists.Count; ++i)
else
{
var list = vendorLists[i];
AddButton(20, 90 + i * 40, 4005, 4007, 0, GumpButtonType.Page, 5 + i);
AddItem(55, 90 + i * 40, list.Definition.ItemID);
AddHtmlText(100, 90 + i * 40, 200, 25, list.Definition.Label, false, false);
}
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 1);
AddPage(4);
var financeUpkeep = town.FinanceUpkeep;
var sheriffUpkeep = town.SheriffUpkeep;
var dailyIncome = town.DailyIncome;
var netCashFlow = town.NetCashFlow;
AddHtmlLocalized(20, 30, 300, 25, 1011524); // FINANCE STATEMENT
AddHtmlLocalized(20, 80, 300, 25, 1011538); // Current total money for town :
AddLabel(20, 100, 0x44, town.Silver.ToString());
AddHtmlLocalized(20, 130, 300, 25, 1011520); // Finance Minister Upkeep :
AddLabel(20, 150, 0x44, financeUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 180, 300, 25, 1011521); // Sheriff Upkeep :
AddLabel(20, 200, 0x44, sheriffUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 230, 300, 25, 1011522); // Town Income :
AddLabel(20, 250, 0x44, dailyIncome.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 280, 300, 25, 1011523); // Net Cash flow per day :
AddLabel(20, 300, 0x44, netCashFlow.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 1);
for (var i = 0; i < vendorLists.Count; ++i)
{
var vendorList = vendorLists[i];
AddPage(5 + i);
AddHtmlText(60, 30, 300, 25, vendorList.Definition.Header, false, false);
AddItem(20, 30, vendorList.Definition.ItemID);
AddHtmlLocalized(20, 90, 200, 25, 1011514); // You have :
AddLabel(230, 90, 0x26, vendorList.Vendors.Count.ToString());
AddHtmlLocalized(20, 120, 200, 25, 1011515); // Maximum :
AddLabel(230, 120, 0x256, vendorList.Definition.Maximum.ToString());
AddHtmlLocalized(20, 150, 200, 25, 1011516); // Cost :
AddLabel(230, 150, 0x44, vendorList.Definition.Price.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 180, 200, 25, 1011517); // Daily Pay :
AddLabel(230, 180, 0x37, vendorList.Definition.Upkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 210, 200, 25, 1011518); // Current Silver :
AddLabel(230, 210, 0x44, town.Silver.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 240, 200, 25, 1011519); // Current Payroll :
AddLabel(230, 240, 0x44, financeUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlText(55, 300, 200, 25, vendorList.Definition.Label, false, false);
if (town.Silver >= vendorList.Definition.Price)
{
AddButton(20, 300, 4005, 4007, ToButtonID(1, i));
}
else
{
AddImage(20, 300, 4020);
}
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 3);
AddLabel(x + 35, y, 0x12A, $"+ {ofs}%");
}
}
public override int ButtonTypes => 2;
AddRadio(20, 270, 208, 209, town.Tax == 0, 0);
AddHtmlLocalized(55, 270, 90, 25, 1011542); // normal
public override void OnResponse(NetState sender, in RelayInfo info)
AddHtmlLocalized(55, 330, 200, 25, 1011509); // Set Prices
AddButton(20, 330, 4005, 4007, ToButtonID(0, 0));
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 1);
AddPage(3);
AddHtmlLocalized(20, 30, 200, 25, 1011540); // BUY SHOPKEEPERS
var vendorLists = town.VendorLists;
for (var i = 0; i < vendorLists.Count; ++i)
{
if (!m_Town.IsFinance(m_From) || m_Town.Owner != m_Faction)
var list = vendorLists[i];
AddButton(20, 90 + i * 40, 4005, 4007, 0, GumpButtonType.Page, 5 + i);
AddItem(55, 90 + i * 40, list.Definition.ItemID);
AddHtmlText(100, 90 + i * 40, 200, 25, list.Definition.Label, false, false);
}
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 1);
AddPage(4);
var financeUpkeep = town.FinanceUpkeep;
var sheriffUpkeep = town.SheriffUpkeep;
var dailyIncome = town.DailyIncome;
var netCashFlow = town.NetCashFlow;
AddHtmlLocalized(20, 30, 300, 25, 1011524); // FINANCE STATEMENT
AddHtmlLocalized(20, 80, 300, 25, 1011538); // Current total money for town :
AddLabel(20, 100, 0x44, town.Silver.ToString());
AddHtmlLocalized(20, 130, 300, 25, 1011520); // Finance Minister Upkeep :
AddLabel(20, 150, 0x44, financeUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 180, 300, 25, 1011521); // Sheriff Upkeep :
AddLabel(20, 200, 0x44, sheriffUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 230, 300, 25, 1011522); // Town Income :
AddLabel(20, 250, 0x44, dailyIncome.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 280, 300, 25, 1011523); // Net Cash flow per day :
AddLabel(20, 300, 0x44, netCashFlow.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 1);
for (var i = 0; i < vendorLists.Count; ++i)
{
var vendorList = vendorLists[i];
AddPage(5 + i);
AddHtmlText(60, 30, 300, 25, vendorList.Definition.Header, false, false);
AddItem(20, 30, vendorList.Definition.ItemID);
AddHtmlLocalized(20, 90, 200, 25, 1011514); // You have :
AddLabel(230, 90, 0x26, vendorList.Vendors.Count.ToString());
AddHtmlLocalized(20, 120, 200, 25, 1011515); // Maximum :
AddLabel(230, 120, 0x256, vendorList.Definition.Maximum.ToString());
AddHtmlLocalized(20, 150, 200, 25, 1011516); // Cost :
AddLabel(230, 150, 0x44, vendorList.Definition.Price.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 180, 200, 25, 1011517); // Daily Pay :
AddLabel(230, 180, 0x37, vendorList.Definition.Upkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 210, 200, 25, 1011518); // Current Silver :
AddLabel(230, 210, 0x44, town.Silver.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 240, 200, 25, 1011519); // Current Payroll :
AddLabel(230, 240, 0x44, financeUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlText(55, 300, 200, 25, vendorList.Definition.Label, false, false);
if (town.Silver >= vendorList.Definition.Price)
{
m_From.SendLocalizedMessage(1010339); // You no longer control this city
return;
AddButton(20, 300, 4005, 4007, ToButtonID(1, i));
}
else
{
AddImage(20, 300, 4020);
}
if (!FromButtonID(info.ButtonID, out var type, out var index))
{
return;
}
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 3);
}
}
switch (type)
{
case 0: // general
public override int ButtonTypes => 2;
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (!m_Town.IsFinance(m_From) || m_Town.Owner != m_Faction)
{
m_From.SendLocalizedMessage(1010339); // You no longer control this city
return;
}
if (!FromButtonID(info.ButtonID, out var type, out var index))
{
return;
}
switch (type)
{
case 0: // general
{
switch (index)
{
switch (index)
{
case 0: // set price
case 0: // set price
{
var switches = info.Switches;
if (switches.Length == 0)
{
var switches = info.Switches;
break;
}
if (switches.Length == 0)
var opt = switches[0];
var newTax = 0;
if (opt >= 1 && opt <= m_PriceOffsets.Length)
{
newTax = m_PriceOffsets[opt - 1];
}
if (m_Town.Tax == newTax)
{
break;
}
if (m_From.AccessLevel == AccessLevel.Player && !m_Town.TaxChangeReady)
{
var remaining = Core.Now - (m_Town.LastTaxChange + Town.TaxChangePeriod);
if (remaining.TotalMinutes < 4)
{
break;
// You must wait a short while before changing prices again.
m_From.SendLocalizedMessage(1042165);
}
var opt = switches[0];
var newTax = 0;
if (opt >= 1 && opt <= m_PriceOffsets.Length)
else if (remaining.TotalMinutes < 10)
{
newTax = m_PriceOffsets[opt - 1];
// You must wait several minutes before changing prices again.
m_From.SendLocalizedMessage(1042166);
}
if (m_Town.Tax == newTax)
else if (remaining.TotalHours < 1)
{
break;
// You must wait up to an hour before changing prices again.
m_From.SendLocalizedMessage(1042167);
}
if (m_From.AccessLevel == AccessLevel.Player && !m_Town.TaxChangeReady)
else if (remaining.TotalHours < 4)
{
var remaining = Core.Now - (m_Town.LastTaxChange + Town.TaxChangePeriod);
if (remaining.TotalMinutes < 4)
{
// You must wait a short while before changing prices again.
m_From.SendLocalizedMessage(1042165);
}
else if (remaining.TotalMinutes < 10)
{
// You must wait several minutes before changing prices again.
m_From.SendLocalizedMessage(1042166);
}
else if (remaining.TotalHours < 1)
{
// You must wait up to an hour before changing prices again.
m_From.SendLocalizedMessage(1042167);
}
else if (remaining.TotalHours < 4)
{
// You must wait a few hours before changing prices again.
m_From.SendLocalizedMessage(1042168);
}
else
{
// You must wait several hours before changing prices again.
m_From.SendLocalizedMessage(1042169);
}
// You must wait a few hours before changing prices again.
m_From.SendLocalizedMessage(1042168);
}
else
{
m_Town.Tax = newTax;
if (m_From.AccessLevel == AccessLevel.Player)
{
m_Town.LastTaxChange = Core.Now;
}
// You must wait several hours before changing prices again.
m_From.SendLocalizedMessage(1042169);
}
break;
}
}
break;
}
case 1: // make vendor
{
var vendorLists = m_Town.VendorLists;
if (index >= 0 && index < vendorLists.Count)
{
var vendorList = vendorLists[index];
if (Town.FromRegion(m_From.Region) != m_Town)
{
// You must be in your controlled city to buy Items
m_From.SendLocalizedMessage(1010305);
}
else if (vendorList.Vendors.Count >= vendorList.Definition.Maximum)
{
// You currently have too many of this enhancement type to place another
m_From.SendLocalizedMessage(1010306);
}
else if (BaseBoat.FindBoatAt(m_From.Location, m_From.Map) != null)
{
m_From.SendMessage("You cannot place a vendor here");
}
else if (m_Town.Silver >= vendorList.Definition.Price)
{
var vendor = vendorList.Construct(m_Town, m_Faction);
if (vendor != null)
else
{
m_Town.Silver -= vendorList.Definition.Price;
m_Town.Tax = newTax;
vendor.MoveToWorld(m_From.Location, m_From.Map);
vendor.Home = vendor.Location;
if (m_From.AccessLevel == AccessLevel.Player)
{
m_Town.LastTaxChange = Core.Now;
}
}
break;
}
}
break;
}
case 1: // make vendor
{
var vendorLists = m_Town.VendorLists;
if (index >= 0 && index < vendorLists.Count)
{
var vendorList = vendorLists[index];
if (Town.FromRegion(m_From.Region) != m_Town)
{
// You must be in your controlled city to buy Items
m_From.SendLocalizedMessage(1010305);
}
else if (vendorList.Vendors.Count >= vendorList.Definition.Maximum)
{
// You currently have too many of this enhancement type to place another
m_From.SendLocalizedMessage(1010306);
}
else if (BaseBoat.FindBoatAt(m_From.Location, m_From.Map) != null)
{
m_From.SendMessage("You cannot place a vendor here");
}
else if (m_Town.Silver >= vendorList.Definition.Price)
{
var vendor = vendorList.Construct(m_Town, m_Faction);
if (vendor != null)
{
m_Town.Silver -= vendorList.Definition.Price;
vendor.MoveToWorld(m_From.Location, m_From.Map);
vendor.Home = vendor.Location;
}
}
break;
}
}
break;
}
}
}
}
}

View file

@ -3,95 +3,94 @@ using Server.Items;
using Server.Mobiles;
using Server.Network;
namespace Server.Factions
namespace Server.Factions;
public class HorseBreederGump : FactionGump
{
public class HorseBreederGump : FactionGump
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
public HorseBreederGump(PlayerMobile from, Faction faction) : base(20, 30)
{
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
m_From = from;
m_Faction = faction;
public HorseBreederGump(PlayerMobile from, Faction faction) : base(20, 30)
AddPage(0);
AddBackground(0, 0, 320, 280, 5054);
AddBackground(10, 10, 300, 260, 3000);
AddHtmlText(20, 30, 300, 25, faction.Definition.Header, false, false);
AddHtmlLocalized(20, 60, 300, 25, 1018306); // Purchase a Faction War Horse
AddItem(70, 120, 0x3FFE);
AddItem(150, 120, 0xEF2);
AddLabel(190, 122, 0x3E3, FactionWarHorse.SilverPrice.ToString("N0")); // NOTE: Added 'N0'
AddItem(150, 150, 0xEEF);
AddLabel(190, 152, 0x3E3, FactionWarHorse.GoldPrice.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(55, 210, 200, 25, 1011011); // CONTINUE
AddButton(20, 210, 4005, 4007, 1);
AddHtmlLocalized(55, 240, 200, 25, 1011012); // CANCEL
AddButton(20, 240, 4005, 4007, 0);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (info.ButtonID != 1)
{
m_From = from;
m_Faction = faction;
AddPage(0);
AddBackground(0, 0, 320, 280, 5054);
AddBackground(10, 10, 300, 260, 3000);
AddHtmlText(20, 30, 300, 25, faction.Definition.Header, false, false);
AddHtmlLocalized(20, 60, 300, 25, 1018306); // Purchase a Faction War Horse
AddItem(70, 120, 0x3FFE);
AddItem(150, 120, 0xEF2);
AddLabel(190, 122, 0x3E3, FactionWarHorse.SilverPrice.ToString("N0")); // NOTE: Added 'N0'
AddItem(150, 150, 0xEEF);
AddLabel(190, 152, 0x3E3, FactionWarHorse.GoldPrice.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(55, 210, 200, 25, 1011011); // CONTINUE
AddButton(20, 210, 4005, 4007, 1);
AddHtmlLocalized(55, 240, 200, 25, 1011012); // CANCEL
AddButton(20, 240, 4005, 4007, 0);
return;
}
public override void OnResponse(NetState sender, in RelayInfo info)
if (Faction.Find(m_From) != m_Faction)
{
if (info.ButtonID != 1)
return;
}
var pack = m_From.Backpack;
if (pack == null)
{
return;
}
var horse = new FactionWarHorse(m_Faction);
if (m_From.Followers + horse.ControlSlots > m_From.FollowersMax)
{
// TODO: Message?
horse.Delete();
}
else
{
if (pack.GetAmount(typeof(Silver)) < FactionWarHorse.SilverPrice)
{
return;
}
if (Faction.Find(m_From) != m_Faction)
{
return;
}
var pack = m_From.Backpack;
if (pack == null)
{
return;
}
var horse = new FactionWarHorse(m_Faction);
if (m_From.Followers + horse.ControlSlots > m_From.FollowersMax)
{
// TODO: Message?
sender.Mobile.SendLocalizedMessage(1042204); // You do not have enough silver.
horse.Delete();
}
else if (pack.GetAmount(typeof(Gold)) < FactionWarHorse.GoldPrice)
{
sender.Mobile.SendLocalizedMessage(1042205); // You do not have enough gold.
horse.Delete();
}
else if (pack.ConsumeTotal(typeof(Silver), FactionWarHorse.SilverPrice) &&
pack.ConsumeTotal(typeof(Gold), FactionWarHorse.GoldPrice))
{
horse.Controlled = true;
horse.ControlMaster = m_From;
horse.ControlOrder = OrderType.Follow;
horse.ControlTarget = m_From;
horse.MoveToWorld(m_From.Location, m_From.Map);
}
else
{
if (pack.GetAmount(typeof(Silver)) < FactionWarHorse.SilverPrice)
{
sender.Mobile.SendLocalizedMessage(1042204); // You do not have enough silver.
horse.Delete();
}
else if (pack.GetAmount(typeof(Gold)) < FactionWarHorse.GoldPrice)
{
sender.Mobile.SendLocalizedMessage(1042205); // You do not have enough gold.
horse.Delete();
}
else if (pack.ConsumeTotal(typeof(Silver), FactionWarHorse.SilverPrice) &&
pack.ConsumeTotal(typeof(Gold), FactionWarHorse.GoldPrice))
{
horse.Controlled = true;
horse.ControlMaster = m_From;
horse.ControlOrder = OrderType.Follow;
horse.ControlTarget = m_From;
horse.MoveToWorld(m_From.Location, m_From.Map);
}
else
{
horse.Delete();
}
horse.Delete();
}
}
}
}
}

View file

@ -2,52 +2,51 @@ using Server.Gumps;
using Server.Mobiles;
using Server.Network;
namespace Server.Factions
namespace Server.Factions;
public class JoinStoneGump : FactionGump
{
public class JoinStoneGump : FactionGump
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
public JoinStoneGump(PlayerMobile from, Faction faction) : base(20, 30)
{
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
m_From = from;
m_Faction = faction;
public JoinStoneGump(PlayerMobile from, Faction faction) : base(20, 30)
AddPage(0);
AddBackground(0, 0, 550, 440, 5054);
AddBackground(10, 10, 530, 420, 3000);
AddHtmlText(20, 30, 510, 20, faction.Definition.Header, false, false);
AddHtmlText(20, 130, 510, 100, faction.Definition.About, true, true);
AddHtmlLocalized(20, 60, 100, 20, 1011429); // Led By :
AddHtml(125, 60, 200, 20, faction.Commander != null ? faction.Commander.Name : "Nobody");
AddHtmlLocalized(20, 80, 100, 20, 1011457); // Tithe rate :
if (faction.Tithe >= 0 && faction.Tithe <= 100 && faction.Tithe % 10 == 0)
{
m_From = from;
m_Faction = faction;
AddPage(0);
AddBackground(0, 0, 550, 440, 5054);
AddBackground(10, 10, 530, 420, 3000);
AddHtmlText(20, 30, 510, 20, faction.Definition.Header, false, false);
AddHtmlText(20, 130, 510, 100, faction.Definition.About, true, true);
AddHtmlLocalized(20, 60, 100, 20, 1011429); // Led By :
AddHtml(125, 60, 200, 20, faction.Commander != null ? faction.Commander.Name : "Nobody");
AddHtmlLocalized(20, 80, 100, 20, 1011457); // Tithe rate :
if (faction.Tithe >= 0 && faction.Tithe <= 100 && faction.Tithe % 10 == 0)
{
AddHtmlLocalized(125, 80, 350, 20, 1011480 + faction.Tithe / 10);
}
else
{
AddHtml(125, 80, 350, 20, $"{faction.Tithe}%");
}
AddButton(20, 400, 4005, 4007, 1);
AddHtmlLocalized(55, 400, 200, 20, 1011425); // JOIN THIS FACTION
AddButton(300, 400, 4005, 4007, 0);
AddHtmlLocalized(335, 400, 200, 20, 1011012); // CANCEL
AddHtmlLocalized(125, 80, 350, 20, 1011480 + faction.Tithe / 10);
}
else
{
AddHtml(125, 80, 350, 20, $"{faction.Tithe}%");
}
public override void OnResponse(NetState sender, in RelayInfo info)
AddButton(20, 400, 4005, 4007, 1);
AddHtmlLocalized(55, 400, 200, 20, 1011425); // JOIN THIS FACTION
AddButton(300, 400, 4005, 4007, 0);
AddHtmlLocalized(335, 400, 200, 20, 1011012); // CANCEL
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (info.ButtonID == 1)
{
if (info.ButtonID == 1)
{
m_Faction.OnJoinAccepted(m_From);
}
m_Faction.OnJoinAccepted(m_From);
}
}
}
}

View file

@ -4,55 +4,85 @@ using Server.Gumps;
using Server.Mobiles;
using Server.Network;
namespace Server.Factions
namespace Server.Factions;
public class LeaveFactionGump : FactionGump
{
public class LeaveFactionGump : FactionGump
private readonly PlayerMobile m_From;
private Faction m_Faction;
public LeaveFactionGump(PlayerMobile from, Faction faction) : base(20, 30)
{
private readonly PlayerMobile m_From;
private Faction m_Faction;
m_From = from;
m_Faction = faction;
public LeaveFactionGump(PlayerMobile from, Faction faction) : base(20, 30)
AddBackground(0, 0, 270, 120, 5054);
AddBackground(10, 10, 250, 100, 3000);
if (from.Guild is Guild guild && guild.Leader == from)
{
m_From = from;
m_Faction = faction;
AddBackground(0, 0, 270, 120, 5054);
AddBackground(10, 10, 250, 100, 3000);
if (from.Guild is Guild guild && guild.Leader == from)
{
AddHtmlLocalized(
20,
15,
230,
60,
1018057, // Are you sure you want your entire guild to leave this faction?
true,
true
);
}
else
{
// Are you sure you want to leave this faction?s
AddHtmlLocalized(20, 15, 230, 60, 1018063, true, true);
}
AddHtmlLocalized(55, 80, 75, 20, 1011011); // CONTINUE
AddButton(20, 80, 4005, 4007, 1);
AddHtmlLocalized(170, 80, 75, 20, 1011012); // CANCEL
AddButton(135, 80, 4005, 4007, 2);
AddHtmlLocalized(
20,
15,
230,
60,
1018057, // Are you sure you want your entire guild to leave this faction?
true,
true
);
}
else
{
// Are you sure you want to leave this faction?s
AddHtmlLocalized(20, 15, 230, 60, 1018063, true, true);
}
public override void OnResponse(NetState sender, in RelayInfo info)
AddHtmlLocalized(55, 80, 75, 20, 1011011); // CONTINUE
AddButton(20, 80, 4005, 4007, 1);
AddHtmlLocalized(170, 80, 75, 20, 1011012); // CANCEL
AddButton(135, 80, 4005, 4007, 2);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
switch (info.ButtonID)
{
switch (info.ButtonID)
{
case 1: // continue
case 1: // continue
{
if (m_From.Guild is not Guild guild)
{
if (m_From.Guild is not Guild guild)
var pl = PlayerState.Find(m_From);
if (pl != null)
{
var pl = PlayerState.Find(m_From);
pl.Leaving = Core.Now;
if (TimeSpan.FromDays(3.0) == Faction.LeavePeriod)
{
m_From.SendLocalizedMessage(1005065); // You will be removed from the faction in 3 days
}
else
{
m_From.SendMessage(
$"You will be removed from the faction in {Faction.LeavePeriod.TotalDays} days."
);
}
}
}
else if (guild.Leader != m_From)
{
// You cannot quit the faction because you are not the guild master
m_From.SendLocalizedMessage(1005061);
}
else
{
m_From.SendLocalizedMessage(1042285); // Your guild is now quitting the faction.
for (var i = 0; i < guild.Members.Count; ++i)
{
var mob = guild.Members[i];
var pl = PlayerState.Find(mob);
if (pl != null)
{
@ -60,57 +90,26 @@ namespace Server.Factions
if (TimeSpan.FromDays(3.0) == Faction.LeavePeriod)
{
m_From.SendLocalizedMessage(1005065); // You will be removed from the faction in 3 days
// Your guild will quit the faction in 3 days
mob.SendLocalizedMessage(1005060);
}
else
{
m_From.SendMessage(
$"You will be removed from the faction in {Faction.LeavePeriod.TotalDays} days."
mob.SendMessage(
$"Your guild will quit the faction in {Faction.LeavePeriod.TotalDays} days."
);
}
}
}
else if (guild.Leader != m_From)
{
// You cannot quit the faction because you are not the guild master
m_From.SendLocalizedMessage(1005061);
}
else
{
m_From.SendLocalizedMessage(1042285); // Your guild is now quitting the faction.
for (var i = 0; i < guild.Members.Count; ++i)
{
var mob = guild.Members[i];
var pl = PlayerState.Find(mob);
if (pl != null)
{
pl.Leaving = Core.Now;
if (TimeSpan.FromDays(3.0) == Faction.LeavePeriod)
{
// Your guild will quit the faction in 3 days
mob.SendLocalizedMessage(1005060);
}
else
{
mob.SendMessage(
$"Your guild will quit the faction in {Faction.LeavePeriod.TotalDays} days."
);
}
}
}
}
break;
}
case 2: // cancel
{
m_From.SendLocalizedMessage(500737); // Canceled resignation.
break;
}
}
break;
}
case 2: // cancel
{
m_From.SendLocalizedMessage(500737); // Canceled resignation.
break;
}
}
}
}
}

View file

@ -3,168 +3,167 @@ using Server.Mobiles;
using Server.Multis;
using Server.Network;
namespace Server.Factions
namespace Server.Factions;
public class SheriffGump : FactionGump
{
public class SheriffGump : FactionGump
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
private readonly Town m_Town;
public SheriffGump(PlayerMobile from, Faction faction, Town town) : base(50, 50)
{
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
private readonly Town m_Town;
m_From = from;
m_Faction = faction;
m_Town = town;
public SheriffGump(PlayerMobile from, Faction faction, Town town) : base(50, 50)
AddPage(0);
AddBackground(0, 0, 320, 410, 5054);
AddBackground(10, 10, 300, 390, 3000);
AddPage(1);
AddHtmlLocalized(20, 30, 260, 25, 1011431); // Sheriff
AddHtmlLocalized(55, 90, 200, 25, 1011494); // HIRE GUARDS
AddButton(20, 90, 4005, 4007, 0, GumpButtonType.Page, 3);
AddHtmlLocalized(55, 120, 200, 25, 1011495); // VIEW FINANCES
AddButton(20, 120, 4005, 4007, 0, GumpButtonType.Page, 2);
AddHtmlLocalized(55, 360, 200, 25, 1011441); // Exit
AddButton(20, 360, 4005, 4007, 0);
AddPage(2);
var financeUpkeep = town.FinanceUpkeep;
var sheriffUpkeep = town.SheriffUpkeep;
var dailyIncome = town.DailyIncome;
var netCashFlow = town.NetCashFlow;
AddHtmlLocalized(20, 30, 300, 25, 1011524); // FINANCE STATEMENT
AddHtmlLocalized(20, 80, 300, 25, 1011538); // Current total money for town :
AddLabel(20, 100, 0x44, town.Silver.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 130, 300, 25, 1011520); // Finance Minister Upkeep :
AddLabel(20, 150, 0x44, financeUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 180, 300, 25, 1011521); // Sheriff Upkeep :
AddLabel(20, 200, 0x44, sheriffUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 230, 300, 25, 1011522); // Town Income :
AddLabel(20, 250, 0x44, dailyIncome.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 280, 300, 25, 1011523); // Net Cash flow per day :
AddLabel(20, 300, 0x44, netCashFlow.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 1);
AddPage(3);
AddHtmlLocalized(20, 30, 300, 25, 1011494); // HIRE GUARDS
var guardLists = town.GuardLists;
for (var i = 0; i < guardLists.Count; ++i)
{
m_From = from;
m_Faction = faction;
m_Town = town;
var guardList = guardLists[i];
var y = 90 + i * 60;
AddPage(0);
AddBackground(0, 0, 320, 410, 5054);
AddBackground(10, 10, 300, 390, 3000);
AddPage(1);
AddHtmlLocalized(20, 30, 260, 25, 1011431); // Sheriff
AddHtmlLocalized(55, 90, 200, 25, 1011494); // HIRE GUARDS
AddButton(20, 90, 4005, 4007, 0, GumpButtonType.Page, 3);
AddHtmlLocalized(55, 120, 200, 25, 1011495); // VIEW FINANCES
AddButton(20, 120, 4005, 4007, 0, GumpButtonType.Page, 2);
AddHtmlLocalized(55, 360, 200, 25, 1011441); // Exit
AddButton(20, 360, 4005, 4007, 0);
AddPage(2);
var financeUpkeep = town.FinanceUpkeep;
var sheriffUpkeep = town.SheriffUpkeep;
var dailyIncome = town.DailyIncome;
var netCashFlow = town.NetCashFlow;
AddHtmlLocalized(20, 30, 300, 25, 1011524); // FINANCE STATEMENT
AddHtmlLocalized(20, 80, 300, 25, 1011538); // Current total money for town :
AddLabel(20, 100, 0x44, town.Silver.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 130, 300, 25, 1011520); // Finance Minister Upkeep :
AddLabel(20, 150, 0x44, financeUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 180, 300, 25, 1011521); // Sheriff Upkeep :
AddLabel(20, 200, 0x44, sheriffUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 230, 300, 25, 1011522); // Town Income :
AddLabel(20, 250, 0x44, dailyIncome.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 280, 300, 25, 1011523); // Net Cash flow per day :
AddLabel(20, 300, 0x44, netCashFlow.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 1);
AddPage(3);
AddHtmlLocalized(20, 30, 300, 25, 1011494); // HIRE GUARDS
var guardLists = town.GuardLists;
for (var i = 0; i < guardLists.Count; ++i)
{
var guardList = guardLists[i];
var y = 90 + i * 60;
AddButton(20, y, 4005, 4007, 0, GumpButtonType.Page, 4 + i);
CenterItem(guardList.Definition.ItemID, 50, y - 20, 70, 60);
AddHtmlText(120, y, 200, 25, guardList.Definition.Header, false, false);
}
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 1);
for (var i = 0; i < guardLists.Count; ++i)
{
var guardList = guardLists[i];
AddPage(4 + i);
AddHtmlText(90, 30, 300, 25, guardList.Definition.Header, false, false);
CenterItem(guardList.Definition.ItemID, 10, 10, 80, 80);
AddHtmlLocalized(20, 90, 200, 25, 1011514); // You have :
AddLabel(230, 90, 0x26, guardList.Guards.Count.ToString());
AddHtmlLocalized(20, 120, 200, 25, 1011515); // Maximum :
AddLabel(230, 120, 0x12A, guardList.Definition.Maximum.ToString());
AddHtmlLocalized(20, 150, 200, 25, 1011516); // Cost :
AddLabel(230, 150, 0x44, guardList.Definition.Price.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 180, 200, 25, 1011517); // Daily Pay :
AddLabel(230, 180, 0x37, guardList.Definition.Upkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 210, 200, 25, 1011518); // Current Silver :
AddLabel(230, 210, 0x44, town.Silver.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 240, 200, 25, 1011519); // Current Payroll :
AddLabel(230, 240, 0x44, sheriffUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlText(55, 300, 200, 25, guardList.Definition.Label, false, false);
AddButton(20, 300, 4005, 4007, 1 + i);
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 3);
}
AddButton(20, y, 4005, 4007, 0, GumpButtonType.Page, 4 + i);
CenterItem(guardList.Definition.ItemID, 50, y - 20, 70, 60);
AddHtmlText(120, y, 200, 25, guardList.Definition.Header, false, false);
}
private void CenterItem(int itemID, int x, int y, int w, int h)
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 1);
for (var i = 0; i < guardLists.Count; ++i)
{
var rc = ItemBounds.Table[itemID];
AddItem(x + (w - rc.Width) / 2 - rc.X, y + (h - rc.Height) / 2 - rc.Y, itemID);
var guardList = guardLists[i];
AddPage(4 + i);
AddHtmlText(90, 30, 300, 25, guardList.Definition.Header, false, false);
CenterItem(guardList.Definition.ItemID, 10, 10, 80, 80);
AddHtmlLocalized(20, 90, 200, 25, 1011514); // You have :
AddLabel(230, 90, 0x26, guardList.Guards.Count.ToString());
AddHtmlLocalized(20, 120, 200, 25, 1011515); // Maximum :
AddLabel(230, 120, 0x12A, guardList.Definition.Maximum.ToString());
AddHtmlLocalized(20, 150, 200, 25, 1011516); // Cost :
AddLabel(230, 150, 0x44, guardList.Definition.Price.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 180, 200, 25, 1011517); // Daily Pay :
AddLabel(230, 180, 0x37, guardList.Definition.Upkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 210, 200, 25, 1011518); // Current Silver :
AddLabel(230, 210, 0x44, town.Silver.ToString("N0")); // NOTE: Added 'N0'
AddHtmlLocalized(20, 240, 200, 25, 1011519); // Current Payroll :
AddLabel(230, 240, 0x44, sheriffUpkeep.ToString("N0")); // NOTE: Added 'N0'
AddHtmlText(55, 300, 200, 25, guardList.Definition.Label, false, false);
AddButton(20, 300, 4005, 4007, 1 + i);
AddHtmlLocalized(55, 360, 200, 25, 1011067); // Previous page
AddButton(20, 360, 4005, 4007, 0, GumpButtonType.Page, 3);
}
}
private void CenterItem(int itemID, int x, int y, int w, int h)
{
var rc = ItemBounds.Table[itemID];
AddItem(x + (w - rc.Width) / 2 - rc.X, y + (h - rc.Height) / 2 - rc.Y, itemID);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (!m_Town.IsSheriff(m_From) || m_Town.Owner != m_Faction)
{
m_From.SendLocalizedMessage(1010339); // You no longer control this city
return;
}
public override void OnResponse(NetState sender, in RelayInfo info)
var index = info.ButtonID - 1;
if (index >= 0 && index < m_Town.GuardLists.Count)
{
if (!m_Town.IsSheriff(m_From) || m_Town.Owner != m_Faction)
var guardList = m_Town.GuardLists[index];
if (Town.FromRegion(m_From.Region) != m_Town)
{
m_From.SendLocalizedMessage(1010339); // You no longer control this city
return;
m_From.SendLocalizedMessage(1010305); // You must be in your controlled city to buy Items
}
var index = info.ButtonID - 1;
if (index >= 0 && index < m_Town.GuardLists.Count)
else if (guardList.Guards.Count >= guardList.Definition.Maximum)
{
var guardList = m_Town.GuardLists[index];
// You currently have too many of this enhancement type to place another
m_From.SendLocalizedMessage(1010306);
}
else if (BaseBoat.FindBoatAt(m_From.Location, m_From.Map) != null)
{
m_From.SendMessage("You cannot place a guard here");
}
else if (m_Town.Silver >= guardList.Definition.Price)
{
var guard = guardList.Construct();
if (Town.FromRegion(m_From.Region) != m_Town)
if (guard != null)
{
m_From.SendLocalizedMessage(1010305); // You must be in your controlled city to buy Items
}
else if (guardList.Guards.Count >= guardList.Definition.Maximum)
{
// You currently have too many of this enhancement type to place another
m_From.SendLocalizedMessage(1010306);
}
else if (BaseBoat.FindBoatAt(m_From.Location, m_From.Map) != null)
{
m_From.SendMessage("You cannot place a guard here");
}
else if (m_Town.Silver >= guardList.Definition.Price)
{
var guard = guardList.Construct();
guard.Faction = m_Faction;
guard.Town = m_Town;
if (guard != null)
{
guard.Faction = m_Faction;
guard.Town = m_Town;
m_Town.Silver -= guardList.Definition.Price;
m_Town.Silver -= guardList.Definition.Price;
guard.MoveToWorld(m_From.Location, m_From.Map);
guard.Home = guard.Location;
}
guard.MoveToWorld(m_From.Location, m_From.Map);
guard.Home = guard.Location;
}
}
}
}
}
}

View file

@ -3,206 +3,209 @@ using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Factions
namespace Server.Factions;
public class TownStoneGump : FactionGump
{
public class TownStoneGump : FactionGump
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
private readonly Town m_Town;
public TownStoneGump(PlayerMobile from, Faction faction, Town town) : base(50, 50)
{
private readonly Faction m_Faction;
private readonly PlayerMobile m_From;
private readonly Town m_Town;
m_From = from;
m_Faction = faction;
m_Town = town;
public TownStoneGump(PlayerMobile from, Faction faction, Town town) : base(50, 50)
AddPage(0);
AddBackground(0, 0, 320, 250, 5054);
AddBackground(10, 10, 300, 230, 3000);
AddHtmlText(25, 30, 250, 25, town.Definition.TownStoneHeader, false, false);
AddHtmlLocalized(55, 60, 150, 25, 1011557); // Hire Sheriff
AddButton(20, 60, 4005, 4007, 1);
AddHtmlLocalized(55, 90, 150, 25, 1011559); // Hire Finance Minister
AddButton(20, 90, 4005, 4007, 2);
AddHtmlLocalized(55, 120, 150, 25, 1011558); // Fire Sheriff
AddButton(20, 120, 4005, 4007, 3);
AddHtmlLocalized(55, 150, 150, 25, 1011560); // Fire Finance Minister
AddButton(20, 150, 4005, 4007, 4);
AddHtmlLocalized(55, 210, 150, 25, 1011441); // EXIT
AddButton(20, 210, 4005, 4007, 0);
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (m_Town.Owner != m_Faction || !m_Faction.IsCommander(m_From))
{
m_From = from;
m_Faction = faction;
m_Town = town;
AddPage(0);
AddBackground(0, 0, 320, 250, 5054);
AddBackground(10, 10, 300, 230, 3000);
AddHtmlText(25, 30, 250, 25, town.Definition.TownStoneHeader, false, false);
AddHtmlLocalized(55, 60, 150, 25, 1011557); // Hire Sheriff
AddButton(20, 60, 4005, 4007, 1);
AddHtmlLocalized(55, 90, 150, 25, 1011559); // Hire Finance Minister
AddButton(20, 90, 4005, 4007, 2);
AddHtmlLocalized(55, 120, 150, 25, 1011558); // Fire Sheriff
AddButton(20, 120, 4005, 4007, 3);
AddHtmlLocalized(55, 150, 150, 25, 1011560); // Fire Finance Minister
AddButton(20, 150, 4005, 4007, 4);
AddHtmlLocalized(55, 210, 150, 25, 1011441); // EXIT
AddButton(20, 210, 4005, 4007, 0);
m_From.SendLocalizedMessage(1010339); // You no longer control this city
return;
}
public override void OnResponse(NetState sender, in RelayInfo info)
switch (info.ButtonID)
{
if (m_Town.Owner != m_Faction || !m_Faction.IsCommander(m_From))
{
m_From.SendLocalizedMessage(1010339); // You no longer control this city
return;
}
switch (info.ButtonID)
{
case 1: // hire sheriff
case 1: // hire sheriff
{
if (m_Town.Sheriff != null)
{
if (m_Town.Sheriff != null)
{
// You must fire your Sheriff before you can elect a new one
m_From.SendLocalizedMessage(1010342);
}
else
{
m_From.SendLocalizedMessage(1010347); // Who shall be your new sheriff
m_From.BeginTarget(12, false, TargetFlags.None, HireSheriff_OnTarget);
}
break;
// You must fire your Sheriff before you can elect a new one
m_From.SendLocalizedMessage(1010342);
}
case 2: // hire finance minister
else
{
if (m_Town.Finance != null)
{
// You must fire your finance minister before you can elect a new one
m_From.SendLocalizedMessage(1010345);
}
else
{
m_From.SendLocalizedMessage(1010348); // Who shall be your new Minister of Finances?
m_From.BeginTarget(12, false, TargetFlags.None, HireFinanceMinister_OnTarget);
}
break;
m_From.SendLocalizedMessage(1010347); // Who shall be your new sheriff
m_From.BeginTarget(12, false, TargetFlags.None, HireSheriff_OnTarget);
}
case 3: // fire sheriff
break;
}
case 2: // hire finance minister
{
if (m_Town.Finance != null)
{
if (m_Town.Sheriff == null)
{
// You need to elect a sheriff before you can fire one
m_From.SendLocalizedMessage(1010350);
}
else
{
m_From.SendLocalizedMessage(1010349); // You have fired your sheriff
m_Town.Sheriff.SendLocalizedMessage(1010270); // You have been fired as Sheriff
m_Town.Sheriff = null;
}
break;
// You must fire your finance minister before you can elect a new one
m_From.SendLocalizedMessage(1010345);
}
case 4: // fire finance minister
else
{
if (m_Town.Finance == null)
{
// You need to elect a financial minister before you can fire one
m_From.SendLocalizedMessage(1010352);
}
else
{
m_From.SendLocalizedMessage(1010351); // You have fired your financial Minister
m_Town.Finance.SendLocalizedMessage(1010151); // You have been fired as Finance Minister
m_Town.Finance = null;
}
break;
m_From.SendLocalizedMessage(1010348); // Who shall be your new Minister of Finances?
m_From.BeginTarget(12, false, TargetFlags.None, HireFinanceMinister_OnTarget);
}
}
break;
}
case 3: // fire sheriff
{
if (m_Town.Sheriff == null)
{
// You need to elect a sheriff before you can fire one
m_From.SendLocalizedMessage(1010350);
}
else
{
m_From.SendLocalizedMessage(1010349); // You have fired your sheriff
m_Town.Sheriff.SendLocalizedMessage(1010270); // You have been fired as Sheriff
m_Town.Sheriff = null;
}
break;
}
case 4: // fire finance minister
{
if (m_Town.Finance == null)
{
// You need to elect a financial minister before you can fire one
m_From.SendLocalizedMessage(1010352);
}
else
{
m_From.SendLocalizedMessage(1010351); // You have fired your financial Minister
m_Town.Finance.SendLocalizedMessage(1010151); // You have been fired as Finance Minister
m_Town.Finance = null;
}
break;
}
}
}
private void HireSheriff_OnTarget(Mobile from, object obj)
{
if (m_Town.Owner != m_Faction || !m_Faction.IsCommander(from))
{
from.SendLocalizedMessage(1010339); // You no longer control this city
return;
}
private void HireSheriff_OnTarget(Mobile from, object obj)
if (m_Town.Sheriff != null)
{
if (m_Town.Owner != m_Faction || !m_Faction.IsCommander(from))
{
from.SendLocalizedMessage(1010339); // You no longer control this city
return;
}
if (m_Town.Sheriff != null)
{
from.SendLocalizedMessage(1010342); // You must fire your Sheriff before you can elect a new one
}
else if (obj is Mobile targ)
{
var pl = PlayerState.Find(targ);
if (pl == null)
{
from.SendLocalizedMessage(1010337); // You must pick someone in a faction
}
else if (pl.Faction != m_Faction)
{
from.SendLocalizedMessage(1010338); // You must pick someone in the correct faction
}
else if (m_Faction.Commander == targ)
{
from.SendLocalizedMessage(1010335); // You cannot elect a commander to a town position
}
else if (pl.Sheriff != null || pl.Finance != null)
{
// You must pick someone who does not already hold a city post
from.SendLocalizedMessage(1005245);
}
else
{
m_Town.Sheriff = targ;
targ.SendLocalizedMessage(1010340); // You are now the Sheriff
from.SendLocalizedMessage(1010341); // You have elected a Sheriff
}
}
else
{
from.SendLocalizedMessage(1010334); // You must select a player to hold a city position!
}
from.SendLocalizedMessage(1010342); // You must fire your Sheriff before you can elect a new one
return;
}
private void HireFinanceMinister_OnTarget(Mobile from, object obj)
if (obj is not Mobile m)
{
if (m_Town.Owner != m_Faction || !m_Faction.IsCommander(from))
{
from.SendLocalizedMessage(1010339); // You no longer control this city
}
else if (m_Town.Finance != null)
{
from.SendLocalizedMessage(1010342); // You must fire your Sheriff before you can elect a new one
}
else if (obj is Mobile targ)
{
var pl = PlayerState.Find(targ);
from.SendLocalizedMessage(1010334); // You must select a player to hold a city position!
return;
}
if (pl == null)
{
from.SendLocalizedMessage(1010337); // You must pick someone in a faction
}
else if (pl.Faction != m_Faction)
{
from.SendLocalizedMessage(1010338); // You must pick someone in the correct faction
}
else if (m_Faction.Commander == targ)
{
from.SendLocalizedMessage(1010335); // You cannot elect a commander to a town position
}
else if (pl.Sheriff != null || pl.Finance != null)
{
// You must pick someone who does not already hold a city post
from.SendLocalizedMessage(1005245);
}
else
{
m_Town.Finance = targ;
targ.SendLocalizedMessage(1010343); // You are now the Financial Minister
from.SendLocalizedMessage(1010344); // You have elected a Financial Minister
}
}
else
{
from.SendLocalizedMessage(1010334); // You must select a player to hold a city position!
}
var pl = PlayerState.Find(m);
if (pl == null)
{
from.SendLocalizedMessage(1010337); // You must pick someone in a faction
}
else if (pl.Faction != m_Faction)
{
from.SendLocalizedMessage(1010338); // You must pick someone in the correct faction
}
else if (m_Faction.Commander == m)
{
from.SendLocalizedMessage(1010335); // You cannot elect a commander to a town position
}
else if (pl.Sheriff != null || pl.Finance != null)
{
// You must pick someone who does not already hold a city post
from.SendLocalizedMessage(1005245);
}
else
{
m_Town.Sheriff = m;
m.SendLocalizedMessage(1010340); // You are now the Sheriff
from.SendLocalizedMessage(1010341); // You have elected a Sheriff
}
}
private void HireFinanceMinister_OnTarget(Mobile from, object obj)
{
if (m_Town.Owner != m_Faction || !m_Faction.IsCommander(from))
{
from.SendLocalizedMessage(1010339); // You no longer control this city
return;
}
if (m_Town.Finance != null)
{
from.SendLocalizedMessage(1010342); // You must fire your Sheriff before you can elect a new one
return;
}
if (obj is not Mobile m)
{
from.SendLocalizedMessage(1010334); // You must select a player to hold a city position!
return;
}
var pl = PlayerState.Find(m);
if (pl == null)
{
from.SendLocalizedMessage(1010337); // You must pick someone in a faction
}
else if (pl.Faction != m_Faction)
{
from.SendLocalizedMessage(1010338); // You must pick someone in the correct faction
}
else if (m_Faction.Commander == m)
{
from.SendLocalizedMessage(1010335); // You cannot elect a commander to a town position
}
else if (pl.Sheriff != null || pl.Finance != null)
{
// You must pick someone who does not already hold a city post
from.SendLocalizedMessage(1005245);
}
else
{
m_Town.Finance = m;
m.SendLocalizedMessage(1010343); // You are now the Financial Minister
from.SendLocalizedMessage(1010344); // You have elected a Financial Minister
}
}
}

View file

@ -2,75 +2,74 @@ using Server.Gumps;
using Server.Mobiles;
using Server.Network;
namespace Server.Factions
namespace Server.Factions;
public class VoteGump : FactionGump
{
public class VoteGump : FactionGump
private readonly Election m_Election;
private readonly PlayerMobile m_From;
public VoteGump(PlayerMobile from, Election election) : base(50, 50)
{
private readonly Election m_Election;
private readonly PlayerMobile m_From;
m_From = from;
m_Election = election;
public VoteGump(PlayerMobile from, Election election) : base(50, 50)
var canVote = election.CanVote(from);
AddPage(0);
AddBackground(0, 0, 420, 350, 5054);
AddBackground(10, 10, 400, 330, 3000);
AddHtmlText(20, 20, 380, 20, election.Faction.Definition.Header, false, false);
if (canVote)
{
m_From = from;
m_Election = election;
AddHtmlLocalized(20, 60, 380, 20, 1011428); // VOTE FOR LEADERSHIP
}
else
{
AddHtmlLocalized(20, 60, 380, 20, 1038032); // You have already voted in this election.
}
var canVote = election.CanVote(from);
AddPage(0);
AddBackground(0, 0, 420, 350, 5054);
AddBackground(10, 10, 400, 330, 3000);
AddHtmlText(20, 20, 380, 20, election.Faction.Definition.Header, false, false);
for (var i = 0; i < election.Candidates.Count; ++i)
{
var cd = election.Candidates[i];
if (canVote)
{
AddHtmlLocalized(20, 60, 380, 20, 1011428); // VOTE FOR LEADERSHIP
}
else
{
AddHtmlLocalized(20, 60, 380, 20, 1038032); // You have already voted in this election.
AddButton(20, 100 + i * 20, 4005, 4007, i + 1);
}
for (var i = 0; i < election.Candidates.Count; ++i)
{
var cd = election.Candidates[i];
if (canVote)
{
AddButton(20, 100 + i * 20, 4005, 4007, i + 1);
}
AddLabel(55, 100 + i * 20, 0, cd.Mobile.Name);
AddLabel(300, 100 + i * 20, 0, cd.Votes.ToString());
}
AddButton(20, 310, 4005, 4007, 0);
AddHtmlLocalized(55, 310, 100, 20, 1011012); // CANCEL
AddLabel(55, 100 + i * 20, 0, cd.Mobile.Name);
AddLabel(300, 100 + i * 20, 0, cd.Votes.ToString());
}
public override void OnResponse(NetState sender, in RelayInfo info)
AddButton(20, 310, 4005, 4007, 0);
AddHtmlLocalized(55, 310, 100, 20, 1011012); // CANCEL
}
public override void OnResponse(NetState sender, in RelayInfo info)
{
if (info.ButtonID == 0)
{
if (info.ButtonID == 0)
m_From.SendGump(new FactionStoneGump(m_From, m_Election.Faction));
}
else
{
if (!m_Election.CanVote(m_From))
{
m_From.SendGump(new FactionStoneGump(m_From, m_Election.Faction));
return;
}
else
var index = info.ButtonID - 1;
if (index >= 0 && index < m_Election.Candidates.Count)
{
if (!m_Election.CanVote(m_From))
{
return;
}
var index = info.ButtonID - 1;
if (index >= 0 && index < m_Election.Candidates.Count)
{
m_Election.Candidates[index].Voters.Add(new Voter(m_From, m_Election.Candidates[index].Mobile));
}
m_From.SendGump(new VoteGump(m_From, m_Election));
m_Election.Candidates[index].Voters.Add(new Voter(m_From, m_Election.Candidates[index].Mobile));
}
m_From.SendGump(new VoteGump(m_From, m_Election));
}
}
}
}

View file

@ -39,15 +39,13 @@ public class CouncilOfMages : Faction
1005189, // Members of the Council of Mages will now be beaten with a stick.
// Moonglow
new StrongholdDefinition(
new[]
{
[
new Rectangle2D(4463, 1487, 15, 35),
new Rectangle2D(4450, 1522, 35, 48)
},
],
new Point3D(4469, 1486, 0),
new Point3D(4457, 1544, 0),
new[]
{
[
new Point3D(4464, 1534, 21),
new Point3D(4470, 1536, 21),
new Point3D(4468, 1534, 21),
@ -56,7 +54,7 @@ public class CouncilOfMages : Faction
new Point3D(4466, 1534, 21),
new Point3D(4466, 1536, 21),
new Point3D(4464, 1536, 21)
}
]
),
// Magincia
/* new StrongholdDefinition(
@ -80,8 +78,7 @@ public class CouncilOfMages : Faction
new Point3D( 3797, 2249, 20 ),
new Point3D( 3797, 2246, 20 )
} ), */
new[]
{
[
new RankDefinition(10, 991, 8, 1060789), // Inquisitor of the Council
new RankDefinition(9, 950, 7, 1060788), // Archon of Principle
new RankDefinition(8, 900, 6, 1060787), // Luminary
@ -92,9 +89,8 @@ public class CouncilOfMages : Faction
new RankDefinition(3, 400, 4, 1060785), // Mystic
new RankDefinition(2, 200, 4, 1060785), // Mystic
new RankDefinition(1, 0, 4, 1060785) // Mystic
},
new[]
{
],
[
new GuardDefinition(
typeof(FactionHenchman),
0x1403,
@ -131,7 +127,7 @@ public class CouncilOfMages : Faction
1011508, // ELDER WIZARD
1011502 // Hire Elder Wizard
)
}
]
);
}

View file

@ -39,14 +39,12 @@ public class Minax : Faction
1005191, // Followers of Minax will now be told to go away.
1005192, // Followers of Minax will now be hanged by their toes.
new StrongholdDefinition(
new[]
{
[
new Rectangle2D(1097, 2570, 70, 50)
},
],
new Point3D(1172, 2593, 0),
new Point3D(1117, 2587, 18),
new[]
{
[
new Point3D(1113, 2601, 18),
new Point3D(1113, 2598, 18),
new Point3D(1113, 2595, 18),
@ -55,10 +53,9 @@ public class Minax : Faction
new Point3D(1116, 2598, 18),
new Point3D(1116, 2595, 18),
new Point3D(1116, 2592, 18)
}
]
),
new[]
{
[
new RankDefinition(10, 991, 8, 1060784), // Avenger of Mondain
new RankDefinition(9, 950, 7, 1060783), // Dread Knight
new RankDefinition(8, 900, 6, 1060782), // Warlord
@ -69,9 +66,8 @@ public class Minax : Faction
new RankDefinition(3, 400, 4, 1060780), // Defiler
new RankDefinition(2, 200, 4, 1060780), // Defiler
new RankDefinition(1, 0, 4, 1060780) // Defiler
},
new[]
{
],
[
new GuardDefinition(
typeof(FactionHenchman),
0x1403,
@ -108,7 +104,7 @@ public class Minax : Faction
1011506, // DRAGOON
1011500 // Hire Dragoon
)
}
]
);
}

View file

@ -38,15 +38,13 @@ public class Shadowlords : Faction
1005185, // Minions of the Shadowlords will now be warned of their impending deaths.
1005186, // Minions of the Shadowlords will now be attacked at will.
new StrongholdDefinition(
new[]
{
[
new Rectangle2D(960, 688, 8, 9),
new Rectangle2D(944, 697, 24, 23)
},
],
new Point3D(969, 768, 0),
new Point3D(947, 713, 0),
new[]
{
[
new Point3D(953, 713, 20),
new Point3D(953, 709, 20),
new Point3D(953, 705, 20),
@ -55,10 +53,9 @@ public class Shadowlords : Faction
new Point3D(957, 709, 20),
new Point3D(957, 705, 20),
new Point3D(957, 701, 20)
}
]
),
new[]
{
[
new RankDefinition(10, 991, 8, 1060799), // Purveyor of Darkness
new RankDefinition(9, 950, 7, 1060798), // Agent of Evil
new RankDefinition(8, 900, 6, 1060797), // Bringer of Sorrow
@ -69,9 +66,8 @@ public class Shadowlords : Faction
new RankDefinition(3, 400, 4, 1060795), // Servant
new RankDefinition(2, 200, 4, 1060795), // Servant
new RankDefinition(1, 0, 4, 1060795) // Servant
},
new[]
{
],
[
new GuardDefinition(
typeof(FactionHenchman),
0x1403,
@ -108,7 +104,7 @@ public class Shadowlords : Faction
1011513, // SHADOW MAGE
1011504 // Hire Shadow Mage
)
}
]
);
}

View file

@ -38,8 +38,7 @@ public class TrueBritannians : Faction
1005182, // Followers of Lord British will now be warned of their impending doom.
1005183, // Followers of Lord British will now be attacked on sight.
new StrongholdDefinition(
new[]
{
[
new Rectangle2D(1292, 1556, 25, 25),
new Rectangle2D(1292, 1676, 120, 25),
new Rectangle2D(1388, 1556, 25, 25),
@ -47,11 +46,10 @@ public class TrueBritannians : Faction
new Rectangle2D(1300, 1581, 105, 95),
new Rectangle2D(1405, 1612, 12, 21),
new Rectangle2D(1405, 1633, 11, 5)
},
],
new Point3D(1419, 1622, 20),
new Point3D(1330, 1621, 50),
new[]
{
[
new Point3D(1328, 1627, 50),
new Point3D(1328, 1621, 50),
new Point3D(1334, 1627, 50),
@ -60,10 +58,9 @@ public class TrueBritannians : Faction
new Point3D(1340, 1621, 50),
new Point3D(1345, 1621, 50),
new Point3D(1345, 1627, 50)
}
]
),
new[]
{
[
new RankDefinition(10, 991, 8, 1060794), // Knight of the Codex
new RankDefinition(9, 950, 7, 1060793), // Knight of Virtue
new RankDefinition(8, 900, 6, 1060792), // Crusader
@ -73,10 +70,9 @@ public class TrueBritannians : Faction
new RankDefinition(4, 500, 5, 1060791), // Sentinel
new RankDefinition(3, 400, 4, 1060790), // Defender
new RankDefinition(2, 200, 4, 1060790), // Defender
new RankDefinition(1, 0, 4, 1060790), // Defender
},
new[]
{
new RankDefinition(1, 0, 4, 1060790) // Defender
],
[
new GuardDefinition(
typeof(FactionHenchman),
0x1403,
@ -113,7 +109,7 @@ public class TrueBritannians : Faction
1011529, // PALADIN
1011498 // Hire Paladin
)
}
]
);
}

View file

@ -1,137 +1,136 @@
using System.Collections.Generic;
namespace Server.Factions
namespace Server.Factions;
public abstract class BaseMonolith : BaseSystemController
{
public abstract class BaseMonolith : BaseSystemController
private Faction m_Faction;
private Sigil m_Sigil;
private Town m_Town;
public BaseMonolith(Town town = null, Faction faction = null) : base(0x1183)
{
private Faction m_Faction;
private Sigil m_Sigil;
private Town m_Town;
Movable = false;
Town = town;
Faction = faction;
Monoliths.Add(this);
}
public BaseMonolith(Town town = null, Faction faction = null) : base(0x1183)
public BaseMonolith(Serial serial) : base(serial)
{
Monoliths.Add(this);
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Sigil Sigil
{
get => m_Sigil;
set
{
Movable = false;
Town = town;
Faction = faction;
Monoliths.Add(this);
}
public BaseMonolith(Serial serial) : base(serial)
{
Monoliths.Add(this);
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Sigil Sigil
{
get => m_Sigil;
set
{
if (m_Sigil == value)
{
return;
}
m_Sigil = value;
if (m_Sigil?.LastMonolith != null && m_Sigil.LastMonolith != this && m_Sigil.LastMonolith.Sigil == m_Sigil)
{
m_Sigil.LastMonolith.Sigil = null;
}
if (m_Sigil != null)
{
m_Sigil.LastMonolith = this;
}
UpdateSigil();
}
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Town Town
{
get => m_Town;
set
{
m_Town = value;
OnTownChanged();
}
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Faction Faction
{
get => m_Faction;
set
{
m_Faction = value;
Hue = m_Faction?.Definition.HuePrimary ?? 0;
}
}
public static List<BaseMonolith> Monoliths { get; set; } = new();
public override void OnLocationChange(Point3D oldLocation)
{
base.OnLocationChange(oldLocation);
UpdateSigil();
}
public override void OnMapChange()
{
base.OnMapChange();
UpdateSigil();
}
public virtual void UpdateSigil()
{
if (m_Sigil?.Deleted != false)
if (m_Sigil == value)
{
return;
}
m_Sigil.MoveToWorld(new Point3D(X, Y, Z + 18), Map);
}
m_Sigil = value;
public virtual void OnTownChanged()
{
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
Monoliths.Remove(this);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Town.WriteReference(writer, m_Town);
Faction.WriteReference(writer, m_Faction);
writer.Write(m_Sigil);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
if (m_Sigil?.LastMonolith != null && m_Sigil.LastMonolith != this && m_Sigil.LastMonolith.Sigil == m_Sigil)
{
case 0:
{
Town = Town.ReadReference(reader);
Faction = Faction.ReadReference(reader);
m_Sigil = reader.ReadEntity<Sigil>();
break;
}
m_Sigil.LastMonolith.Sigil = null;
}
if (m_Sigil != null)
{
m_Sigil.LastMonolith = this;
}
UpdateSigil();
}
}
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Town Town
{
get => m_Town;
set
{
m_Town = value;
OnTownChanged();
}
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Faction Faction
{
get => m_Faction;
set
{
m_Faction = value;
Hue = m_Faction?.Definition.HuePrimary ?? 0;
}
}
public static List<BaseMonolith> Monoliths { get; set; } = new();
public override void OnLocationChange(Point3D oldLocation)
{
base.OnLocationChange(oldLocation);
UpdateSigil();
}
public override void OnMapChange()
{
base.OnMapChange();
UpdateSigil();
}
public virtual void UpdateSigil()
{
if (m_Sigil?.Deleted != false)
{
return;
}
m_Sigil.MoveToWorld(new Point3D(X, Y, Z + 18), Map);
}
public virtual void OnTownChanged()
{
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
Monoliths.Remove(this);
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Town.WriteReference(writer, m_Town);
Faction.WriteReference(writer, m_Faction);
writer.Write(m_Sigil);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 0:
{
Town = Town.ReadReference(reader);
Faction = Faction.ReadReference(reader);
m_Sigil = reader.ReadEntity<Sigil>();
break;
}
}
}
}

View file

@ -1,66 +1,44 @@
namespace Server.Factions
using ModernUO.Serialization;
namespace Server.Factions;
[SerializationGenerator(1, false)]
public abstract partial class BaseSystemController : Item
{
public abstract class BaseSystemController : Item
private int _labelNumber;
public BaseSystemController(int itemID) : base(itemID)
{
private int m_LabelNumber;
}
public BaseSystemController(int itemID) : base(itemID)
public virtual int DefaultLabelNumber => 0;
[SerializableProperty(0, useField: nameof(_labelNumber))]
public override int LabelNumber => _labelNumber > 0 ? _labelNumber : DefaultLabelNumber;
public virtual void AssignName(TextDefinition name)
{
if (name?.Number > 0)
{
_labelNumber = name.Number;
Name = null;
}
else if (name?.String != null)
{
_labelNumber = 0;
Name = name.String;
}
else
{
_labelNumber = 0;
Name = null;
}
public BaseSystemController(Serial serial) : base(serial)
{
}
InvalidateProperties();
}
public virtual int DefaultLabelNumber => base.LabelNumber;
public new virtual string DefaultName => null;
public override int LabelNumber
{
get
{
if (m_LabelNumber > 0)
{
return m_LabelNumber;
}
return DefaultLabelNumber;
}
}
public virtual void AssignName(TextDefinition name)
{
if (name?.Number > 0)
{
m_LabelNumber = name.Number;
Name = null;
}
else if (name?.String != null)
{
m_LabelNumber = 0;
Name = name.String;
}
else
{
m_LabelNumber = 0;
Name = DefaultName;
}
InvalidateProperties();
}
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();
}
private void Deserialize(IGenericReader reader, int version)
{
// Do nothing
}
}

View file

@ -1,104 +1,103 @@
using Server.Mobiles;
namespace Server.Factions
namespace Server.Factions;
public class FactionStone : BaseSystemController
{
public class FactionStone : BaseSystemController
private Faction m_Faction;
[Constructible]
public FactionStone(Faction faction = null) : base(0xEDC)
{
private Faction m_Faction;
Movable = false;
Faction = faction;
}
[Constructible]
public FactionStone(Faction faction = null) : base(0xEDC)
public FactionStone(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Faction Faction
{
get => m_Faction;
set
{
Movable = false;
Faction = faction;
m_Faction = value;
AssignName(m_Faction?.Definition.FactionStoneName);
}
}
public override string DefaultName => "faction stone";
public override void OnDoubleClick(Mobile from)
{
if (m_Faction == null)
{
return;
}
public FactionStone(Serial serial) : base(serial)
if (!from.InRange(GetWorldLocation(), 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Faction Faction
else if (FactionGump.Exists(from))
{
get => m_Faction;
set
{
m_Faction = value;
AssignName(m_Faction?.Definition.FactionStoneName);
}
from.SendLocalizedMessage(1042160); // You already have a faction menu open.
}
public override string DefaultName => "faction stone";
public override void OnDoubleClick(Mobile from)
else if (from is PlayerMobile mobile)
{
if (m_Faction == null)
{
return;
}
var existingFaction = Faction.Find(mobile);
if (!from.InRange(GetWorldLocation(), 2))
if (existingFaction == m_Faction || mobile.AccessLevel >= AccessLevel.GameMaster)
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
else if (FactionGump.Exists(from))
{
from.SendLocalizedMessage(1042160); // You already have a faction menu open.
}
else if (from is PlayerMobile mobile)
{
var existingFaction = Faction.Find(mobile);
var pl = PlayerState.Find(mobile);
if (existingFaction == m_Faction || mobile.AccessLevel >= AccessLevel.GameMaster)
if (pl?.IsLeaving == true)
{
var pl = PlayerState.Find(mobile);
if (pl?.IsLeaving == true)
{
// You cannot use the faction stone until you have finished quitting your current faction
mobile.SendLocalizedMessage(1005051);
}
else
{
mobile.SendGump(new FactionStoneGump(mobile, m_Faction));
}
}
else if (existingFaction != null)
{
// TODO: Validate
mobile.SendLocalizedMessage(1005053); // This is not your faction stone!
// You cannot use the faction stone until you have finished quitting your current faction
mobile.SendLocalizedMessage(1005051);
}
else
{
mobile.SendGump(new JoinStoneGump(mobile, m_Faction));
mobile.SendGump(new FactionStoneGump(mobile, m_Faction));
}
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Faction.WriteReference(writer, m_Faction);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
else if (existingFaction != null)
{
case 0:
{
Faction = Faction.ReadReference(reader);
break;
}
// TODO: Validate
mobile.SendLocalizedMessage(1005053); // This is not your faction stone!
}
else
{
mobile.SendGump(new JoinStoneGump(mobile, m_Faction));
}
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Faction.WriteReference(writer, m_Faction);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 0:
{
Faction = Faction.ReadReference(reader);
break;
}
}
}
}

View file

@ -1,81 +1,80 @@
using Server.Mobiles;
namespace Server.Factions
namespace Server.Factions;
public class JoinStone : BaseSystemController
{
public class JoinStone : BaseSystemController
private Faction m_Faction;
[Constructible]
public JoinStone(Faction faction = null) : base(0xEDC)
{
private Faction m_Faction;
Movable = false;
Faction = faction;
}
[Constructible]
public JoinStone(Faction faction = null) : base(0xEDC)
public JoinStone(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Faction Faction
{
get => m_Faction;
set
{
Movable = false;
Faction = faction;
}
m_Faction = value;
public JoinStone(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Faction Faction
{
get => m_Faction;
set
{
m_Faction = value;
Hue = m_Faction?.Definition.HueJoin ?? 0;
AssignName(m_Faction?.Definition.SignupName);
}
}
public override string DefaultName => "faction signup stone";
public override void OnDoubleClick(Mobile from)
{
if (m_Faction == null)
{
return;
}
if (!from.InRange(GetWorldLocation(), 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
else if (FactionGump.Exists(from))
{
from.SendLocalizedMessage(1042160); // You already have a faction menu open.
}
else if (Faction.Find(from) == null && from is PlayerMobile mobile)
{
mobile.SendGump(new JoinStoneGump(mobile, m_Faction));
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Faction.WriteReference(writer, m_Faction);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 0:
{
Faction = Faction.ReadReference(reader);
break;
}
}
Hue = m_Faction?.Definition.HueJoin ?? 0;
AssignName(m_Faction?.Definition.SignupName);
}
}
}
public override string DefaultName => "faction signup stone";
public override void OnDoubleClick(Mobile from)
{
if (m_Faction == null)
{
return;
}
if (!from.InRange(GetWorldLocation(), 2))
{
from.LocalOverheadMessage(MessageType.Regular, 0x3B2, 1019045); // I can't reach that.
}
else if (FactionGump.Exists(from))
{
from.SendLocalizedMessage(1042160); // You already have a faction menu open.
}
else if (Faction.Find(from) == null && from is PlayerMobile mobile)
{
mobile.SendGump(new JoinStoneGump(mobile, m_Faction));
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Faction.WriteReference(writer, m_Faction);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 0:
{
Faction = Faction.ReadReference(reader);
break;
}
}
}
}

View file

@ -4,474 +4,473 @@ using Server.Mobiles;
using Server.Network;
using Server.Targeting;
namespace Server.Factions
namespace Server.Factions;
public class Sigil : BaseSystemController
{
public class Sigil : BaseSystemController
public const int OwnershipHue = 0xB;
// ?? time corrupting faction has to return the sigil before corruption time resets ?
public static readonly TimeSpan CorruptionGrace = TimeSpan.FromMinutes(Core.SE ? 30.0 : 15.0);
// Sigil must be held at a stronghold for this amount of time in order to become corrupted
public static readonly TimeSpan CorruptionPeriod = Core.SE ? TimeSpan.FromHours(10.0) : TimeSpan.FromHours(24.0);
// After a sigil has been corrupted it must be returned to the town within this period of time
public static readonly TimeSpan ReturnPeriod = TimeSpan.FromHours(1.0);
// Once it's been returned the corrupting faction owns the town for this period of time
public static readonly TimeSpan PurificationPeriod = TimeSpan.FromDays(3.0);
private Faction m_Corrupted;
private Faction m_Corrupting;
private Town m_Town;
public Sigil(Town town) : base(0x1869)
{
public const int OwnershipHue = 0xB;
Movable = false;
Town = town;
// ?? time corrupting faction has to return the sigil before corruption time resets ?
public static readonly TimeSpan CorruptionGrace = TimeSpan.FromMinutes(Core.SE ? 30.0 : 15.0);
Sigils.Add(this);
}
// Sigil must be held at a stronghold for this amount of time in order to become corrupted
public static readonly TimeSpan CorruptionPeriod = Core.SE ? TimeSpan.FromHours(10.0) : TimeSpan.FromHours(24.0);
public Sigil(Serial serial) : base(serial)
{
Sigils.Add(this);
}
// After a sigil has been corrupted it must be returned to the town within this period of time
public static readonly TimeSpan ReturnPeriod = TimeSpan.FromHours(1.0);
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public DateTime LastStolen { get; set; }
// Once it's been returned the corrupting faction owns the town for this period of time
public static readonly TimeSpan PurificationPeriod = TimeSpan.FromDays(3.0);
private Faction m_Corrupted;
private Faction m_Corrupting;
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public DateTime GraceStart { get; set; }
private Town m_Town;
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public DateTime CorruptionStart { get; set; }
public Sigil(Town town) : base(0x1869)
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public DateTime PurificationStart { get; set; }
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Town Town
{
get => m_Town;
set
{
Movable = false;
Town = town;
m_Town = value;
Update();
}
}
Sigils.Add(this);
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Faction Corrupted
{
get => m_Corrupted;
set
{
m_Corrupted = value;
Update();
}
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Faction Corrupting
{
get => m_Corrupting;
set
{
m_Corrupting = value;
Update();
}
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public BaseMonolith LastMonolith { get; set; }
[CommandProperty(AccessLevel.Counselor)]
public bool IsBeingCorrupted => LastMonolith is StrongholdMonolith && LastMonolith.Faction == m_Corrupting &&
m_Corrupting != null;
[CommandProperty(AccessLevel.Counselor)]
public bool IsCorrupted => m_Corrupted != null;
[CommandProperty(AccessLevel.Counselor)]
public bool IsPurifying => PurificationStart != DateTime.MinValue;
[CommandProperty(AccessLevel.Counselor)]
public bool IsCorrupting => m_Corrupting != null && m_Corrupting != m_Corrupted;
[CommandProperty(AccessLevel.GameMaster)]
public TimeSpan TimeUntilCorruption =>
!IsBeingCorrupted ?
TimeSpan.Zero :
Utility.Max(CorruptionStart + CorruptionPeriod - Core.Now, TimeSpan.Zero);
public static List<Sigil> Sigils { get; } = new();
public void Update()
{
ItemID = m_Town?.Definition.SigilID ?? 0x1869;
if (m_Town == null)
{
AssignName(null);
}
else if (IsCorrupted || IsPurifying)
{
AssignName(m_Town.Definition.CorruptedSigilName);
}
else
{
AssignName(m_Town.Definition.SigilName);
}
public Sigil(Serial serial) : base(serial)
InvalidateProperties();
}
public override void GetProperties(IPropertyList list)
{
base.GetProperties(list);
if (IsCorrupted)
{
Sigils.Add(this);
m_Corrupted.Definition.SigilControl.AddTo(list);
}
else
{
list.Add(1042256); // This sigil is not corrupted.
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public DateTime LastStolen { get; set; }
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public DateTime GraceStart { get; set; }
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public DateTime CorruptionStart { get; set; }
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public DateTime PurificationStart { get; set; }
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Town Town
if (IsCorrupting)
{
get => m_Town;
set
list.Add(1042257); // This sigil is in the process of being corrupted.
}
else if (IsPurifying)
{
list.Add(1042258); // This sigil has recently been corrupted, and is undergoing purification.
}
else
{
list.Add(1042259); // This sigil is not in the process of being corrupted.
}
}
public override void OnSingleClick(Mobile from)
{
base.OnSingleClick(from);
if (IsCorrupted)
{
if (m_Corrupted.Definition.SigilControl.Number > 0)
{
m_Town = value;
Update();
LabelTo(from, m_Corrupted.Definition.SigilControl.Number);
}
else if (m_Corrupted.Definition.SigilControl.String != null)
{
LabelTo(from, m_Corrupted.Definition.SigilControl.String);
}
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Faction Corrupted
else
{
get => m_Corrupted;
set
{
m_Corrupted = value;
Update();
}
LabelTo(from, 1042256); // This sigil is not corrupted.
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Faction Corrupting
if (IsCorrupting)
{
get => m_Corrupting;
set
{
m_Corrupting = value;
Update();
}
LabelTo(from, 1042257); // This sigil is in the process of being corrupted.
}
else if (IsPurifying)
{
LabelTo(from, 1042258); // This sigil has been recently corrupted, and is undergoing purification.
}
else
{
LabelTo(from, 1042259); // This sigil is not in the process of being corrupted.
}
}
public override bool CheckLift(Mobile from, Item item, ref LRReason reject)
{
from.SendLocalizedMessage(1005225); // You must use the stealing skill to pick up the sigil
return false;
}
private Mobile FindOwner(IEntity parent)
{
if (parent is Item item)
{
return item.RootParent as Mobile;
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public BaseMonolith LastMonolith { get; set; }
[CommandProperty(AccessLevel.Counselor)]
public bool IsBeingCorrupted => LastMonolith is StrongholdMonolith && LastMonolith.Faction == m_Corrupting &&
m_Corrupting != null;
[CommandProperty(AccessLevel.Counselor)]
public bool IsCorrupted => m_Corrupted != null;
[CommandProperty(AccessLevel.Counselor)]
public bool IsPurifying => PurificationStart != DateTime.MinValue;
[CommandProperty(AccessLevel.Counselor)]
public bool IsCorrupting => m_Corrupting != null && m_Corrupting != m_Corrupted;
[CommandProperty(AccessLevel.GameMaster)]
public TimeSpan TimeUntilCorruption =>
!IsBeingCorrupted ?
TimeSpan.Zero :
Utility.Max(CorruptionStart + CorruptionPeriod - Core.Now, TimeSpan.Zero);
public static List<Sigil> Sigils { get; } = new();
public void Update()
if (parent is Mobile mobile)
{
ItemID = m_Town?.Definition.SigilID ?? 0x1869;
if (m_Town == null)
{
AssignName(null);
}
else if (IsCorrupted || IsPurifying)
{
AssignName(m_Town.Definition.CorruptedSigilName);
}
else
{
AssignName(m_Town.Definition.SigilName);
}
InvalidateProperties();
return mobile;
}
public override void GetProperties(IPropertyList list)
return null;
}
public override void OnAdded(IEntity parent)
{
base.OnAdded(parent);
var mob = FindOwner(parent);
if (mob != null)
{
base.GetProperties(list);
mob.SolidHueOverride = OwnershipHue;
}
}
if (IsCorrupted)
{
m_Corrupted.Definition.SigilControl.AddTo(list);
}
else
{
list.Add(1042256); // This sigil is not corrupted.
}
public override void OnRemoved(IEntity parent)
{
base.OnRemoved(parent);
if (IsCorrupting)
{
list.Add(1042257); // This sigil is in the process of being corrupted.
}
else if (IsPurifying)
{
list.Add(1042258); // This sigil has recently been corrupted, and is undergoing purification.
}
else
{
list.Add(1042259); // This sigil is not in the process of being corrupted.
}
var mob = FindOwner(parent);
if (mob != null)
{
mob.SolidHueOverride = -1;
}
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack))
{
from.BeginTarget(1, false, TargetFlags.None, Sigil_OnTarget);
from.SendLocalizedMessage(1042251); // Click on a sigil monolith or player
}
}
public static bool ExistsOn(Mobile mob) => mob.Backpack?.FindItemByType<Sigil>() != null;
private void BeginCorrupting(Faction faction)
{
m_Corrupting = faction;
CorruptionStart = Core.Now;
}
private void ClearCorrupting()
{
m_Corrupting = null;
CorruptionStart = DateTime.MinValue;
}
private void Sigil_OnTarget(Mobile from, object obj)
{
if (Deleted || !IsChildOf(from.Backpack))
{
return;
}
public override void OnSingleClick(Mobile from)
if (obj is Mobile)
{
base.OnSingleClick(from);
if (IsCorrupted)
if (obj is PlayerMobile targ)
{
if (m_Corrupted.Definition.SigilControl.Number > 0)
var toFaction = Faction.Find(targ);
var fromFaction = Faction.Find(from);
if (toFaction == null)
{
LabelTo(from, m_Corrupted.Definition.SigilControl.Number);
from.SendLocalizedMessage(1005223); // You cannot give the sigil to someone not in a faction
}
else if (m_Corrupted.Definition.SigilControl.String != null)
else if (fromFaction != toFaction)
{
LabelTo(from, m_Corrupted.Definition.SigilControl.String);
from.SendLocalizedMessage(1005222); // You cannot give the sigil to someone not in your faction
}
else if (ExistsOn(targ))
{
from.SendLocalizedMessage(1005220); // You cannot give this sigil to someone who already has a sigil
}
else if (!targ.Alive)
{
from.SendLocalizedMessage(1042248); // You cannot give a sigil to a dead person.
}
else if (from.NetState != null && targ.NetState != null)
{
var pack = targ.Backpack;
pack?.DropItem(this);
}
}
else
{
LabelTo(from, 1042256); // This sigil is not corrupted.
}
if (IsCorrupting)
{
LabelTo(from, 1042257); // This sigil is in the process of being corrupted.
}
else if (IsPurifying)
{
LabelTo(from, 1042258); // This sigil has been recently corrupted, and is undergoing purification.
}
else
{
LabelTo(from, 1042259); // This sigil is not in the process of being corrupted.
from.SendLocalizedMessage(1005221); // You cannot give the sigil to them
}
}
public override bool CheckLift(Mobile from, Item item, ref LRReason reject)
else if (obj is BaseMonolith)
{
from.SendLocalizedMessage(1005225); // You must use the stealing skill to pick up the sigil
return false;
}
private Mobile FindOwner(IEntity parent)
{
if (parent is Item item)
if (obj is StrongholdMonolith sm)
{
return item.RootParent as Mobile;
}
if (parent is Mobile mobile)
{
return mobile;
}
return null;
}
public override void OnAdded(IEntity parent)
{
base.OnAdded(parent);
var mob = FindOwner(parent);
if (mob != null)
{
mob.SolidHueOverride = OwnershipHue;
}
}
public override void OnRemoved(IEntity parent)
{
base.OnRemoved(parent);
var mob = FindOwner(parent);
if (mob != null)
{
mob.SolidHueOverride = -1;
}
}
public override void OnDoubleClick(Mobile from)
{
if (IsChildOf(from.Backpack))
{
from.BeginTarget(1, false, TargetFlags.None, Sigil_OnTarget);
from.SendLocalizedMessage(1042251); // Click on a sigil monolith or player
}
}
public static bool ExistsOn(Mobile mob) => mob.Backpack?.FindItemByType<Sigil>() != null;
private void BeginCorrupting(Faction faction)
{
m_Corrupting = faction;
CorruptionStart = Core.Now;
}
private void ClearCorrupting()
{
m_Corrupting = null;
CorruptionStart = DateTime.MinValue;
}
private void Sigil_OnTarget(Mobile from, object obj)
{
if (Deleted || !IsChildOf(from.Backpack))
{
return;
}
if (obj is Mobile)
{
if (obj is PlayerMobile targ)
if (sm.Faction == null || sm.Faction != Faction.Find(from))
{
var toFaction = Faction.Find(targ);
var fromFaction = Faction.Find(from);
if (toFaction == null)
{
from.SendLocalizedMessage(1005223); // You cannot give the sigil to someone not in a faction
}
else if (fromFaction != toFaction)
{
from.SendLocalizedMessage(1005222); // You cannot give the sigil to someone not in your faction
}
else if (ExistsOn(targ))
{
from.SendLocalizedMessage(1005220); // You cannot give this sigil to someone who already has a sigil
}
else if (!targ.Alive)
{
from.SendLocalizedMessage(1042248); // You cannot give a sigil to a dead person.
}
else if (from.NetState != null && targ.NetState != null)
{
var pack = targ.Backpack;
pack?.DropItem(this);
}
from.SendLocalizedMessage(1042246); // You can't place that on an enemy monolith
}
else if (sm.Town == null || sm.Town != m_Town)
{
from.SendLocalizedMessage(1042247); // That is not the correct faction monolith
}
else
{
from.SendLocalizedMessage(1005221); // You cannot give the sigil to them
sm.Sigil = this;
var newController = sm.Faction;
var oldController = m_Corrupting;
if (oldController == null)
{
if (m_Corrupted != newController)
{
BeginCorrupting(newController);
}
}
else if (GraceStart > DateTime.MinValue && GraceStart + CorruptionGrace < Core.Now)
{
if (m_Corrupted != newController)
{
BeginCorrupting(newController); // grace time over, reset period
}
else
{
ClearCorrupting();
}
GraceStart = DateTime.MinValue;
}
else if (newController == oldController)
{
GraceStart = DateTime.MinValue; // returned within grace period
}
else if (GraceStart == DateTime.MinValue)
{
GraceStart = Core.Now;
}
PurificationStart = DateTime.MinValue;
}
}
else if (obj is BaseMonolith)
else if (obj is TownMonolith tm)
{
if (obj is StrongholdMonolith sm)
if (tm.Town == null || tm.Town != m_Town)
{
if (sm.Faction == null || sm.Faction != Faction.Find(from))
{
from.SendLocalizedMessage(1042246); // You can't place that on an enemy monolith
}
else if (sm.Town == null || sm.Town != m_Town)
{
from.SendLocalizedMessage(1042247); // That is not the correct faction monolith
}
else
{
sm.Sigil = this;
var newController = sm.Faction;
var oldController = m_Corrupting;
if (oldController == null)
{
if (m_Corrupted != newController)
{
BeginCorrupting(newController);
}
}
else if (GraceStart > DateTime.MinValue && GraceStart + CorruptionGrace < Core.Now)
{
if (m_Corrupted != newController)
{
BeginCorrupting(newController); // grace time over, reset period
}
else
{
ClearCorrupting();
}
GraceStart = DateTime.MinValue;
}
else if (newController == oldController)
{
GraceStart = DateTime.MinValue; // returned within grace period
}
else if (GraceStart == DateTime.MinValue)
{
GraceStart = Core.Now;
}
PurificationStart = DateTime.MinValue;
}
from.SendLocalizedMessage(1042245); // This is not the correct town sigil monolith
}
else if (obj is TownMonolith tm)
else if (m_Corrupted == null || m_Corrupted != Faction.Find(from))
{
if (tm.Town == null || tm.Town != m_Town)
{
from.SendLocalizedMessage(1042245); // This is not the correct town sigil monolith
}
else if (m_Corrupted == null || m_Corrupted != Faction.Find(from))
{
// Your faction did not corrupt this sigil. Take it to your stronghold.
from.SendLocalizedMessage(1042244);
}
else
{
tm.Sigil = this;
// Your faction did not corrupt this sigil. Take it to your stronghold.
from.SendLocalizedMessage(1042244);
}
else
{
tm.Sigil = this;
m_Corrupting = null;
PurificationStart = Core.Now;
CorruptionStart = DateTime.MinValue;
m_Corrupting = null;
PurificationStart = Core.Now;
CorruptionStart = DateTime.MinValue;
m_Town.Capture(m_Corrupted);
m_Corrupted = null;
}
m_Town.Capture(m_Corrupted);
m_Corrupted = null;
}
}
else
{
from.SendLocalizedMessage(1005224); // You can't use the sigil on that
}
Update();
}
else
{
from.SendLocalizedMessage(1005224); // You can't use the sigil on that
}
public override void Serialize(IGenericWriter writer)
Update();
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Town.WriteReference(writer, m_Town);
Faction.WriteReference(writer, m_Corrupted);
Faction.WriteReference(writer, m_Corrupting);
writer.Write(LastMonolith);
writer.Write(LastStolen);
writer.Write(GraceStart);
writer.Write(CorruptionStart);
writer.Write(PurificationStart);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
base.Serialize(writer);
case 0:
{
m_Town = Town.ReadReference(reader);
m_Corrupted = Faction.ReadReference(reader);
m_Corrupting = Faction.ReadReference(reader);
writer.Write(0); // version
LastMonolith = reader.ReadEntity<BaseMonolith>();
Town.WriteReference(writer, m_Town);
Faction.WriteReference(writer, m_Corrupted);
Faction.WriteReference(writer, m_Corrupting);
LastStolen = reader.ReadDateTime();
GraceStart = reader.ReadDateTime();
CorruptionStart = reader.ReadDateTime();
PurificationStart = reader.ReadDateTime();
writer.Write(LastMonolith);
Update();
writer.Write(LastStolen);
writer.Write(GraceStart);
writer.Write(CorruptionStart);
writer.Write(PurificationStart);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 0:
if (RootParent is Mobile mob)
{
m_Town = Town.ReadReference(reader);
m_Corrupted = Faction.ReadReference(reader);
m_Corrupting = Faction.ReadReference(reader);
LastMonolith = reader.ReadEntity<BaseMonolith>();
LastStolen = reader.ReadDateTime();
GraceStart = reader.ReadDateTime();
CorruptionStart = reader.ReadDateTime();
PurificationStart = reader.ReadDateTime();
Update();
if (RootParent is Mobile mob)
{
mob.SolidHueOverride = OwnershipHue;
}
break;
mob.SolidHueOverride = OwnershipHue;
}
}
}
public bool ReturnHome()
{
var monolith = LastMonolith;
if (monolith == null && m_Town != null)
{
monolith = m_Town.Monolith;
}
if (monolith?.Deleted == false)
{
monolith.Sigil = this;
}
return monolith?.Deleted == false;
}
public override void OnParentDeleted(IEntity parent)
{
base.OnParentDeleted(parent);
ReturnHome();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
Sigils.Remove(this);
}
public override void Delete()
{
if (ReturnHome())
{
return;
}
base.Delete();
break;
}
}
}
}
public bool ReturnHome()
{
var monolith = LastMonolith;
if (monolith == null && m_Town != null)
{
monolith = m_Town.Monolith;
}
if (monolith?.Deleted == false)
{
monolith.Sigil = this;
}
return monolith?.Deleted == false;
}
public override void OnParentDeleted(IEntity parent)
{
base.OnParentDeleted(parent);
ReturnHome();
}
public override void OnAfterDelete()
{
base.OnAfterDelete();
Sigils.Remove(this);
}
public override void Delete()
{
if (ReturnHome())
{
return;
}
base.Delete();
}
}

View file

@ -1,34 +1,33 @@
namespace Server.Factions
namespace Server.Factions;
public class StrongholdMonolith : BaseMonolith
{
public class StrongholdMonolith : BaseMonolith
public StrongholdMonolith(Town town = null, Faction faction = null) : base(town, faction)
{
public StrongholdMonolith(Town town = null, Faction faction = null) : base(town, faction)
{
}
public StrongholdMonolith(Serial serial) : base(serial)
{
}
public override int DefaultLabelNumber => 1041042; // A Faction Sigil Monolith
public override void OnTownChanged()
{
AssignName(Town?.Definition.StrongholdMonolithName);
}
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 StrongholdMonolith(Serial serial) : base(serial)
{
}
public override int DefaultLabelNumber => 1041042; // A Faction Sigil Monolith
public override void OnTownChanged()
{
AssignName(Town?.Definition.StrongholdMonolithName);
}
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();
}
}

View file

@ -1,34 +1,33 @@
namespace Server.Factions
namespace Server.Factions;
public class TownMonolith : BaseMonolith
{
public class TownMonolith : BaseMonolith
public TownMonolith(Town town = null) : base(town)
{
public TownMonolith(Town town = null) : base(town)
{
}
public TownMonolith(Serial serial) : base(serial)
{
}
public override int DefaultLabelNumber => 1041403; // A Faction Town Sigil Monolith
public override void OnTownChanged()
{
AssignName(Town?.Definition.TownMonolithName);
}
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 TownMonolith(Serial serial) : base(serial)
{
}
public override int DefaultLabelNumber => 1041403; // A Faction Town Sigil Monolith
public override void OnTownChanged()
{
AssignName(Town?.Definition.TownMonolithName);
}
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();
}
}

View file

@ -1,91 +1,90 @@
using Server.Mobiles;
namespace Server.Factions
namespace Server.Factions;
public class TownStone : BaseSystemController
{
public class TownStone : BaseSystemController
private Town m_Town;
[Constructible]
public TownStone(Town town = null) : base(0xEDE)
{
private Town m_Town;
Movable = false;
Town = town;
}
[Constructible]
public TownStone(Town town = null) : base(0xEDE)
public TownStone(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Town Town
{
get => m_Town;
set
{
Movable = false;
Town = town;
}
m_Town = value;
public TownStone(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.Counselor, AccessLevel.Administrator)]
public Town Town
{
get => m_Town;
set
{
m_Town = value;
AssignName(m_Town?.Definition.TownStoneName);
}
}
public override string DefaultName => "faction town stone";
public override void OnDoubleClick(Mobile from)
{
if (m_Town == null)
{
return;
}
var faction = Faction.Find(from);
if (faction == null && from.AccessLevel < AccessLevel.GameMaster)
{
return; // TODO: Message?
}
if (m_Town.Owner == null || from.AccessLevel < AccessLevel.GameMaster && faction != m_Town.Owner)
{
from.SendLocalizedMessage(1010332); // Your faction does not control this town
}
else if (!m_Town.Owner.IsCommander(from))
{
from.SendLocalizedMessage(1005242); // Only faction Leaders can use townstones
}
else if (FactionGump.Exists(from))
{
from.SendLocalizedMessage(1042160); // You already have a faction menu open.
}
else if (from is PlayerMobile mobile)
{
mobile.SendGump(new TownStoneGump(mobile, m_Town.Owner, m_Town));
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Town.WriteReference(writer, m_Town);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 0:
{
Town = Town.ReadReference(reader);
break;
}
}
AssignName(m_Town?.Definition.TownStoneName);
}
}
}
public override string DefaultName => "faction town stone";
public override void OnDoubleClick(Mobile from)
{
if (m_Town == null)
{
return;
}
var faction = Faction.Find(from);
if (faction == null && from.AccessLevel < AccessLevel.GameMaster)
{
return; // TODO: Message?
}
if (m_Town.Owner == null || from.AccessLevel < AccessLevel.GameMaster && faction != m_Town.Owner)
{
from.SendLocalizedMessage(1010332); // Your faction does not control this town
}
else if (!m_Town.Owner.IsCommander(from))
{
from.SendLocalizedMessage(1005242); // Only faction Leaders can use townstones
}
else if (FactionGump.Exists(from))
{
from.SendLocalizedMessage(1042160); // You already have a faction menu open.
}
else if (from is PlayerMobile mobile)
{
mobile.SendGump(new TownStoneGump(mobile, m_Town.Owner, m_Town));
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Town.WriteReference(writer, m_Town);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
switch (version)
{
case 0:
{
Town = Town.ReadReference(reader);
break;
}
}
}
}

View file

@ -2,289 +2,288 @@ using System;
using Server.Items;
using Server.Network;
namespace Server.Factions
{
public enum AllowedPlacing
{
Everywhere,
namespace Server.Factions;
AnyFactionTown,
ControlledFactionTown,
FactionStronghold
public enum AllowedPlacing
{
Everywhere,
AnyFactionTown,
ControlledFactionTown,
FactionStronghold
}
public abstract class BaseFactionTrap : BaseTrap
{
private TimerExecutionToken _concealingTimerToken;
public BaseFactionTrap(Faction f, Mobile m, int itemID) : base(itemID)
{
Visible = false;
Faction = f;
TimeOfPlacement = Core.Now;
Placer = m;
}
public abstract class BaseFactionTrap : BaseTrap
public BaseFactionTrap(Serial serial) : base(serial)
{
private TimerExecutionToken _concealingTimerToken;
}
public BaseFactionTrap(Faction f, Mobile m, int itemID) : base(itemID)
[CommandProperty(AccessLevel.GameMaster)]
public Faction Faction { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Placer { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public DateTime TimeOfPlacement { get; set; }
public virtual int EffectSound => 0;
public virtual int SilverFromDisarm => 100;
public virtual int MessageHue => 0;
public virtual int AttackMessage => 0;
public virtual int DisarmMessage => 0;
public virtual AllowedPlacing AllowedPlacing => AllowedPlacing.Everywhere;
public virtual TimeSpan ConcealPeriod => TimeSpan.FromMinutes(1.0);
public virtual TimeSpan DecayPeriod => Core.AOS ? TimeSpan.FromDays(1.0) : TimeSpan.MaxValue;
public override void OnTrigger(Mobile from)
{
if (!IsEnemy(from))
{
Visible = false;
Faction = f;
TimeOfPlacement = Core.Now;
Placer = m;
return;
}
public BaseFactionTrap(Serial serial) : base(serial)
Conceal();
DoVisibleEffect();
Effects.PlaySound(Location, Map, EffectSound);
DoAttackEffect(from);
var silverToAward = from.Alive ? 20 : 40;
if (Placer != null && Faction != null)
{
}
var victimState = PlayerState.Find(from);
[CommandProperty(AccessLevel.GameMaster)]
public Faction Faction { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Placer { get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public DateTime TimeOfPlacement { get; set; }
public virtual int EffectSound => 0;
public virtual int SilverFromDisarm => 100;
public virtual int MessageHue => 0;
public virtual int AttackMessage => 0;
public virtual int DisarmMessage => 0;
public virtual AllowedPlacing AllowedPlacing => AllowedPlacing.Everywhere;
public virtual TimeSpan ConcealPeriod => TimeSpan.FromMinutes(1.0);
public virtual TimeSpan DecayPeriod => Core.AOS ? TimeSpan.FromDays(1.0) : TimeSpan.MaxValue;
public override void OnTrigger(Mobile from)
{
if (!IsEnemy(from))
if (victimState?.CanGiveSilverTo(Placer) == true && victimState.KillPoints > 0)
{
return;
}
var silverGiven = Faction.AwardSilver(Placer, silverToAward);
Conceal();
DoVisibleEffect();
Effects.PlaySound(Location, Map, EffectSound);
DoAttackEffect(from);
var silverToAward = from.Alive ? 20 : 40;
if (Placer != null && Faction != null)
{
var victimState = PlayerState.Find(from);
if (victimState?.CanGiveSilverTo(Placer) == true && victimState.KillPoints > 0)
if (silverGiven > 0)
{
var silverGiven = Faction.AwardSilver(Placer, silverToAward);
if (silverGiven > 0)
// TODO: Get real message
if (from.Alive)
{
// TODO: Get real message
if (from.Alive)
{
Placer.SendMessage(
$"You have earned {silverGiven} silver pieces because {from.Name} fell for your trap."
);
}
else
{
// You have earned ~1_SILVER_AMOUNT~ pieces for vanquishing ~2_PLAYER_NAME~!
Placer.SendLocalizedMessage(1042736, $"{silverGiven} silver\t{from.Name}");
}
Placer.SendMessage(
$"You have earned {silverGiven} silver pieces because {from.Name} fell for your trap."
);
}
victimState.OnGivenSilverTo(Placer);
}
}
from.LocalOverheadMessage(MessageType.Regular, MessageHue, AttackMessage);
}
public abstract void DoVisibleEffect();
public abstract void DoAttackEffect(Mobile m);
public virtual int IsValidLocation() => IsValidLocation(GetWorldLocation(), Map);
public virtual int IsValidLocation(Point3D p, Map m)
{
if (m == null)
{
return 502956; // You cannot place a trap on that.
}
if (Core.ML)
{
foreach (var item in m.GetItemsAt(p))
{
if (item is BaseFactionTrap trap && trap.Faction == Faction)
else
{
return 1075263; // There is already a trap belonging to your faction at this location.;
// You have earned ~1_SILVER_AMOUNT~ pieces for vanquishing ~2_PLAYER_NAME~!
Placer.SendLocalizedMessage(1042736, $"{silverGiven} silver\t{from.Name}");
}
}
victimState.OnGivenSilverTo(Placer);
}
switch (AllowedPlacing)
{
case AllowedPlacing.FactionStronghold:
{
var region = Region.Find(p, m).GetRegion<StrongholdRegion>();
if (region != null && region.Faction == Faction)
{
return 0;
}
return 1010355; // This trap can only be placed in your stronghold
}
case AllowedPlacing.AnyFactionTown:
{
var town = Town.FromRegion(Region.Find(p, m));
if (town != null)
{
return 0;
}
return 1010356; // This trap can only be placed in a faction town
}
case AllowedPlacing.ControlledFactionTown:
{
var town = Town.FromRegion(Region.Find(p, m));
if (town != null && town.Owner == Faction)
{
return 0;
}
return 1010357; // This trap can only be placed in a town your faction controls
}
}
return 0;
}
public override void OnMovement(Mobile m, Point3D oldLocation)
{
base.OnMovement(m, oldLocation);
from.LocalOverheadMessage(MessageType.Regular, MessageHue, AttackMessage);
}
if (!CheckDecay() && CheckRange(m.Location, oldLocation, 6))
public abstract void DoVisibleEffect();
public abstract void DoAttackEffect(Mobile m);
public virtual int IsValidLocation() => IsValidLocation(GetWorldLocation(), Map);
public virtual int IsValidLocation(Point3D p, Map m)
{
if (m == null)
{
return 502956; // You cannot place a trap on that.
}
if (Core.ML)
{
foreach (var item in m.GetItemsAt(p))
{
if (Faction.Find(m) != null &&
(m.Skills.DetectHidden.Value - 80.0) / 20.0 > Utility.RandomDouble())
if (item is BaseFactionTrap trap && trap.Faction == Faction)
{
PrivateOverheadLocalizedMessage(m, 1010154, MessageHue, "", ""); // [Faction Trap]
return 1075263; // There is already a trap belonging to your faction at this location.;
}
}
}
public void PrivateOverheadLocalizedMessage(Mobile to, int number, int hue, string name, string args)
switch (AllowedPlacing)
{
to?.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number, name, args);
case AllowedPlacing.FactionStronghold:
{
var region = Region.Find(p, m).GetRegion<StrongholdRegion>();
if (region != null && region.Faction == Faction)
{
return 0;
}
return 1010355; // This trap can only be placed in your stronghold
}
case AllowedPlacing.AnyFactionTown:
{
var town = Town.FromRegion(Region.Find(p, m));
if (town != null)
{
return 0;
}
return 1010356; // This trap can only be placed in a faction town
}
case AllowedPlacing.ControlledFactionTown:
{
var town = Town.FromRegion(Region.Find(p, m));
if (town != null && town.Owner == Faction)
{
return 0;
}
return 1010357; // This trap can only be placed in a town your faction controls
}
}
public virtual bool CheckDecay()
return 0;
}
public override void OnMovement(Mobile m, Point3D oldLocation)
{
base.OnMovement(m, oldLocation);
if (!CheckDecay() && CheckRange(m.Location, oldLocation, 6))
{
var decayPeriod = DecayPeriod;
if (decayPeriod == TimeSpan.MaxValue)
if (Faction.Find(m) != null &&
(m.Skills.DetectHidden.Value - 80.0) / 20.0 > Utility.RandomDouble())
{
return false;
PrivateOverheadLocalizedMessage(m, 1010154, MessageHue, "", ""); // [Faction Trap]
}
}
}
if (TimeOfPlacement + decayPeriod < Core.Now)
{
Timer.StartTimer(Delete);
return true;
}
public void PrivateOverheadLocalizedMessage(Mobile to, int number, int hue, string name, string args)
{
to?.NetState.SendMessageLocalized(Serial, ItemID, MessageType.Regular, hue, 3, number, name, args);
}
public virtual bool CheckDecay()
{
var decayPeriod = DecayPeriod;
if (decayPeriod == TimeSpan.MaxValue)
{
return false;
}
public virtual void BeginConceal()
if (TimeOfPlacement + decayPeriod < Core.Now)
{
_concealingTimerToken.Cancel();
Timer.StartTimer(ConcealPeriod, Conceal, out _concealingTimerToken);
Timer.StartTimer(Delete);
return true;
}
public virtual void Conceal()
return false;
}
public virtual void BeginConceal()
{
_concealingTimerToken.Cancel();
Timer.StartTimer(ConcealPeriod, Conceal, out _concealingTimerToken);
}
public virtual void Conceal()
{
_concealingTimerToken.Cancel();
if (!Deleted)
{
_concealingTimerToken.Cancel();
if (!Deleted)
{
Visible = false;
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Faction.WriteReference(writer, Faction);
writer.Write(Placer);
writer.Write(TimeOfPlacement);
if (Visible)
{
BeginConceal();
}
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
Faction = Faction.ReadReference(reader);
Placer = reader.ReadEntity<Mobile>();
TimeOfPlacement = reader.ReadDateTime();
if (Visible)
{
BeginConceal();
}
CheckDecay();
}
public override void OnDelete()
{
if (Faction?.Traps.Contains(this) == true)
{
Faction.Traps.Remove(this);
}
base.OnDelete();
}
public virtual bool IsEnemy(Mobile mob)
{
if (mob.Hidden && mob.AccessLevel > AccessLevel.Player)
{
return false;
}
if (!mob.Alive || mob.IsDeadBondedPet)
{
return false;
}
var faction = Faction.Find(mob, true);
if (faction == null && mob is BaseFactionGuard guard)
{
faction = guard.Faction;
}
if (faction == null)
{
return false;
}
return faction != Faction;
Visible = false;
}
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Faction.WriteReference(writer, Faction);
writer.Write(Placer);
writer.Write(TimeOfPlacement);
if (Visible)
{
BeginConceal();
}
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
Faction = Faction.ReadReference(reader);
Placer = reader.ReadEntity<Mobile>();
TimeOfPlacement = reader.ReadDateTime();
if (Visible)
{
BeginConceal();
}
CheckDecay();
}
public override void OnDelete()
{
if (Faction?.Traps.Contains(this) == true)
{
Faction.Traps.Remove(this);
}
base.OnDelete();
}
public virtual bool IsEnemy(Mobile mob)
{
if (mob.Hidden && mob.AccessLevel > AccessLevel.Player)
{
return false;
}
if (!mob.Alive || mob.IsDeadBondedPet)
{
return false;
}
var faction = Faction.Find(mob, true);
if (faction == null && mob is BaseFactionGuard guard)
{
faction = guard.Faction;
}
if (faction == null)
{
return false;
}
return faction != Faction;
}
}

View file

@ -2,120 +2,119 @@ using System;
using Server.Engines.Craft;
using Server.Items;
namespace Server.Factions
namespace Server.Factions;
public abstract class BaseFactionTrapDeed : Item, ICraftable
{
public abstract class BaseFactionTrapDeed : Item, ICraftable
private Faction m_Faction;
public BaseFactionTrapDeed(int itemID = 0x14F0) : base(itemID)
{
private Faction m_Faction;
Weight = 1.0;
LootType = LootType.Blessed;
}
public BaseFactionTrapDeed(int itemID = 0x14F0) : base(itemID)
public BaseFactionTrapDeed(Serial serial) : base(serial)
{
}
public abstract Type TrapType { get; }
[CommandProperty(AccessLevel.GameMaster)]
public Faction Faction
{
get => m_Faction;
set
{
Weight = 1.0;
LootType = LootType.Blessed;
}
m_Faction = value;
public BaseFactionTrapDeed(Serial serial) : base(serial)
{
}
public abstract Type TrapType { get; }
[CommandProperty(AccessLevel.GameMaster)]
public Faction Faction
{
get => m_Faction;
set
if (m_Faction != null)
{
m_Faction = value;
if (m_Faction != null)
{
Hue = m_Faction.Definition.HuePrimary;
}
Hue = m_Faction.Definition.HuePrimary;
}
}
}
public int OnCraft(
int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool,
CraftItem craftItem, int resHue
)
public int OnCraft(
int quality, bool makersMark, Mobile from, CraftSystem craftSystem, Type typeRes, BaseTool tool,
CraftItem craftItem, int resHue
)
{
ItemID = 0x14F0;
Faction = Faction.Find(from);
return 1;
}
public virtual BaseFactionTrap Construct(Mobile from)
{
try
{
ItemID = 0x14F0;
Faction = Faction.Find(from);
return 1;
return TrapType.CreateInstance<BaseFactionTrap>(m_Faction, from);
}
public virtual BaseFactionTrap Construct(Mobile from)
catch
{
try
{
return TrapType.CreateInstance<BaseFactionTrap>(m_Faction, from);
}
catch
{
return null;
}
return null;
}
}
public override void OnDoubleClick(Mobile from)
public override void OnDoubleClick(Mobile from)
{
var faction = Faction.Find(from);
if (faction == null)
{
var faction = Faction.Find(from);
from.SendLocalizedMessage(1010353, "", 0x23); // Only faction members may place faction traps
}
else if (faction != m_Faction)
{
from.SendLocalizedMessage(1010354, "", 0x23); // You may only place faction traps created by your faction
}
else if (faction.Traps.Count >= faction.MaximumTraps)
{
from.SendLocalizedMessage(1010358, "", 0x23); // Your faction already has the maximum number of traps placed
}
else
{
var trap = Construct(from);
if (faction == null)
if (trap == null)
{
from.SendLocalizedMessage(1010353, "", 0x23); // Only faction members may place faction traps
return;
}
else if (faction != m_Faction)
var message = trap.IsValidLocation(from.Location, from.Map);
if (message > 0)
{
from.SendLocalizedMessage(1010354, "", 0x23); // You may only place faction traps created by your faction
}
else if (faction.Traps.Count >= faction.MaximumTraps)
{
from.SendLocalizedMessage(1010358, "", 0x23); // Your faction already has the maximum number of traps placed
from.SendLocalizedMessage(message, "", 0x23);
trap.Delete();
}
else
{
var trap = Construct(from);
if (trap == null)
{
return;
}
var message = trap.IsValidLocation(from.Location, from.Map);
if (message > 0)
{
from.SendLocalizedMessage(message, "", 0x23);
trap.Delete();
}
else
{
from.SendLocalizedMessage(1010360); // You arm the trap and carefully hide it from view
trap.MoveToWorld(from.Location, from.Map);
faction.Traps.Add(trap);
Delete();
}
from.SendLocalizedMessage(1010360); // You arm the trap and carefully hide it from view
trap.MoveToWorld(from.Location, from.Map);
faction.Traps.Add(trap);
Delete();
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Faction.WriteReference(writer, m_Faction);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m_Faction = Faction.ReadReference(reader);
}
}
}
public override void Serialize(IGenericWriter writer)
{
base.Serialize(writer);
writer.Write(0); // version
Faction.WriteReference(writer, m_Faction);
}
public override void Deserialize(IGenericReader reader)
{
base.Deserialize(reader);
var version = reader.ReadInt();
m_Faction = Faction.ReadReference(reader);
}
}

View file

@ -0,0 +1,14 @@
{
"version": 1,
"type": "Server.Factions.BaseSystemController",
"properties": [
{
"name": "LabelNumber",
"type": "int",
"rule": "PrimitiveTypeMigrationRule",
"ruleArguments": [
""
]
}
]
}