Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -0,0 +1,626 @@
using System;
using System.Collections.Generic;
using System.Net;
using Server.Mobiles;
namespace Server.Factions
{
public enum ElectionState
{
Pending,
Campaign,
Election
}
public class Election
{
public static readonly TimeSpan PendingPeriod = TimeSpan.FromDays(5.0);
public static readonly TimeSpan CampaignPeriod = TimeSpan.FromDays(1.0);
public static readonly TimeSpan VotingPeriod = TimeSpan.FromDays(3.0);
public const int MaxCandidates = 10;
public const int CandidateRank = 5;
private Faction m_Faction;
private readonly List<Candidate> m_Candidates;
private ElectionState m_State;
private DateTime m_LastStateTime;
private Timer m_Timer;
public Election(Faction faction)
{
m_Faction = faction;
m_Candidates = new List<Candidate>();
StartTimer();
}
public Election(GenericReader reader)
{
int version = reader.ReadEncodedInt();
switch ( version )
{
case 0:
{
m_Faction = Faction.ReadReference(reader);
m_LastStateTime = reader.ReadDateTime();
m_State = (ElectionState)reader.ReadEncodedInt();
m_Candidates = new List<Candidate>();
int count = reader.ReadEncodedInt();
for (int i = 0; i < count; ++i)
{
Candidate cd = new Candidate(reader);
if (cd.Mobile != null)
m_Candidates.Add(cd);
}
break;
}
}
StartTimer();
}
public Faction Faction
{
get
{
return m_Faction;
}
set
{
m_Faction = value;
}
}
public List<Candidate> Candidates
{
get
{
return m_Candidates;
}
}
public ElectionState State
{
get
{
return m_State;
}
set
{
m_State = value;
m_LastStateTime = DateTime.UtcNow;
}
}
public DateTime LastStateTime
{
get
{
return m_LastStateTime;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public ElectionState CurrentState
{
get
{
return m_State;
}
}
[CommandProperty(AccessLevel.GameMaster, AccessLevel.Administrator)]
public TimeSpan NextStateTime
{
get
{
TimeSpan period;
switch ( m_State )
{
default:
case ElectionState.Pending:
period = PendingPeriod;
break;
case ElectionState.Election:
period = VotingPeriod;
break;
case ElectionState.Campaign:
period = CampaignPeriod;
break;
}
TimeSpan until = (m_LastStateTime + period) - DateTime.UtcNow;
if (until < TimeSpan.Zero)
until = TimeSpan.Zero;
return until;
}
set
{
TimeSpan period;
switch ( m_State )
{
default:
case ElectionState.Pending:
period = PendingPeriod;
break;
case ElectionState.Election:
period = VotingPeriod;
break;
case ElectionState.Campaign:
period = CampaignPeriod;
break;
}
m_LastStateTime = DateTime.UtcNow - period + value;
}
}
public void StartTimer()
{
m_Timer = Timer.DelayCall(TimeSpan.FromMinutes(1.0), TimeSpan.FromMinutes(1.0), new TimerCallback(Slice));
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt((int)0); // version
Faction.WriteReference(writer, m_Faction);
writer.Write((DateTime)m_LastStateTime);
writer.WriteEncodedInt((int)m_State);
writer.WriteEncodedInt(m_Candidates.Count);
for (int i = 0; i < m_Candidates.Count; ++i)
m_Candidates[i].Serialize(writer);
}
public void AddCandidate(Mobile mob)
{
if (IsCandidate(mob))
return;
m_Candidates.Add(new Candidate(mob));
mob.SendLocalizedMessage(1010117); // You are now running for office.
}
public void RemoveVoter(Mobile mob)
{
if (m_State == ElectionState.Election)
{
for (int i = 0; i < m_Candidates.Count; ++i)
{
List<Voter> voters = m_Candidates[i].Voters;
for (int j = 0; j < voters.Count; ++j)
{
Voter voter = voters[j];
if (voter.From == mob)
voters.RemoveAt(j--);
}
}
}
}
public void RemoveCandidate(Mobile mob)
{
Candidate cd = FindCandidate(mob);
if (cd == null)
return;
m_Candidates.Remove(cd);
mob.SendLocalizedMessage(1038031);
if (m_State == ElectionState.Election)
{
if (m_Candidates.Count == 1)
{
m_Faction.Broadcast(1038031); // There are no longer any valid candidates in the Faction Commander election.
Candidate winner = m_Candidates[0];
Mobile winMob = winner.Mobile;
PlayerState pl = PlayerState.Find(winMob);
if (pl == null || pl.Faction != m_Faction || winMob == m_Faction.Commander)
{
m_Faction.Broadcast(1038026); // Faction leadership has not changed.
}
else
{
m_Faction.Broadcast(1038028); // The faction has a new commander.
m_Faction.Commander = winMob;
}
m_Candidates.Clear();
State = ElectionState.Pending;
}
else if (m_Candidates.Count == 0) // well, I guess this'll never happen
{
m_Faction.Broadcast(1038031); // There are no longer any valid candidates in the Faction Commander election.
m_Candidates.Clear();
State = ElectionState.Pending;
}
}
}
public bool IsCandidate(Mobile mob)
{
return (FindCandidate(mob) != null);
}
public bool CanVote(Mobile mob)
{
return (m_State == ElectionState.Election && !HasVoted(mob));
}
public bool HasVoted(Mobile mob)
{
return (FindVoter(mob) != null);
}
public Candidate FindCandidate(Mobile mob)
{
for (int i = 0; i < m_Candidates.Count; ++i)
{
if (m_Candidates[i].Mobile == mob)
return m_Candidates[i];
}
return null;
}
public Candidate FindVoter(Mobile mob)
{
for (int i = 0; i < m_Candidates.Count; ++i)
{
List<Voter> voters = m_Candidates[i].Voters;
for (int j = 0; j < voters.Count; ++j)
{
Voter voter = voters[j];
if (voter.From == mob)
return m_Candidates[i];
}
}
return null;
}
public bool CanBeCandidate(Mobile mob)
{
if (IsCandidate(mob))
return false;
if (m_Candidates.Count >= MaxCandidates)
return false;
if (m_State != ElectionState.Campaign)
return false; // sanity..
PlayerState pl = PlayerState.Find(mob);
return (pl != null && pl.Faction == m_Faction && pl.Rank.Rank >= CandidateRank);
}
public void Slice()
{
if (m_Faction == null || m_Faction.Election != this)
{
if (m_Timer != null)
m_Timer.Stop();
m_Timer = null;
return;
}
switch ( m_State )
{
case ElectionState.Pending:
{
if ((m_LastStateTime + PendingPeriod) > DateTime.UtcNow)
break;
m_Faction.Broadcast(1038023); // Campaigning for the Faction Commander election has begun.
m_Candidates.Clear();
State = ElectionState.Campaign;
break;
}
case ElectionState.Campaign:
{
if ((m_LastStateTime + CampaignPeriod) > DateTime.UtcNow)
break;
if (m_Candidates.Count == 0)
{
m_Faction.Broadcast(1038025); // Nobody ran for office.
State = ElectionState.Pending;
}
else if (m_Candidates.Count == 1)
{
m_Faction.Broadcast(1038029); // Only one member ran for office.
Candidate winner = m_Candidates[0];
Mobile mob = winner.Mobile;
PlayerState pl = PlayerState.Find(mob);
if (pl == null || pl.Faction != m_Faction || mob == m_Faction.Commander)
{
m_Faction.Broadcast(1038026); // Faction leadership has not changed.
}
else
{
m_Faction.Broadcast(1038028); // The faction has a new commander.
m_Faction.Commander = mob;
}
m_Candidates.Clear();
State = ElectionState.Pending;
}
else
{
m_Faction.Broadcast(1038030);
State = ElectionState.Election;
}
break;
}
case ElectionState.Election:
{
if ((m_LastStateTime + VotingPeriod) > DateTime.UtcNow)
break;
m_Faction.Broadcast(1038024); // The results for the Faction Commander election are in
Candidate winner = null;
for (int i = 0; i < m_Candidates.Count; ++i)
{
Candidate cd = m_Candidates[i];
PlayerState pl = PlayerState.Find(cd.Mobile);
if (pl == null || pl.Faction != m_Faction)
continue;
//cd.CleanMuleVotes();
if (winner == null || cd.Votes > winner.Votes)
winner = cd;
}
if (winner == null)
{
m_Faction.Broadcast(1038026); // Faction leadership has not changed.
}
else if (winner.Mobile == m_Faction.Commander)
{
m_Faction.Broadcast(1038027); // The incumbent won the election.
}
else
{
m_Faction.Broadcast(1038028); // The faction has a new commander.
m_Faction.Commander = winner.Mobile;
}
m_Candidates.Clear();
State = ElectionState.Pending;
break;
}
}
}
}
public class Voter
{
private readonly Mobile m_From;
private readonly Mobile m_Candidate;
private readonly IPAddress m_Address;
private readonly DateTime m_Time;
public Voter(Mobile from, Mobile candidate)
{
m_From = from;
m_Candidate = candidate;
if (m_From.NetState != null)
m_Address = m_From.NetState.Address;
else
m_Address = IPAddress.None;
m_Time = DateTime.UtcNow;
}
public Voter(GenericReader reader, Mobile candidate)
{
m_Candidate = candidate;
int version = reader.ReadEncodedInt();
switch ( version )
{
case 0:
{
m_From = reader.ReadMobile();
m_Address = Utility.Intern(reader.ReadIPAddress());
m_Time = reader.ReadDateTime();
break;
}
}
}
public Mobile From
{
get
{
return m_From;
}
}
public Mobile Candidate
{
get
{
return m_Candidate;
}
}
public IPAddress Address
{
get
{
return m_Address;
}
}
public DateTime Time
{
get
{
return m_Time;
}
}
public object[] AcquireFields()
{
TimeSpan gameTime = TimeSpan.Zero;
if (m_From is PlayerMobile)
gameTime = ((PlayerMobile)m_From).GameTime;
int kp = 0;
PlayerState pl = PlayerState.Find(m_From);
if (pl != null)
kp = pl.KillPoints;
int sk = m_From.Skills.Total;
int factorSkills = 50 + ((sk * 100) / 10000);
int factorKillPts = 100 + (kp * 2);
int factorGameTime = 50 + (int)((gameTime.Ticks * 100) / TimeSpan.TicksPerDay);
int totalFactor = (factorSkills * factorKillPts * Math.Max(factorGameTime, 100)) / 10000;
if (totalFactor > 100)
totalFactor = 100;
else if (totalFactor < 0)
totalFactor = 0;
return new object[] { m_From, m_Address, m_Time, totalFactor };
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt((int)0);
writer.Write((Mobile)m_From);
writer.Write((IPAddress)m_Address);
writer.Write((DateTime)m_Time);
}
}
public class Candidate
{
private readonly Mobile m_Mobile;
private readonly List<Voter> m_Voters;
public Candidate(Mobile mob)
{
m_Mobile = mob;
m_Voters = new List<Voter>();
}
public Candidate(GenericReader reader)
{
int version = reader.ReadEncodedInt();
switch ( version )
{
case 1:
{
m_Mobile = reader.ReadMobile();
int count = reader.ReadEncodedInt();
m_Voters = new List<Voter>(count);
for (int i = 0; i < count; ++i)
{
Voter voter = new Voter(reader, m_Mobile);
if (voter.From != null)
m_Voters.Add(voter);
}
break;
}
case 0:
{
m_Mobile = reader.ReadMobile();
List<Mobile> mobs = reader.ReadStrongMobileList();
m_Voters = new List<Voter>(mobs.Count);
for (int i = 0; i < mobs.Count; ++i)
m_Voters.Add(new Voter(mobs[i], m_Mobile));
break;
}
}
}
public Mobile Mobile
{
get
{
return m_Mobile;
}
}
public List<Voter> Voters
{
get
{
return m_Voters;
}
}
public int Votes
{
get
{
return m_Voters.Count;
}
}
public void CleanMuleVotes()
{
for (int i = 0; i < m_Voters.Count; ++i)
{
Voter voter = (Voter)m_Voters[i];
if ((int)voter.AcquireFields()[3] < 90)
m_Voters.RemoveAt(i--);
}
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt((int)1); // version
writer.Write((Mobile)m_Mobile);
writer.WriteEncodedInt((int)m_Voters.Count);
for (int i = 0; i < m_Voters.Count; ++i)
((Voter)m_Voters[i]).Serialize(writer);
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,179 @@
using System;
namespace Server.Factions
{
public interface IFactionItem
{
FactionItem FactionItemState { get; set; }
}
public class FactionItem
{
public static readonly TimeSpan ExpirationPeriod = TimeSpan.FromDays(21.0);
private readonly Item m_Item;
private readonly Faction m_Faction;
private DateTime m_Expiration;
private int m_MinRank;
public FactionItem(Item item, Faction faction, int level)
{
m_Item = item;
m_Faction = faction;
m_MinRank = level;
}
public FactionItem(GenericReader reader, Faction faction)
{
int version = reader.ReadEncodedInt();
switch ( version )
{
case 1:
{
m_MinRank = reader.ReadInt();
goto case 0;
}
case 0:
{
m_Item = reader.ReadItem();
m_Expiration = reader.ReadDateTime();
break;
}
}
m_Faction = faction;
}
public Item Item
{
get
{
return m_Item;
}
}
public Faction Faction
{
get
{
return m_Faction;
}
}
public DateTime Expiration
{
get
{
return m_Expiration;
}
}
public int MinRank
{
get
{
return m_MinRank;
}
}
public bool HasExpired
{
get
{
if (m_Item == null || m_Item.Deleted)
return true;
return (m_Expiration != DateTime.MinValue && DateTime.UtcNow >= m_Expiration);
}
}
public static int GetMaxWearables(Mobile mob)
{
PlayerState pl = PlayerState.Find(mob);
if (pl == null)
return 0;
if (pl.Faction.IsCommander(mob))
return 9;
return pl.Rank.MaxWearables;
}
public static FactionItem Find(Item item)
{
if (item is IFactionItem)
{
FactionItem state = ((IFactionItem)item).FactionItemState;
if (state != null && state.HasExpired)
{
state.Detach();
state = null;
}
return state;
}
return null;
}
public static Item Imbue(Item item, Faction faction, bool expire, int hue, int MinRank = 0)
{
if (!(item is IFactionItem))
return item;
FactionItem state = Find(item);
if (state == null)
{
state = new FactionItem(item, faction, MinRank);
state.Attach();
}
if (expire)
state.StartExpiration();
if (hue >= 0)
item.Hue = hue;
return item;
}
public void StartExpiration()
{
m_Expiration = DateTime.UtcNow + ExpirationPeriod;
}
public void CheckAttach()
{
if (!HasExpired)
Attach();
else
Detach();
}
public void Attach()
{
if (m_Item is IFactionItem)
((IFactionItem)m_Item).FactionItemState = this;
if (m_Faction != null)
m_Faction.State.FactionItems.Add(this);
}
public void Detach()
{
if (m_Item is IFactionItem)
((IFactionItem)m_Item).FactionItemState = null;
if (m_Faction != null && m_Faction.State.FactionItems.Contains(this))
m_Faction.State.FactionItems.Remove(this);
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt((int)1);
writer.Write(m_MinRank);
writer.Write((Item)m_Item);
writer.Write((DateTime)m_Expiration);
}
}
}

View File

@@ -0,0 +1,389 @@
using System;
using System.Collections.Generic;
namespace Server.Factions
{
public class FactionState
{
private static readonly TimeSpan BroadcastPeriod = TimeSpan.FromHours(1.0);
private const int BroadcastsPerPeriod = 2;
private readonly Faction m_Faction;
private readonly DateTime[] m_LastBroadcasts = new DateTime[BroadcastsPerPeriod];
private Mobile m_Commander;
private int m_Tithe;
private int m_Silver;
private List<PlayerState> m_Members;
private Election m_Election;
private List<FactionItem> m_FactionItems;
private List<BaseFactionTrap> m_FactionTraps;
private DateTime m_LastAtrophy;
public FactionState(Faction faction)
{
m_Faction = faction;
m_Tithe = 50;
m_Members = new List<PlayerState>();
m_Election = new Election(faction);
m_FactionItems = new List<FactionItem>();
m_FactionTraps = new List<BaseFactionTrap>();
}
public FactionState(GenericReader reader)
{
int version = reader.ReadEncodedInt();
switch ( version )
{
case 6:
case 5:
{
m_LastAtrophy = reader.ReadDateTime();
goto case 4;
}
case 4:
{
int count = reader.ReadEncodedInt();
for (int i = 0; i < count; ++i)
{
DateTime time = reader.ReadDateTime();
if (i < m_LastBroadcasts.Length)
m_LastBroadcasts[i] = time;
}
goto case 3;
}
case 3:
case 2:
case 1:
{
Election ele = new Election(reader);
if (Settings.Enabled)
m_Election = ele;
else
m_Election = new Election(m_Faction);
goto case 0;
}
case 0:
{
m_Faction = Faction.ReadReference(reader);
if (m_Election.Faction == null)
{
m_Election.Faction = m_Faction;
}
m_Commander = reader.ReadMobile();
if (version < 5)
m_LastAtrophy = DateTime.UtcNow;
if (version < 4)
{
DateTime time = reader.ReadDateTime();
if (m_LastBroadcasts.Length > 0)
m_LastBroadcasts[0] = time;
}
m_Tithe = reader.ReadEncodedInt();
m_Silver = reader.ReadEncodedInt();
int memberCount = reader.ReadEncodedInt();
m_Members = new List<PlayerState>();
for (int i = 0; i < memberCount; ++i)
{
PlayerState pl = new PlayerState(reader, m_Faction, m_Members);
if (pl.Mobile != null)
{
if (Settings.Enabled)
{
m_Members.Add(pl);
}
else
{
Settings.AddDisabledNotice(pl.Mobile);
}
}
}
m_Faction.State = this;
m_Faction.ZeroRankOffset = m_Members.Count;
m_Members.Sort();
for (int i = m_Members.Count - 1; i >= 0; i--)
{
PlayerState player = m_Members[i];
if (player.KillPoints <= 0)
m_Faction.ZeroRankOffset = i;
else
player.RankIndex = i;
}
m_FactionItems = new List<FactionItem>();
if (version >= 2)
{
int factionItemCount = reader.ReadEncodedInt();
for (int i = 0; i < factionItemCount; ++i)
{
FactionItem factionItem = new FactionItem(reader, m_Faction);
if(Settings.Enabled)
Timer.DelayCall(TimeSpan.Zero, new TimerCallback(factionItem.CheckAttach)); // sandbox attachment
}
}
m_FactionTraps = new List<BaseFactionTrap>();
if (version >= 3)
{
int factionTrapCount = reader.ReadEncodedInt();
for (int i = 0; i < factionTrapCount; ++i)
{
BaseFactionTrap trap = reader.ReadItem() as BaseFactionTrap;
if (trap != null && !trap.CheckDecay())
{
if (Settings.Enabled)
m_FactionTraps.Add(trap);
else
trap.Delete();
}
}
}
break;
}
}
if (version < 6 && Settings.Enabled && Core.ML)
{
FactionCollectionBox box = new FactionCollectionBox(m_Faction);
WeakEntityCollection.Add("factions", box);
box.MoveToWorld(m_Faction.Definition.Stronghold.CollectionBox, Faction.Facet);
}
if (version < 1)
m_Election = new Election(m_Faction);
}
public DateTime LastAtrophy
{
get
{
return m_LastAtrophy;
}
set
{
m_LastAtrophy = value;
}
}
public bool FactionMessageReady
{
get
{
for (int i = 0; i < m_LastBroadcasts.Length; ++i)
{
if (DateTime.UtcNow >= (m_LastBroadcasts[i] + BroadcastPeriod))
return true;
}
return false;
}
}
public bool IsAtrophyReady
{
get
{
return DateTime.UtcNow >= (m_LastAtrophy + TimeSpan.FromHours(47.0));
}
}
public List<FactionItem> FactionItems
{
get
{
return m_FactionItems;
}
set
{
m_FactionItems = value;
}
}
public List<BaseFactionTrap> Traps
{
get
{
return m_FactionTraps;
}
set
{
m_FactionTraps = value;
}
}
public Election Election
{
get
{
return m_Election;
}
set
{
m_Election = value;
}
}
public Mobile Commander
{
get
{
return m_Commander;
}
set
{
if (m_Commander != null)
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();
PlayerState pl = PlayerState.Find(m_Commander);
if (pl != null && pl.Finance != null)
pl.Finance.Finance = null;
if (pl != null && pl.Sheriff != null)
pl.Sheriff.Sheriff = null;
}
}
}
public int Tithe
{
get
{
return m_Tithe;
}
set
{
m_Tithe = value;
}
}
public int Silver
{
get
{
return m_Silver;
}
set
{
m_Silver = value;
}
}
public List<PlayerState> Members
{
get
{
return m_Members;
}
set
{
m_Members = value;
}
}
public int CheckAtrophy()
{
if (DateTime.UtcNow < (m_LastAtrophy + TimeSpan.FromHours(47.0)))
return 0;
int distrib = 0;
m_LastAtrophy = DateTime.UtcNow;
List<PlayerState> members = new List<PlayerState>(m_Members);
for (int i = 0; i < members.Count; ++i)
{
PlayerState ps = members[i];
if (ps.IsActive)
{
ps.IsActive = false;
continue;
}
else if (ps.KillPoints > 0)
{
int atrophy = (ps.KillPoints + 9) / 10;
ps.KillPoints -= atrophy;
distrib += atrophy;
}
}
return distrib;
}
public void RegisterBroadcast()
{
for (int i = 0; i < m_LastBroadcasts.Length; ++i)
{
if (DateTime.UtcNow >= (m_LastBroadcasts[i] + BroadcastPeriod))
{
m_LastBroadcasts[i] = DateTime.UtcNow;
break;
}
}
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt((int)6); // version
writer.Write(m_LastAtrophy);
writer.WriteEncodedInt((int)m_LastBroadcasts.Length);
for (int i = 0; i < m_LastBroadcasts.Length; ++i)
writer.Write((DateTime)m_LastBroadcasts[i]);
m_Election.Serialize(writer);
Faction.WriteReference(writer, m_Faction);
writer.Write((Mobile)m_Commander);
writer.WriteEncodedInt((int)m_Tithe);
writer.WriteEncodedInt((int)m_Silver);
writer.WriteEncodedInt((int)m_Members.Count);
for (int i = 0; i < m_Members.Count; ++i)
{
PlayerState pl = (PlayerState)m_Members[i];
pl.Serialize(writer);
}
writer.WriteEncodedInt((int)m_FactionItems.Count);
for (int i = 0; i < m_FactionItems.Count; ++i)
m_FactionItems[i].Serialize(writer);
writer.WriteEncodedInt((int)m_FactionTraps.Count);
for (int i = 0; i < m_FactionTraps.Count; ++i)
writer.Write((Item)m_FactionTraps[i]);
}
}
}

View File

@@ -0,0 +1,137 @@
using System;
using System.Collections.Generic;
using Server.Commands;
using System.Linq;
namespace Server.Factions
{
public class Generator
{
public static void Initialize()
{
CommandSystem.Register("GenerateFactions", AccessLevel.Administrator, new CommandEventHandler(GenerateFactions_OnCommand));
CommandSystem.Register("DeleteFactions", AccessLevel.Administrator, new CommandEventHandler(DeleteFactions_OnCommand));
}
public static void RemoveFactions()
{
// Removes Items, ie monoliths, stones, etc
WeakEntityCollection.Delete("factions");
List<Item> items = new List<Item>(World.Items.Values.Where(i => i is StrongholdRune ||
i is ShrineGem || i is EnchantedBandage || i is PowderOfPerseverance || i is Sigil));
foreach (var item in items)
{
item.Delete();
}
ColUtility.Free(items);
}
public static void DeleteFactions_OnCommand(CommandEventArgs e)
{
RemoveFactions();
}
public static void GenerateFactions_OnCommand(CommandEventArgs e)
{
if (Settings.Enabled)
{
new FactionPersistence();
List<Faction> factions = Faction.Factions;
foreach (Faction faction in factions)
Generate(faction);
List<Town> towns = Town.Towns;
foreach (Town town in towns)
Generate(town);
e.Mobile.SendMessage("Factions generated!");
}
else
{
e.Mobile.SendMessage("You must enable factions first by disabling VvV before you can generate.");
}
}
public static void Generate(Town town)
{
Map facet = Faction.Facet;
TownDefinition def = town.Definition;
if (!CheckExistance(def.Monolith, facet, typeof(TownMonolith)))
{
TownMonolith mono = new TownMonolith(town);
mono.MoveToWorld(def.Monolith, facet);
mono.Sigil = new Sigil(town);
WeakEntityCollection.Add("factions", mono);
WeakEntityCollection.Add("factions", mono.Sigil);
}
if (!CheckExistance(def.TownStone, facet, typeof(TownStone)))
{
TownStone stone = new TownStone(town);
WeakEntityCollection.Add("factions", stone);
stone.MoveToWorld(def.TownStone, facet);
}
}
public static void Generate(Faction faction)
{
Map facet = Faction.Facet;
List<Town> towns = Town.Towns;
StrongholdDefinition stronghold = faction.Definition.Stronghold;
if (!CheckExistance(stronghold.JoinStone, facet, typeof(JoinStone)))
{
JoinStone join = new JoinStone(faction);
WeakEntityCollection.Add("factions", join);
join.MoveToWorld(stronghold.JoinStone, facet);
}
if (!CheckExistance(stronghold.FactionStone, facet, typeof(FactionStone)))
{
FactionStone stone = new FactionStone(faction);
WeakEntityCollection.Add("factions", stone);
stone.MoveToWorld(stronghold.FactionStone, facet);
}
for (int i = 0; i < stronghold.Monoliths.Length; ++i)
{
Point3D monolith = stronghold.Monoliths[i];
if (!CheckExistance(monolith, facet, typeof(StrongholdMonolith)))
{
StrongholdMonolith mono = new StrongholdMonolith(towns[i], faction);
WeakEntityCollection.Add("factions", mono);
mono.MoveToWorld(monolith, facet);
}
}
if (Core.ML && !CheckExistance(stronghold.FactionStone, facet, typeof(FactionCollectionBox)))
{
FactionCollectionBox box = new FactionCollectionBox(faction);
WeakEntityCollection.Add("factions", box);
box.MoveToWorld(stronghold.CollectionBox, facet);
}
}
private static bool CheckExistance(Point3D loc, Map facet, Type type)
{
foreach (Item item in facet.GetItemsInRange(loc, 0))
{
if (type.IsAssignableFrom(item.GetType()))
return true;
}
return false;
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
namespace Server.Factions
{
public class GuardList
{
private readonly GuardDefinition m_Definition;
private readonly List<BaseFactionGuard> m_Guards;
public GuardList(GuardDefinition definition)
{
this.m_Definition = definition;
this.m_Guards = new List<BaseFactionGuard>();
}
public GuardDefinition Definition
{
get
{
return this.m_Definition;
}
}
public List<BaseFactionGuard> Guards
{
get
{
return this.m_Guards;
}
}
public BaseFactionGuard Construct()
{
try
{
return Activator.CreateInstance(this.m_Definition.Type) as BaseFactionGuard;
}
catch
{
return null;
}
}
}
}

View File

@@ -0,0 +1,156 @@
using System;
using Server.Mobiles;
using Server.Network;
namespace Server.Factions
{
public class Keywords
{
public static void Initialize()
{
EventSink.Speech += new SpeechEventHandler(EventSink_Speech);
}
private static void ShowScore_Sandbox(object state)
{
PlayerState pl = (PlayerState)state;
if (pl != null)
pl.Mobile.PublicOverheadMessage(MessageType.Regular, pl.Mobile.SpeechHue, true, pl.KillPoints.ToString("N0")); // NOTE: Added 'N0'
}
private static void EventSink_Speech(SpeechEventArgs e)
{
Mobile from = e.Mobile;
int[] keywords = e.Keywords;
for (int i = 0; i < keywords.Length; ++i)
{
switch ( keywords[i] )
{
case 0x00E4: // *i wish to access the city treasury*
{
Town town = Town.FromRegion(from.Region);
if (town == null || !town.IsFinance(from) || !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)
from.SendGump(new FinanceGump((PlayerMobile)from, town.Owner, town));
break;
}
case 0x0ED: // *i am sheriff*
{
Town town = Town.FromRegion(from.Region);
if (town == null || !town.IsSheriff(from) || !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*
{
Town 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*
{
PlayerState pl = PlayerState.Find(from);
if (pl != null && 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*
{
PlayerState pl = PlayerState.Find(from);
if (pl != null && 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*
{
PlayerState pl = PlayerState.Find(from);
if (pl != null && pl.IsLeaving)
{
if (Faction.CheckLeaveTimer(from))
break;
TimeSpan remaining = (pl.Leaving + Faction.LeavePeriod) - DateTime.UtcNow;
if (remaining.TotalDays >= 1)
from.SendLocalizedMessage(1042743, remaining.TotalDays.ToString("N0")) ;// Your term of service will come to an end in ~1_DAYS~ days.
else if (remaining.TotalHours >= 1)
from.SendLocalizedMessage(1042741, remaining.TotalHours.ToString("N0")); // Your term of service will come to an end in ~1_HOURS~ hours.
else
from.SendLocalizedMessage(1042742); // Your term of service will come to an end in less than one hour.
}
else if (pl != null)
{
from.SendLocalizedMessage(1042233); // You are not in the process of quitting the faction.
}
break;
}
case 0x00EA: // *message faction*
{
Faction faction = Faction.Find(from);
if (faction == null || !faction.IsCommander(from))
break;
if (from.IsPlayer() && !faction.FactionMessageReady)
from.SendLocalizedMessage(1010264); // The required time has not yet passed since the last message was sent
else
faction.BeginBroadcast(from);
break;
}
case 0x00EC: // *showscore*
{
PlayerState pl = PlayerState.Find(from);
if (pl != null)
Timer.DelayCall(TimeSpan.Zero, new TimerStateCallback(ShowScore_Sandbox), pl);
break;
}
case 0x0178: // i honor your leadership
{
Faction faction = Faction.Find(from);
if (faction != null)
faction.BeginHonorLeadership(from);
break;
}
}
}
}
}
}

View File

@@ -0,0 +1,120 @@
using System;
namespace Server.Factions
{
public enum MerchantTitle
{
None,
Scribe,
Carpenter,
Blacksmith,
Bowyer,
Tialor
}
public class MerchantTitleInfo
{
private readonly SkillName m_Skill;
private readonly double m_Requirement;
private readonly TextDefinition m_Title;
private readonly TextDefinition m_Label;
private readonly TextDefinition m_Assigned;
public MerchantTitleInfo(SkillName skill, double requirement, TextDefinition title, TextDefinition label, TextDefinition assigned)
{
this.m_Skill = skill;
this.m_Requirement = requirement;
this.m_Title = title;
this.m_Label = label;
this.m_Assigned = assigned;
}
public SkillName Skill
{
get
{
return this.m_Skill;
}
}
public double Requirement
{
get
{
return this.m_Requirement;
}
}
public TextDefinition Title
{
get
{
return this.m_Title;
}
}
public TextDefinition Label
{
get
{
return this.m_Label;
}
}
public TextDefinition Assigned
{
get
{
return this.m_Assigned;
}
}
}
public class MerchantTitles
{
private static readonly MerchantTitleInfo[] m_Info = new MerchantTitleInfo[]
{
new MerchantTitleInfo(SkillName.Inscribe, 90.0, new TextDefinition(1060773, "Scribe"), new TextDefinition(1011468, "SCRIBE"), new TextDefinition(1010121, "You now have the faction title of scribe")),
new MerchantTitleInfo(SkillName.Carpentry, 90.0, new TextDefinition(1060774, "Carpenter"), new TextDefinition(1011469, "CARPENTER"), new TextDefinition(1010122, "You now have the faction title of carpenter")),
new MerchantTitleInfo(SkillName.Tinkering, 90.0, new TextDefinition(1022984, "Tinker"), new TextDefinition(1011470, "TINKER"), new TextDefinition(1010123, "You now have the faction title of tinker")),
new MerchantTitleInfo(SkillName.Blacksmith, 90.0, new TextDefinition(1023016, "Blacksmith"), new TextDefinition(1011471, "BLACKSMITH"), new TextDefinition(1010124, "You now have the faction title of blacksmith")),
new MerchantTitleInfo(SkillName.Fletching, 90.0, new TextDefinition(1023022, "Bowyer"), new TextDefinition(1011472, "BOWYER"), new TextDefinition(1010125, "You now have the faction title of Bowyer")),
new MerchantTitleInfo(SkillName.Tailoring, 90.0, new TextDefinition(1022982, "Tailor"), new TextDefinition(1018300, "TAILOR"), new TextDefinition(1042162, "You now have the faction title of Tailor")),
};
public static MerchantTitleInfo[] Info
{
get
{
return m_Info;
}
}
public static MerchantTitleInfo GetInfo(MerchantTitle title)
{
int idx = (int)title - 1;
if (idx >= 0 && idx < m_Info.Length)
return m_Info[idx];
return null;
}
public static bool HasMerchantQualifications(Mobile mob)
{
for (int i = 0; i < m_Info.Length; ++i)
{
if (IsQualified(mob, m_Info[i]))
return true;
}
return false;
}
public static bool IsQualified(Mobile mob, MerchantTitle title)
{
return 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);
}
}
}

View File

@@ -0,0 +1,112 @@
using System;
using System.Collections.Generic;
namespace Server.Factions
{
[TypeAlias("Server.Factions.FactionPersistance")]
public class FactionPersistence : Item
{
private static FactionPersistence m_Instance;
public FactionPersistence()
: base(1)
{
this.Movable = false;
if (m_Instance == null || m_Instance.Deleted)
m_Instance = this;
else
base.Delete();
}
public FactionPersistence(Serial serial)
: base(serial)
{
m_Instance = this;
}
private enum PersistedType
{
Terminator,
Faction,
Town
}
public static FactionPersistence Instance
{
get
{
return m_Instance;
}
}
public override string DefaultName
{
get
{
return "Faction Persistance - Internal";
}
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
// Version 0 removes faction items, ie monoliths, stones, etc
writer.Write((int)1); // version
List<Faction> factions = Faction.Factions;
for (int i = 0; i < factions.Count; ++i)
{
writer.WriteEncodedInt((int)PersistedType.Faction);
factions[i].State.Serialize(writer);
}
List<Town> towns = Town.Towns;
for (int i = 0; i < towns.Count; ++i)
{
writer.WriteEncodedInt((int)PersistedType.Town);
towns[i].State.Serialize(writer);
}
writer.WriteEncodedInt((int)PersistedType.Terminator);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch ( version )
{
case 1:
case 0:
{
PersistedType type;
while ((type = (PersistedType)reader.ReadEncodedInt()) != PersistedType.Terminator)
{
switch ( type )
{
case PersistedType.Faction:
new FactionState(reader);
break;
case PersistedType.Town:
new TownState(reader);
break;
}
}
break;
}
}
if (!Settings.Enabled && version == 0)
Timer.DelayCall(TimeSpan.FromSeconds(10), () => Generator.RemoveFactions());
}
public override void Delete()
{
}
}
}

View File

@@ -0,0 +1,374 @@
using System;
using System.Collections.Generic;
using Server.Mobiles;
namespace Server.Factions
{
public class PlayerState : IComparable
{
private readonly Mobile m_Mobile;
private readonly Faction m_Faction;
private readonly List<PlayerState> m_Owner;
private int m_KillPoints;
private DateTime m_Leaving;
private MerchantTitle m_MerchantTitle;
private RankDefinition m_Rank;
private List<SilverGivenEntry> m_SilverGiven;
private bool m_IsActive;
private Town m_Sheriff;
private Town m_Finance;
private DateTime m_LastHonorTime;
private bool m_InvalidateRank = true;
private int m_RankIndex = -1;
public PlayerState(Mobile mob, Faction faction, List<PlayerState> owner)
{
m_Mobile = mob;
m_Faction = faction;
m_Owner = owner;
Attach();
Invalidate();
}
public PlayerState(GenericReader reader, Faction faction, List<PlayerState> owner)
{
m_Faction = faction;
m_Owner = owner;
int version = reader.ReadEncodedInt();
switch ( version )
{
case 1:
{
m_IsActive = reader.ReadBool();
m_LastHonorTime = reader.ReadDateTime();
goto case 0;
}
case 0:
{
m_Mobile = reader.ReadMobile();
m_KillPoints = reader.ReadEncodedInt();
m_MerchantTitle = (MerchantTitle)reader.ReadEncodedInt();
m_Leaving = reader.ReadDateTime();
break;
}
}
Attach();
}
public Mobile Mobile
{
get
{
return m_Mobile;
}
}
public Faction Faction
{
get
{
return m_Faction;
}
}
public List<PlayerState> Owner
{
get
{
return m_Owner;
}
}
public MerchantTitle MerchantTitle
{
get
{
return m_MerchantTitle;
}
set
{
m_MerchantTitle = value;
Invalidate();
}
}
public Town Sheriff
{
get
{
return m_Sheriff;
}
set
{
m_Sheriff = value;
Invalidate();
}
}
public Town Finance
{
get
{
return m_Finance;
}
set
{
m_Finance = value;
Invalidate();
}
}
public List<SilverGivenEntry> SilverGiven
{
get
{
return m_SilverGiven;
}
}
public int KillPoints
{
get
{
return m_KillPoints;
}
set
{
if (m_KillPoints != value)
{
if (value > m_KillPoints)
{
if (m_KillPoints <= 0)
{
if (value <= 0)
{
m_KillPoints = value;
Invalidate();
return;
}
m_Owner.Remove(this);
m_Owner.Insert(m_Faction.ZeroRankOffset, this);
m_RankIndex = m_Faction.ZeroRankOffset;
m_Faction.ZeroRankOffset++;
}
while ((m_RankIndex - 1) >= 0)
{
PlayerState p = m_Owner[m_RankIndex - 1] as PlayerState;
if (value > p.KillPoints)
{
m_Owner[m_RankIndex] = p;
m_Owner[m_RankIndex - 1] = this;
RankIndex--;
p.RankIndex++;
}
else
break;
}
}
else
{
if (value <= 0)
{
if (m_KillPoints <= 0)
{
m_KillPoints = value;
Invalidate();
return;
}
while ((m_RankIndex + 1) < m_Faction.ZeroRankOffset)
{
PlayerState p = m_Owner[m_RankIndex + 1] as PlayerState;
m_Owner[m_RankIndex + 1] = this;
m_Owner[m_RankIndex] = p;
RankIndex++;
p.RankIndex--;
}
m_RankIndex = -1;
m_Faction.ZeroRankOffset--;
}
else
{
while ((m_RankIndex + 1) < m_Faction.ZeroRankOffset)
{
PlayerState p = m_Owner[m_RankIndex + 1] as PlayerState;
if (value < p.KillPoints)
{
m_Owner[m_RankIndex + 1] = this;
m_Owner[m_RankIndex] = p;
RankIndex++;
p.RankIndex--;
}
else
break;
}
}
}
m_KillPoints = value;
Invalidate();
}
}
}
public int RankIndex
{
get
{
return m_RankIndex;
}
set
{
if (m_RankIndex != value)
{
m_RankIndex = value;
m_InvalidateRank = true;
}
}
}
public RankDefinition Rank
{
get
{
if (m_InvalidateRank)
{
RankDefinition[] ranks = m_Faction.Definition.Ranks;
int percent;
if (m_Owner.Count == 1)
percent = 1000;
else if (m_RankIndex == -1)
percent = 0;
else
percent = ((m_Faction.ZeroRankOffset - m_RankIndex) * 1000) / m_Faction.ZeroRankOffset;
for (int i = 0; i < ranks.Length; i++)
{
RankDefinition check = ranks[i];
if (percent >= check.Required)
{
m_Rank = check;
m_InvalidateRank = false;
break;
}
}
Invalidate();
}
return m_Rank;
}
}
public DateTime LastHonorTime
{
get
{
return m_LastHonorTime;
}
set
{
m_LastHonorTime = value;
}
}
public DateTime Leaving
{
get
{
return m_Leaving;
}
set
{
m_Leaving = value;
}
}
public bool IsLeaving
{
get
{
return (m_Leaving > DateTime.MinValue);
}
}
public bool IsActive
{
get
{
return m_IsActive;
}
set
{
m_IsActive = value;
}
}
public static PlayerState Find(Mobile mob)
{
if (mob is PlayerMobile)
return ((PlayerMobile)mob).FactionPlayerState;
return null;
}
public bool CanGiveSilverTo(Mobile mob)
{
if (m_SilverGiven == null)
return true;
for (int i = 0; i < m_SilverGiven.Count; ++i)
{
SilverGivenEntry sge = m_SilverGiven[i];
if (sge.IsExpired)
m_SilverGiven.RemoveAt(i--);
else if (sge.GivenTo == mob)
return false;
}
return true;
}
public void OnGivenSilverTo(Mobile mob)
{
if (m_SilverGiven == null)
m_SilverGiven = new List<SilverGivenEntry>();
m_SilverGiven.Add(new SilverGivenEntry(mob));
}
public void Invalidate()
{
if (m_Mobile is PlayerMobile)
{
PlayerMobile pm = (PlayerMobile)m_Mobile;
pm.InvalidateProperties();
}
}
public void Attach()
{
if (Settings.Enabled && m_Mobile is PlayerMobile)
((PlayerMobile)m_Mobile).FactionPlayerState = this;
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt((int)1); // version
writer.Write(m_IsActive);
writer.Write(m_LastHonorTime);
writer.Write((Mobile)m_Mobile);
writer.WriteEncodedInt((int)m_KillPoints);
writer.WriteEncodedInt((int)m_MerchantTitle);
writer.Write((DateTime)m_Leaving);
}
public int CompareTo(object obj)
{
return ((PlayerState)obj).m_KillPoints - m_KillPoints;
}
}
}

View File

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

View File

@@ -0,0 +1,38 @@
using System;
namespace Server.Factions
{
public class SilverGivenEntry
{
public static readonly TimeSpan ExpirePeriod = TimeSpan.FromHours(3.0);
private readonly Mobile m_GivenTo;
private readonly DateTime m_TimeOfGift;
public SilverGivenEntry(Mobile givenTo)
{
this.m_GivenTo = givenTo;
this.m_TimeOfGift = DateTime.UtcNow;
}
public Mobile GivenTo
{
get
{
return this.m_GivenTo;
}
}
public DateTime TimeOfGift
{
get
{
return this.m_TimeOfGift;
}
}
public bool IsExpired
{
get
{
return (this.m_TimeOfGift + ExpirePeriod) < DateTime.UtcNow;
}
}
}
}

View File

@@ -0,0 +1,45 @@
using System;
using Server.Mobiles;
using Server.Regions;
namespace Server.Factions
{
public class StrongholdRegion : BaseRegion
{
private Faction m_Faction;
public StrongholdRegion(Faction faction)
: base(faction.Definition.FriendlyName, Faction.Facet, Region.DefaultPriority, faction.Definition.Stronghold.Area)
{
this.m_Faction = faction;
this.Register();
}
public Faction Faction
{
get
{
return this.m_Faction;
}
set
{
this.m_Faction = value;
}
}
public override bool OnMoveInto(Mobile m, Direction d, Point3D newLocation, Point3D oldLocation)
{
if (!base.OnMoveInto(m, d, newLocation, oldLocation))
return false;
if (m.IsStaff() || this.Contains(oldLocation))
return true;
return (Faction.Find(m, true, true) != null);
}
public override bool AllowHousing(Mobile from, Point3D p)
{
return false;
}
}
}

View File

@@ -0,0 +1,611 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Server.Commands;
using Server.Targeting;
namespace Server.Factions
{
[CustomEnum(new string[] { "Britain", "Magincia", "Minoc", "Moonglow", "Skara Brae", "Trinsic", "Vesper", "Yew" })]
public abstract class Town : IComparable
{
public static readonly TimeSpan TaxChangePeriod = TimeSpan.FromHours(12.0);
public static readonly TimeSpan IncomePeriod = TimeSpan.FromDays(1.0);
public const int SilverCaptureBonus = 10000;
private TownDefinition m_Definition;
private TownState m_State;
private Timer m_IncomeTimer;
private List<VendorList> m_VendorLists;
private List<GuardList> m_GuardLists;
public Town()
{
this.m_State = new TownState(this);
this.ConstructVendorLists();
this.ConstructGuardLists();
this.StartIncomeTimer();
}
public static List<Town> Towns
{
get
{
return Reflector.Towns;
}
}
public TownDefinition Definition
{
get
{
return this.m_Definition;
}
set
{
this.m_Definition = value;
}
}
public TownState State
{
get
{
return this.m_State;
}
set
{
this.m_State = value;
this.ConstructGuardLists();
}
}
public int Silver
{
get
{
return this.m_State.Silver;
}
set
{
this.m_State.Silver = value;
}
}
public Faction Owner
{
get
{
return this.m_State.Owner;
}
set
{
this.Capture(value);
}
}
public Mobile Sheriff
{
get
{
return this.m_State.Sheriff;
}
set
{
this.m_State.Sheriff = value;
}
}
public Mobile Finance
{
get
{
return this.m_State.Finance;
}
set
{
this.m_State.Finance = value;
}
}
public int Tax
{
get
{
return this.m_State.Tax;
}
set
{
this.m_State.Tax = value;
}
}
public DateTime LastTaxChange
{
get
{
return this.m_State.LastTaxChange;
}
set
{
this.m_State.LastTaxChange = value;
}
}
public bool TaxChangeReady
{
get
{
return (this.m_State.LastTaxChange + TaxChangePeriod) < DateTime.UtcNow;
}
}
public int FinanceUpkeep
{
get
{
List<VendorList> vendorLists = this.VendorLists;
int upkeep = 0;
for (int i = 0; i < vendorLists.Count; ++i)
upkeep += vendorLists[i].Vendors.Count * vendorLists[i].Definition.Upkeep;
return upkeep;
}
}
public int SheriffUpkeep
{
get
{
List<GuardList> guardLists = this.GuardLists;
int upkeep = 0;
for (int i = 0; i < guardLists.Count; ++i)
upkeep += guardLists[i].Guards.Count * guardLists[i].Definition.Upkeep;
return upkeep;
}
}
public int DailyIncome
{
get
{
return (10000 * (100 + this.m_State.Tax)) / 100;
}
}
public int NetCashFlow
{
get
{
return this.DailyIncome - this.FinanceUpkeep - this.SheriffUpkeep;
}
}
public TownMonolith Monolith
{
get
{
List<BaseMonolith> monoliths = BaseMonolith.Monoliths;
foreach (BaseMonolith monolith in monoliths)
{
if (monolith is TownMonolith)
{
TownMonolith townMonolith = (TownMonolith)monolith;
if (townMonolith.Town == this)
return townMonolith;
}
}
return null;
}
}
public DateTime LastIncome
{
get
{
return this.m_State.LastIncome;
}
set
{
this.m_State.LastIncome = value;
}
}
public List<VendorList> VendorLists
{
get
{
return this.m_VendorLists;
}
set
{
this.m_VendorLists = value;
}
}
public List<GuardList> GuardLists
{
get
{
return this.m_GuardLists;
}
set
{
this.m_GuardLists = value;
}
}
public static Town FromRegion(Region reg)
{
if (reg.Map != Faction.Facet)
return null;
List<Town> towns = Towns;
for (int i = 0; i < towns.Count; ++i)
{
Town town = towns[i];
if (reg.IsPartOf(town.Definition.Region))
return town;
}
return null;
}
public static void Initialize()
{
List<Town> towns = Towns;
for (int i = 0; i < towns.Count; ++i)
{
towns[i].Sheriff = towns[i].Sheriff;
towns[i].Finance = towns[i].Finance;
}
CommandSystem.Register("GrantTownSilver", AccessLevel.Administrator, new CommandEventHandler(GrantTownSilver_OnCommand));
}
public static void WriteReference(GenericWriter writer, Town town)
{
int idx = Towns.IndexOf(town);
writer.WriteEncodedInt((int)(idx + 1));
}
public static Town ReadReference(GenericReader reader)
{
int idx = reader.ReadEncodedInt() - 1;
if (idx >= 0 && idx < Towns.Count)
return Towns[idx];
return null;
}
public static Town Parse(string name)
{
List<Town> towns = Towns;
for (int i = 0; i < towns.Count; ++i)
{
Town town = towns[i];
if (Insensitive.Equals(town.Definition.FriendlyName, name))
return town;
}
return null;
}
public static void GrantTownSilver_OnCommand(CommandEventArgs e)
{
Town town = FromRegion(e.Mobile.Region);
if (town == null)
e.Mobile.SendMessage("You are not in a faction town.");
else if (e.Length == 0)
e.Mobile.SendMessage("Format: GrantTownSilver <amount>");
else
{
town.Silver += e.GetInt32(0);
e.Mobile.SendMessage("You have granted {0:N0} silver to the town. It now has {1:N0} silver.", e.GetInt32(0), town.Silver);
}
}
public void BeginOrderFiring(Mobile from)
{
bool isFinance = this.IsFinance(from);
bool isSheriff = this.IsSheriff(from);
string type = null;
// NOTE: Messages not OSI-accurate, intentional
if (isFinance && isSheriff) // GM only
type = "vendor or guard";
else if (isFinance)
type = "vendor";
else if (isSheriff)
type = "guard";
from.SendMessage("Target the {0} you wish to dismiss.", type);
from.BeginTarget(12, false, TargetFlags.None, new TargetCallback(EndOrderFiring));
}
public void EndOrderFiring(Mobile from, object obj)
{
bool isFinance = this.IsFinance(from);
bool isSheriff = this.IsSheriff(from);
string type = null;
if (isFinance && isSheriff) // GM only
type = "vendor or guard";
else if (isFinance)
type = "vendor";
else if (isSheriff)
type = "guard";
if (obj is BaseFactionVendor)
{
BaseFactionVendor vendor = (BaseFactionVendor)obj;
if (vendor.Town == this && isFinance)
vendor.Delete();
}
else if (obj is BaseFactionGuard)
{
BaseFactionGuard guard = (BaseFactionGuard)obj;
if (guard.Town == this && isSheriff)
guard.Delete();
}
else
{
from.SendMessage("That is not a {0}!", type);
}
}
public void StartIncomeTimer()
{
if (this.m_IncomeTimer != null)
this.m_IncomeTimer.Stop();
this.m_IncomeTimer = Timer.DelayCall(TimeSpan.FromMinutes(1.0), TimeSpan.FromMinutes(1.0), new TimerCallback(CheckIncome));
}
public void StopIncomeTimer()
{
if (this.m_IncomeTimer != null)
this.m_IncomeTimer.Stop();
this.m_IncomeTimer = null;
}
public void CheckIncome()
{
if ((this.LastIncome + IncomePeriod) > DateTime.UtcNow || this.Owner == null)
return;
this.ProcessIncome();
}
public void ProcessIncome()
{
this.LastIncome = DateTime.UtcNow;
int flow = this.NetCashFlow;
if ((this.Silver + flow) < 0)
{
ArrayList toDelete = this.BuildFinanceList();
while ((this.Silver + flow) < 0 && toDelete.Count > 0)
{
int index = Utility.Random(toDelete.Count);
Mobile mob = (Mobile)toDelete[index];
mob.Delete();
toDelete.RemoveAt(index);
flow = this.NetCashFlow;
}
}
this.Silver += flow;
}
public ArrayList BuildFinanceList()
{
ArrayList list = new ArrayList();
List<VendorList> vendorLists = this.VendorLists;
for (int i = 0; i < vendorLists.Count; ++i)
list.AddRange(vendorLists[i].Vendors);
List<GuardList> guardLists = this.GuardLists;
for (int i = 0; i < guardLists.Count; ++i)
list.AddRange(guardLists[i].Guards);
return list;
}
public void ConstructGuardLists()
{
GuardDefinition[] defs = (this.Owner == null ? new GuardDefinition[0] : this.Owner.Definition.Guards);
this.m_GuardLists = new List<GuardList>();
for (int i = 0; i < defs.Length; ++i)
this.m_GuardLists.Add(new GuardList(defs[i]));
}
public GuardList FindGuardList(Type type)
{
List<GuardList> guardLists = this.GuardLists;
for (int i = 0; i < guardLists.Count; ++i)
{
GuardList guardList = guardLists[i];
if (guardList.Definition.Type == type)
return guardList;
}
return null;
}
public void ConstructVendorLists()
{
VendorDefinition[] defs = VendorDefinition.Definitions;
this.m_VendorLists = new List<VendorList>();
for (int i = 0; i < defs.Length; ++i)
this.m_VendorLists.Add(new VendorList(defs[i]));
}
public VendorList FindVendorList(Type type)
{
List<VendorList> vendorLists = this.VendorLists;
for (int i = 0; i < vendorLists.Count; ++i)
{
VendorList vendorList = vendorLists[i];
if (vendorList.Definition.Type == type)
return vendorList;
}
return null;
}
public bool RegisterGuard(BaseFactionGuard guard)
{
if (guard == null)
return false;
GuardList guardList = this.FindGuardList(guard.GetType());
if (guardList == null)
return false;
guardList.Guards.Add(guard);
return true;
}
public bool UnregisterGuard(BaseFactionGuard guard)
{
if (guard == null)
return false;
GuardList guardList = this.FindGuardList(guard.GetType());
if (guardList == null)
return false;
if (!guardList.Guards.Contains(guard))
return false;
guardList.Guards.Remove(guard);
return true;
}
public bool RegisterVendor(BaseFactionVendor vendor)
{
if (vendor == null)
return false;
VendorList vendorList = this.FindVendorList(vendor.GetType());
if (vendorList == null)
return false;
vendorList.Vendors.Add(vendor);
return true;
}
public bool UnregisterVendor(BaseFactionVendor vendor)
{
if (vendor == null)
return false;
VendorList vendorList = this.FindVendorList(vendor.GetType());
if (vendorList == null)
return false;
if (!vendorList.Vendors.Contains(vendor))
return false;
vendorList.Vendors.Remove(vendor);
return true;
}
public bool IsSheriff(Mobile mob)
{
if (mob == null || mob.Deleted)
return false;
return (mob.AccessLevel >= AccessLevel.GameMaster || mob == this.Sheriff);
}
public bool IsFinance(Mobile mob)
{
if (mob == null || mob.Deleted)
return false;
return (mob.AccessLevel >= AccessLevel.GameMaster || mob == this.Finance);
}
public void Capture(Faction f)
{
if (this.m_State.Owner == f)
return;
if (this.m_State.Owner == null) // going from unowned to owned
{
this.LastIncome = DateTime.UtcNow;
f.Silver += SilverCaptureBonus;
}
else if (f == null) // going from owned to unowned
{
this.LastIncome = DateTime.MinValue;
}
else // otherwise changing hands, income timer doesn't change
{
f.Silver += SilverCaptureBonus;
}
this.m_State.Owner = f;
this.Sheriff = null;
this.Finance = null;
TownMonolith monolith = this.Monolith;
if (monolith != null)
monolith.Faction = f;
List<VendorList> vendorLists = this.VendorLists;
for (int i = 0; i < vendorLists.Count; ++i)
{
VendorList vendorList = vendorLists[i];
List<BaseFactionVendor> vendors = vendorList.Vendors;
for (int j = vendors.Count - 1; j >= 0; --j)
vendors[j].Delete();
}
List<GuardList> guardLists = this.GuardLists;
for (int i = 0; i < guardLists.Count; ++i)
{
GuardList guardList = guardLists[i];
List<BaseFactionGuard> guards = guardList.Guards;
for (int j = guards.Count - 1; j >= 0; --j)
guards[j].Delete();
}
this.ConstructGuardLists();
}
public int CompareTo(object obj)
{
return this.m_Definition.Sort - ((Town)obj).m_Definition.Sort;
}
public override string ToString()
{
return this.m_Definition.FriendlyName;
}
}
}

View File

@@ -0,0 +1,198 @@
using System;
namespace Server.Factions
{
public class TownState
{
private Town m_Town;
private Faction m_Owner;
private Mobile m_Sheriff;
private Mobile m_Finance;
private int m_Silver;
private int m_Tax;
private DateTime m_LastTaxChange;
private DateTime m_LastIncome;
public TownState(Town town)
{
this.m_Town = town;
}
public TownState(GenericReader reader)
{
int version = reader.ReadEncodedInt();
switch ( version )
{
case 3:
{
this.m_LastIncome = reader.ReadDateTime();
goto case 2;
}
case 2:
{
this.m_Tax = reader.ReadEncodedInt();
this.m_LastTaxChange = reader.ReadDateTime();
goto case 1;
}
case 1:
{
this.m_Silver = reader.ReadEncodedInt();
goto case 0;
}
case 0:
{
this.m_Town = Town.ReadReference(reader);
this.m_Owner = Faction.ReadReference(reader);
this.m_Sheriff = reader.ReadMobile();
this.m_Finance = reader.ReadMobile();
this.m_Town.State = this;
break;
}
}
}
public Town Town
{
get
{
return this.m_Town;
}
set
{
this.m_Town = value;
}
}
public Faction Owner
{
get
{
return this.m_Owner;
}
set
{
this.m_Owner = value;
}
}
public Mobile Sheriff
{
get
{
return this.m_Sheriff;
}
set
{
if (this.m_Sheriff != null)
{
PlayerState pl = PlayerState.Find(this.m_Sheriff);
if (pl != null)
pl.Sheriff = null;
}
this.m_Sheriff = value;
if (this.m_Sheriff != null)
{
PlayerState pl = PlayerState.Find(this.m_Sheriff);
if (pl != null)
pl.Sheriff = this.m_Town;
}
}
}
public Mobile Finance
{
get
{
return this.m_Finance;
}
set
{
if (this.m_Finance != null)
{
PlayerState pl = PlayerState.Find(this.m_Finance);
if (pl != null)
pl.Finance = null;
}
this.m_Finance = value;
if (this.m_Finance != null)
{
PlayerState pl = PlayerState.Find(this.m_Finance);
if (pl != null)
pl.Finance = this.m_Town;
}
}
}
public int Silver
{
get
{
return this.m_Silver;
}
set
{
this.m_Silver = value;
}
}
public int Tax
{
get
{
return this.m_Tax;
}
set
{
this.m_Tax = value;
}
}
public DateTime LastTaxChange
{
get
{
return this.m_LastTaxChange;
}
set
{
this.m_LastTaxChange = value;
}
}
public DateTime LastIncome
{
get
{
return this.m_LastIncome;
}
set
{
this.m_LastIncome = value;
}
}
public void Serialize(GenericWriter writer)
{
writer.WriteEncodedInt((int)3); // version
writer.Write((DateTime)this.m_LastIncome);
writer.WriteEncodedInt((int)this.m_Tax);
writer.Write((DateTime)this.m_LastTaxChange);
writer.WriteEncodedInt((int)this.m_Silver);
Town.WriteReference(writer, this.m_Town);
Faction.WriteReference(writer, this.m_Owner);
writer.Write((Mobile)this.m_Sheriff);
writer.Write((Mobile)this.m_Finance);
}
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
namespace Server.Factions
{
public class VendorList
{
private readonly VendorDefinition m_Definition;
private readonly List<BaseFactionVendor> m_Vendors;
public VendorList(VendorDefinition definition)
{
this.m_Definition = definition;
this.m_Vendors = new List<BaseFactionVendor>();
}
public VendorDefinition Definition
{
get
{
return this.m_Definition;
}
}
public List<BaseFactionVendor> Vendors
{
get
{
return this.m_Vendors;
}
}
public BaseFactionVendor Construct(Town town, Faction faction)
{
try
{
return Activator.CreateInstance(this.m_Definition.Type, new object[] { town, faction }) as BaseFactionVendor;
}
catch
{
return null;
}
}
}
}