fix: Stages faction code for serialization conversion (#1835)
This commit is contained in:
parent
20596e52fa
commit
221312be4c
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
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue