#W# Source and Scripts added. Added Scripts/Settings.cs to expose some basic tweak able settings.
This commit is contained in:
parent
b51c58f514
commit
3045c83799
3512 changed files with 627673 additions and 0 deletions
564
Scripts/Engines/Factions/Core/Election.cs
Normal file
564
Scripts/Engines/Factions/Core/Election.cs
Normal file
|
|
@ -0,0 +1,564 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
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 List<Candidate> m_Candidates;
|
||||
|
||||
private ElectionState m_State;
|
||||
private DateTime m_LastStateTime;
|
||||
|
||||
public Faction Faction{ get{ return m_Faction; } }
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
private Timer m_Timer;
|
||||
|
||||
public void StartTimer()
|
||||
{
|
||||
m_Timer = Timer.DelayCall( TimeSpan.FromMinutes( 1.0 ), TimeSpan.FromMinutes( 1.0 ), new TimerCallback( Slice ) );
|
||||
}
|
||||
|
||||
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 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.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 Mobile m_From;
|
||||
private Mobile m_Candidate;
|
||||
|
||||
private IPAddress m_Address;
|
||||
private DateTime m_Time;
|
||||
|
||||
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 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 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 Mobile m_Mobile;
|
||||
private List<Voter> m_Voters;
|
||||
|
||||
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 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 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 );
|
||||
}
|
||||
}
|
||||
|
||||
public enum ElectionState
|
||||
{
|
||||
Pending,
|
||||
Campaign,
|
||||
Election
|
||||
}
|
||||
}
|
||||
1437
Scripts/Engines/Factions/Core/Faction.cs
Normal file
1437
Scripts/Engines/Factions/Core/Faction.cs
Normal file
File diff suppressed because it is too large
Load diff
146
Scripts/Engines/Factions/Core/FactionItem.cs
Normal file
146
Scripts/Engines/Factions/Core/FactionItem.cs
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
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 Item m_Item;
|
||||
private Faction m_Faction;
|
||||
private DateTime m_Expiration;
|
||||
|
||||
public Item Item{ get{ return m_Item; } }
|
||||
public Faction Faction{ get{ return m_Faction; } }
|
||||
public DateTime Expiration{ get{ return m_Expiration; } }
|
||||
|
||||
public bool HasExpired
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_Item == null || m_Item.Deleted )
|
||||
return true;
|
||||
|
||||
return ( m_Expiration != DateTime.MinValue && DateTime.UtcNow >= m_Expiration );
|
||||
}
|
||||
}
|
||||
|
||||
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 FactionItem( Item item, Faction faction )
|
||||
{
|
||||
m_Item = item;
|
||||
m_Faction = faction;
|
||||
}
|
||||
|
||||
public FactionItem( GenericReader reader, Faction faction )
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
m_Item = reader.ReadItem();
|
||||
m_Expiration = reader.ReadDateTime();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_Faction = faction;
|
||||
}
|
||||
|
||||
public void Serialize( GenericWriter writer )
|
||||
{
|
||||
writer.WriteEncodedInt( (int) 0 );
|
||||
|
||||
writer.Write( (Item) m_Item );
|
||||
writer.Write( (DateTime) 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 )
|
||||
{
|
||||
if ( !(item is IFactionItem) )
|
||||
return item;
|
||||
|
||||
FactionItem state = Find( item );
|
||||
|
||||
if ( state == null )
|
||||
{
|
||||
state = new FactionItem( item, faction );
|
||||
state.Attach();
|
||||
}
|
||||
|
||||
if ( expire )
|
||||
state.StartExpiration();
|
||||
|
||||
item.Hue = hue;
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
312
Scripts/Engines/Factions/Core/FactionState.cs
Normal file
312
Scripts/Engines/Factions/Core/FactionState.cs
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionState
|
||||
{
|
||||
private Faction m_Faction;
|
||||
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;
|
||||
|
||||
private const int BroadcastsPerPeriod = 2;
|
||||
private static readonly TimeSpan BroadcastPeriod = TimeSpan.FromHours( 1.0 );
|
||||
|
||||
private DateTime[] m_LastBroadcasts = new DateTime[BroadcastsPerPeriod];
|
||||
|
||||
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 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 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 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 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:
|
||||
{
|
||||
m_Election = new Election( reader );
|
||||
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
m_Faction = Faction.ReadReference( reader );
|
||||
|
||||
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 )
|
||||
m_Members.Add( pl );
|
||||
}
|
||||
|
||||
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 );
|
||||
|
||||
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() )
|
||||
m_FactionTraps.Add( trap );
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( version < 1 )
|
||||
m_Election = new Election( m_Faction );
|
||||
}
|
||||
|
||||
public void Serialize( GenericWriter writer )
|
||||
{
|
||||
writer.WriteEncodedInt( (int) 5 ); // 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] );
|
||||
}
|
||||
}
|
||||
}
|
||||
80
Scripts/Engines/Factions/Core/Generator.cs
Normal file
80
Scripts/Engines/Factions/Core/Generator.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
using System;
|
||||
using Server.Commands;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class Generator
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
CommandSystem.Register( "GenerateFactions", AccessLevel.Administrator, new CommandEventHandler( GenerateFactions_OnCommand ) );
|
||||
}
|
||||
|
||||
public static void GenerateFactions_OnCommand( CommandEventArgs e )
|
||||
{
|
||||
new FactionPersistance();
|
||||
|
||||
List<Faction> factions = Faction.Factions;
|
||||
|
||||
foreach ( Faction faction in factions )
|
||||
Generate( faction );
|
||||
|
||||
List<Town> towns = Town.Towns;
|
||||
|
||||
foreach ( Town town in towns )
|
||||
Generate( town );
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
if ( !CheckExistance( def.TownStone, facet, typeof( TownStone ) ) )
|
||||
new TownStone( town ).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 ) ) )
|
||||
new JoinStone( faction ).MoveToWorld( stronghold.JoinStone, facet );
|
||||
|
||||
if ( !CheckExistance( stronghold.FactionStone, facet, typeof( FactionStone ) ) )
|
||||
new FactionStone( faction ).MoveToWorld( stronghold.FactionStone, facet );
|
||||
|
||||
for ( int i = 0; i < stronghold.Monoliths.Length; ++i )
|
||||
{
|
||||
Point3D monolith = stronghold.Monoliths[i];
|
||||
|
||||
if ( !CheckExistance( monolith, facet, typeof( StrongholdMonolith ) ) )
|
||||
new StrongholdMonolith( towns[i], faction ).MoveToWorld( monolith, 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Scripts/Engines/Factions/Core/GuardList.cs
Normal file
27
Scripts/Engines/Factions/Core/GuardList.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using Server;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class GuardList
|
||||
{
|
||||
private GuardDefinition m_Definition;
|
||||
private List<BaseFactionGuard> m_Guards;
|
||||
|
||||
public GuardDefinition Definition{ get{ return m_Definition; } }
|
||||
public List<BaseFactionGuard> Guards{ get{ return m_Guards; } }
|
||||
|
||||
public BaseFactionGuard Construct()
|
||||
{
|
||||
try{ return Activator.CreateInstance( m_Definition.Type ) as BaseFactionGuard; }
|
||||
catch{ return null; }
|
||||
}
|
||||
|
||||
public GuardList( GuardDefinition definition )
|
||||
{
|
||||
m_Definition = definition;
|
||||
m_Guards = new List<BaseFactionGuard>();
|
||||
}
|
||||
}
|
||||
}
|
||||
159
Scripts/Engines/Factions/Core/Keywords.cs
Normal file
159
Scripts/Engines/Factions/Core/Keywords.cs
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using Server.Network;
|
||||
using Server.Factions;
|
||||
using Server.Mobiles;
|
||||
|
||||
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.AccessLevel == AccessLevel.Player && !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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
87
Scripts/Engines/Factions/Core/MerchantTitles.cs
Normal file
87
Scripts/Engines/Factions/Core/MerchantTitles.cs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public enum MerchantTitle
|
||||
{
|
||||
None,
|
||||
Scribe,
|
||||
Carpenter,
|
||||
Blacksmith,
|
||||
Bowyer,
|
||||
Tialor
|
||||
}
|
||||
|
||||
public class MerchantTitleInfo
|
||||
{
|
||||
private SkillName m_Skill;
|
||||
private double m_Requirement;
|
||||
private TextDefinition m_Title;
|
||||
private TextDefinition m_Label;
|
||||
private TextDefinition m_Assigned;
|
||||
|
||||
public SkillName Skill{ get{ return m_Skill; } }
|
||||
public double Requirement{ get{ return m_Requirement; } }
|
||||
public TextDefinition Title{ get{ return m_Title; } }
|
||||
public TextDefinition Label{ get{ return m_Label; } }
|
||||
public TextDefinition Assigned{ get{ return m_Assigned; } }
|
||||
|
||||
public MerchantTitleInfo( SkillName skill, double requirement, TextDefinition title, TextDefinition label, TextDefinition assigned )
|
||||
{
|
||||
m_Skill = skill;
|
||||
m_Requirement = requirement;
|
||||
m_Title = title;
|
||||
m_Label = label;
|
||||
m_Assigned = assigned;
|
||||
}
|
||||
}
|
||||
|
||||
public class MerchantTitles
|
||||
{
|
||||
private static 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
94
Scripts/Engines/Factions/Core/Persistance.cs
Normal file
94
Scripts/Engines/Factions/Core/Persistance.cs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class FactionPersistance : Item
|
||||
{
|
||||
private static FactionPersistance m_Instance;
|
||||
|
||||
public static FactionPersistance Instance{ get{ return m_Instance; } }
|
||||
|
||||
public override string DefaultName
|
||||
{
|
||||
get { return "Faction Persistance - Internal"; }
|
||||
}
|
||||
|
||||
public FactionPersistance() : base( 1 )
|
||||
{
|
||||
Movable = false;
|
||||
|
||||
if ( m_Instance == null || m_Instance.Deleted )
|
||||
m_Instance = this;
|
||||
else
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
private enum PersistedType
|
||||
{
|
||||
Terminator,
|
||||
Faction,
|
||||
Town
|
||||
}
|
||||
|
||||
public FactionPersistance( Serial serial ) : base( serial )
|
||||
{
|
||||
m_Instance = this;
|
||||
}
|
||||
|
||||
public override void Serialize( GenericWriter writer )
|
||||
{
|
||||
base.Serialize( writer );
|
||||
|
||||
writer.Write( (int) 0 ); // 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 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
255
Scripts/Engines/Factions/Core/PlayerState.cs
Normal file
255
Scripts/Engines/Factions/Core/PlayerState.cs
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class PlayerState : IComparable
|
||||
{
|
||||
private Mobile m_Mobile;
|
||||
private Faction m_Faction;
|
||||
private 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;
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool m_InvalidateRank = true;
|
||||
private int m_RankIndex = -1;
|
||||
|
||||
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 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();
|
||||
pm.InvalidateMyRunUO();
|
||||
}
|
||||
}
|
||||
|
||||
public void Attach()
|
||||
{
|
||||
if ( m_Mobile is PlayerMobile )
|
||||
((PlayerMobile)m_Mobile).FactionPlayerState = this;
|
||||
}
|
||||
|
||||
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 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 static PlayerState Find( Mobile mob )
|
||||
{
|
||||
if ( mob is PlayerMobile )
|
||||
return ((PlayerMobile)mob).FactionPlayerState;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public int CompareTo( object obj )
|
||||
{
|
||||
return ((PlayerState)obj).m_KillPoints - m_KillPoints;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
Scripts/Engines/Factions/Core/Reflector.cs
Normal file
78
Scripts/Engines/Factions/Core/Reflector.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class Reflector
|
||||
{
|
||||
private static List<Town> m_Towns;
|
||||
|
||||
public static List<Town> Towns
|
||||
{
|
||||
get
|
||||
{
|
||||
if ( m_Towns == null )
|
||||
ProcessTypes();
|
||||
|
||||
return m_Towns;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<Faction> m_Factions;
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Scripts/Engines/Factions/Core/SilverGivenEntry.cs
Normal file
23
Scripts/Engines/Factions/Core/SilverGivenEntry.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class SilverGivenEntry
|
||||
{
|
||||
public static readonly TimeSpan ExpirePeriod = TimeSpan.FromHours( 3.0 );
|
||||
|
||||
private Mobile m_GivenTo;
|
||||
private DateTime m_TimeOfGift;
|
||||
|
||||
public Mobile GivenTo{ get{ return m_GivenTo; } }
|
||||
public DateTime TimeOfGift{ get{ return m_TimeOfGift; } }
|
||||
|
||||
public bool IsExpired{ get{ return ( m_TimeOfGift + ExpirePeriod ) < DateTime.UtcNow; } }
|
||||
|
||||
public SilverGivenEntry( Mobile givenTo )
|
||||
{
|
||||
m_GivenTo = givenTo;
|
||||
m_TimeOfGift = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
51
Scripts/Engines/Factions/Core/StrongholdRegion.cs
Normal file
51
Scripts/Engines/Factions/Core/StrongholdRegion.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class StrongholdRegion : BaseRegion
|
||||
{
|
||||
private Faction m_Faction;
|
||||
|
||||
public Faction Faction
|
||||
{
|
||||
get{ return m_Faction; }
|
||||
set{ m_Faction = value; }
|
||||
}
|
||||
|
||||
public StrongholdRegion( Faction faction ) : base( faction.Definition.FriendlyName, Faction.Facet, Region.DefaultPriority, faction.Definition.Stronghold.Area )
|
||||
{
|
||||
m_Faction = faction;
|
||||
|
||||
Register();
|
||||
}
|
||||
|
||||
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 ) {
|
||||
PlayerMobile pm = (PlayerMobile)m;
|
||||
|
||||
if ( pm.DuelContext != null ) {
|
||||
m.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 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
554
Scripts/Engines/Factions/Core/Town.cs
Normal file
554
Scripts/Engines/Factions/Core/Town.cs
Normal file
|
|
@ -0,0 +1,554 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using Server;
|
||||
using Server.Targeting;
|
||||
using Server.Mobiles;
|
||||
using Server.Commands;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
[CustomEnum( new string[]{ "Britain", "Magincia", "Minoc", "Moonglow", "Skara Brae", "Trinsic", "Vesper", "Yew" } )]
|
||||
public abstract class Town : IComparable
|
||||
{
|
||||
private TownDefinition m_Definition;
|
||||
private TownState m_State;
|
||||
|
||||
public TownDefinition Definition
|
||||
{
|
||||
get{ return m_Definition; }
|
||||
set{ m_Definition = value; }
|
||||
}
|
||||
|
||||
public TownState State
|
||||
{
|
||||
get{ return m_State; }
|
||||
set{ m_State = value; ConstructGuardLists(); }
|
||||
}
|
||||
|
||||
public int Silver
|
||||
{
|
||||
get{ return m_State.Silver; }
|
||||
set{ m_State.Silver = value; }
|
||||
}
|
||||
|
||||
public Faction Owner
|
||||
{
|
||||
get{ return m_State.Owner; }
|
||||
set{ Capture( value ); }
|
||||
}
|
||||
|
||||
public Mobile Sheriff
|
||||
{
|
||||
get{ return m_State.Sheriff; }
|
||||
set{ m_State.Sheriff = value; }
|
||||
}
|
||||
|
||||
public Mobile Finance
|
||||
{
|
||||
get{ return m_State.Finance; }
|
||||
set{ m_State.Finance = value; }
|
||||
}
|
||||
|
||||
public int Tax
|
||||
{
|
||||
get{ return m_State.Tax; }
|
||||
set{ m_State.Tax = value; }
|
||||
}
|
||||
|
||||
public DateTime LastTaxChange
|
||||
{
|
||||
get{ return m_State.LastTaxChange; }
|
||||
set{ m_State.LastTaxChange = value; }
|
||||
}
|
||||
|
||||
public static readonly TimeSpan TaxChangePeriod = TimeSpan.FromHours( 12.0 );
|
||||
public static readonly TimeSpan IncomePeriod = TimeSpan.FromDays( 1.0 );
|
||||
|
||||
public bool TaxChangeReady
|
||||
{
|
||||
get{ return ( m_State.LastTaxChange + TaxChangePeriod ) < DateTime.UtcNow; }
|
||||
}
|
||||
|
||||
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 int FinanceUpkeep
|
||||
{
|
||||
get
|
||||
{
|
||||
List<VendorList> vendorLists = 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 = 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 + m_State.Tax)) / 100; }
|
||||
}
|
||||
|
||||
public int NetCashFlow
|
||||
{
|
||||
get{ return DailyIncome - FinanceUpkeep - 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 m_State.LastIncome; }
|
||||
set{ m_State.LastIncome = value; }
|
||||
}
|
||||
|
||||
public void BeginOrderFiring( Mobile from )
|
||||
{
|
||||
bool isFinance = IsFinance( from );
|
||||
bool isSheriff = 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 = IsFinance( from );
|
||||
bool isSheriff = 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 );
|
||||
}
|
||||
}
|
||||
|
||||
private Timer m_IncomeTimer;
|
||||
|
||||
public void StartIncomeTimer()
|
||||
{
|
||||
if ( m_IncomeTimer != null )
|
||||
m_IncomeTimer.Stop();
|
||||
|
||||
m_IncomeTimer = Timer.DelayCall( TimeSpan.FromMinutes( 1.0 ), TimeSpan.FromMinutes( 1.0 ), new TimerCallback( CheckIncome ) );
|
||||
}
|
||||
|
||||
public void StopIncomeTimer()
|
||||
{
|
||||
if ( m_IncomeTimer != null )
|
||||
m_IncomeTimer.Stop();
|
||||
|
||||
m_IncomeTimer = null;
|
||||
}
|
||||
|
||||
public void CheckIncome()
|
||||
{
|
||||
if ( (LastIncome + IncomePeriod) > DateTime.UtcNow || Owner == null )
|
||||
return;
|
||||
|
||||
ProcessIncome();
|
||||
}
|
||||
|
||||
public void ProcessIncome()
|
||||
{
|
||||
LastIncome = DateTime.UtcNow;
|
||||
|
||||
int flow = NetCashFlow;
|
||||
|
||||
if ( (Silver + flow) < 0 )
|
||||
{
|
||||
ArrayList toDelete = BuildFinanceList();
|
||||
|
||||
while ( (Silver + flow) < 0 && toDelete.Count > 0 )
|
||||
{
|
||||
int index = Utility.Random( toDelete.Count );
|
||||
Mobile mob = (Mobile)toDelete[index];
|
||||
|
||||
mob.Delete();
|
||||
|
||||
toDelete.RemoveAt( index );
|
||||
flow = NetCashFlow;
|
||||
}
|
||||
}
|
||||
|
||||
Silver += flow;
|
||||
}
|
||||
|
||||
public ArrayList BuildFinanceList()
|
||||
{
|
||||
ArrayList list = new ArrayList();
|
||||
|
||||
List<VendorList> vendorLists = VendorLists;
|
||||
|
||||
for ( int i = 0; i < vendorLists.Count; ++i )
|
||||
list.AddRange( vendorLists[i].Vendors );
|
||||
|
||||
List<GuardList> guardLists = GuardLists;
|
||||
|
||||
for ( int i = 0; i < guardLists.Count; ++i )
|
||||
list.AddRange( guardLists[i].Guards );
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private List<VendorList> m_VendorLists;
|
||||
private List<GuardList> m_GuardLists;
|
||||
|
||||
public List<VendorList> VendorLists
|
||||
{
|
||||
get{ return m_VendorLists; }
|
||||
set{ m_VendorLists = value; }
|
||||
}
|
||||
|
||||
public List<GuardList> GuardLists
|
||||
{
|
||||
get{ return m_GuardLists; }
|
||||
set{ m_GuardLists = value; }
|
||||
}
|
||||
|
||||
public void ConstructGuardLists()
|
||||
{
|
||||
GuardDefinition[] defs = ( Owner == null ? new GuardDefinition[0] : Owner.Definition.Guards );
|
||||
|
||||
m_GuardLists = new List<GuardList>();
|
||||
|
||||
for ( int i = 0; i < defs.Length; ++i )
|
||||
m_GuardLists.Add( new GuardList( defs[i] ) );
|
||||
}
|
||||
|
||||
public GuardList FindGuardList( Type type )
|
||||
{
|
||||
List<GuardList> guardLists = 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;
|
||||
|
||||
m_VendorLists = new List<VendorList>();
|
||||
|
||||
for ( int i = 0; i < defs.Length; ++i )
|
||||
m_VendorLists.Add( new VendorList( defs[i] ) );
|
||||
}
|
||||
|
||||
public VendorList FindVendorList( Type type )
|
||||
{
|
||||
List<VendorList> vendorLists = 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 = 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 = 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 = 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 = FindVendorList( vendor.GetType() );
|
||||
|
||||
if ( vendorList == null )
|
||||
return false;
|
||||
|
||||
if ( !vendorList.Vendors.Contains( vendor ) )
|
||||
return false;
|
||||
|
||||
vendorList.Vendors.Remove( vendor );
|
||||
return true;
|
||||
}
|
||||
|
||||
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 Town()
|
||||
{
|
||||
m_State = new TownState( this );
|
||||
ConstructVendorLists();
|
||||
ConstructGuardLists();
|
||||
StartIncomeTimer();
|
||||
}
|
||||
|
||||
public bool IsSheriff( Mobile mob )
|
||||
{
|
||||
if ( mob == null || mob.Deleted )
|
||||
return false;
|
||||
|
||||
return ( mob.AccessLevel >= AccessLevel.GameMaster || mob == Sheriff );
|
||||
}
|
||||
|
||||
public bool IsFinance( Mobile mob )
|
||||
{
|
||||
if ( mob == null || mob.Deleted )
|
||||
return false;
|
||||
|
||||
return ( mob.AccessLevel >= AccessLevel.GameMaster || mob == Finance );
|
||||
}
|
||||
|
||||
public static List<Town> Towns { get { return Reflector.Towns; } }
|
||||
|
||||
public const int SilverCaptureBonus = 10000;
|
||||
|
||||
public void Capture( Faction f )
|
||||
{
|
||||
if ( m_State.Owner == f )
|
||||
return;
|
||||
|
||||
if ( m_State.Owner == null ) // going from unowned to owned
|
||||
{
|
||||
LastIncome = DateTime.UtcNow;
|
||||
f.Silver += SilverCaptureBonus;
|
||||
}
|
||||
else if ( f == null ) // going from owned to unowned
|
||||
{
|
||||
LastIncome = DateTime.MinValue;
|
||||
}
|
||||
else // otherwise changing hands, income timer doesn't change
|
||||
{
|
||||
f.Silver += SilverCaptureBonus;
|
||||
}
|
||||
|
||||
m_State.Owner = f;
|
||||
|
||||
Sheriff = null;
|
||||
Finance = null;
|
||||
|
||||
TownMonolith monolith = this.Monolith;
|
||||
|
||||
if ( monolith != null )
|
||||
monolith.Faction = f;
|
||||
|
||||
List<VendorList> vendorLists = 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 = 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();
|
||||
}
|
||||
|
||||
ConstructGuardLists();
|
||||
}
|
||||
|
||||
public int CompareTo( object obj )
|
||||
{
|
||||
return m_Definition.Sort - ((Town)obj).m_Definition.Sort;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return m_Definition.FriendlyName;
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
168
Scripts/Engines/Factions/Core/TownState.cs
Normal file
168
Scripts/Engines/Factions/Core/TownState.cs
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
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 Town Town
|
||||
{
|
||||
get{ return m_Town; }
|
||||
set{ m_Town = value; }
|
||||
}
|
||||
|
||||
public Faction Owner
|
||||
{
|
||||
get{ return m_Owner; }
|
||||
set{ m_Owner = value; }
|
||||
}
|
||||
|
||||
public Mobile Sheriff
|
||||
{
|
||||
get{ return m_Sheriff; }
|
||||
set
|
||||
{
|
||||
if ( m_Sheriff != null )
|
||||
{
|
||||
PlayerState pl = PlayerState.Find( m_Sheriff );
|
||||
|
||||
if ( pl != null )
|
||||
pl.Sheriff = null;
|
||||
}
|
||||
|
||||
m_Sheriff = value;
|
||||
|
||||
if ( m_Sheriff != null )
|
||||
{
|
||||
PlayerState pl = PlayerState.Find( m_Sheriff );
|
||||
|
||||
if ( pl != null )
|
||||
pl.Sheriff = m_Town;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Mobile Finance
|
||||
{
|
||||
get{ return m_Finance; }
|
||||
set
|
||||
{
|
||||
if ( m_Finance != null )
|
||||
{
|
||||
PlayerState pl = PlayerState.Find( m_Finance );
|
||||
|
||||
if ( pl != null )
|
||||
pl.Finance = null;
|
||||
}
|
||||
|
||||
m_Finance = value;
|
||||
|
||||
if ( m_Finance != null )
|
||||
{
|
||||
PlayerState pl = PlayerState.Find( m_Finance );
|
||||
|
||||
if ( pl != null )
|
||||
pl.Finance = m_Town;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int Silver
|
||||
{
|
||||
get{ return m_Silver; }
|
||||
set{ m_Silver = value; }
|
||||
}
|
||||
|
||||
public int Tax
|
||||
{
|
||||
get{ return m_Tax; }
|
||||
set{ m_Tax = value; }
|
||||
}
|
||||
|
||||
public DateTime LastTaxChange
|
||||
{
|
||||
get{ return m_LastTaxChange; }
|
||||
set{ m_LastTaxChange = value; }
|
||||
}
|
||||
|
||||
public DateTime LastIncome
|
||||
{
|
||||
get{ return m_LastIncome; }
|
||||
set{ m_LastIncome = value; }
|
||||
}
|
||||
|
||||
public TownState( Town town )
|
||||
{
|
||||
m_Town = town;
|
||||
}
|
||||
|
||||
public TownState( GenericReader reader )
|
||||
{
|
||||
int version = reader.ReadEncodedInt();
|
||||
|
||||
switch ( version )
|
||||
{
|
||||
case 3:
|
||||
{
|
||||
m_LastIncome = reader.ReadDateTime();
|
||||
|
||||
goto case 2;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
m_Tax = reader.ReadEncodedInt();
|
||||
m_LastTaxChange = reader.ReadDateTime();
|
||||
|
||||
goto case 1;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
m_Silver = reader.ReadEncodedInt();
|
||||
|
||||
goto case 0;
|
||||
}
|
||||
case 0:
|
||||
{
|
||||
m_Town = Town.ReadReference( reader );
|
||||
m_Owner = Faction.ReadReference( reader );
|
||||
|
||||
m_Sheriff = reader.ReadMobile();
|
||||
m_Finance = reader.ReadMobile();
|
||||
|
||||
m_Town.State = this;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize( GenericWriter writer )
|
||||
{
|
||||
writer.WriteEncodedInt( (int) 3 ); // version
|
||||
|
||||
writer.Write( (DateTime) m_LastIncome );
|
||||
|
||||
writer.WriteEncodedInt( (int) m_Tax );
|
||||
writer.Write( (DateTime) m_LastTaxChange );
|
||||
|
||||
writer.WriteEncodedInt( (int) m_Silver );
|
||||
|
||||
Town.WriteReference( writer, m_Town );
|
||||
Faction.WriteReference( writer, m_Owner );
|
||||
|
||||
writer.Write( (Mobile) m_Sheriff );
|
||||
writer.Write( (Mobile) m_Finance );
|
||||
}
|
||||
}
|
||||
}
|
||||
27
Scripts/Engines/Factions/Core/VendorList.cs
Normal file
27
Scripts/Engines/Factions/Core/VendorList.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using Server;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Factions
|
||||
{
|
||||
public class VendorList
|
||||
{
|
||||
private VendorDefinition m_Definition;
|
||||
private List<BaseFactionVendor> m_Vendors;
|
||||
|
||||
public VendorDefinition Definition{ get{ return m_Definition; } }
|
||||
public List<BaseFactionVendor> Vendors { get { return m_Vendors; } }
|
||||
|
||||
public BaseFactionVendor Construct( Town town, Faction faction )
|
||||
{
|
||||
try{ return Activator.CreateInstance( m_Definition.Type, new object[]{ town, faction } ) as BaseFactionVendor; }
|
||||
catch{ return null; }
|
||||
}
|
||||
|
||||
public VendorList( VendorDefinition definition )
|
||||
{
|
||||
m_Definition = definition;
|
||||
m_Vendors = new List<BaseFactionVendor>();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue