Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
77
Scripts/Services/City Loyalty System/CityDefinition.cs
Normal file
77
Scripts/Services/City Loyalty System/CityDefinition.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.Points;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
[PropertyObject]
|
||||
public class CityDefinition
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public City City { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D StoneLocation { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D TradeMinisterLocation { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D HeraldLocation { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D GuardsmanLocation { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Point3D BoardLocation { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Name { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int LocalizedName { get; private set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int BattleMessage { get; private set; }
|
||||
|
||||
private Region _Region;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Region Region
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_Region == null)
|
||||
{
|
||||
_Region = Region.Regions.FirstOrDefault(r => r.Name == Name && r.Map == CityLoyaltySystem.SystemMap);
|
||||
|
||||
if(_Region == null)
|
||||
Console.WriteLine("WARNING: Region for {0} not found!", Name);
|
||||
}
|
||||
|
||||
return _Region;
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "...";
|
||||
}
|
||||
|
||||
public CityDefinition(City city, Point3D stoneLoc, Point3D tradeloc, Point3D heraldLoc, Point3D guardsmanloc, Point3D boardloc, string name, int locname, int battleloc)
|
||||
{
|
||||
City = city;
|
||||
StoneLocation = stoneLoc;
|
||||
TradeMinisterLocation = tradeloc;
|
||||
HeraldLocation = heraldLoc;
|
||||
GuardsmanLocation = guardsmanloc;
|
||||
BoardLocation = boardloc;
|
||||
Name = name;
|
||||
LocalizedName = locname;
|
||||
BattleMessage = battleloc;
|
||||
}
|
||||
}
|
||||
}
|
||||
191
Scripts/Services/City Loyalty System/CityLoyaltyEntry.cs
Normal file
191
Scripts/Services/City Loyalty System/CityLoyaltyEntry.cs
Normal file
@@ -0,0 +1,191 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Points;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
[PropertyObject]
|
||||
public class CityLoyaltyEntry : PointsEntry
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Love { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Hate { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Neutrality { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CityTitle Titles { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool IsCitizen { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public City City { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string CustomTitle { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool ShowGainMessage { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public LoyaltyRating LoyaltyRating
|
||||
{
|
||||
get
|
||||
{
|
||||
return CityLoyaltySystem.GetCityInstance(City).GetLoyaltyRating(Player, this);
|
||||
}
|
||||
}
|
||||
|
||||
private bool _Utilizing;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool UtilizingTradeDeal
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Utilizing;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (Player == null)
|
||||
return;
|
||||
|
||||
if (!_Utilizing && value)
|
||||
TradeDealExpires = DateTime.UtcNow + TimeSpan.FromHours(CityLoyaltySystem.TradeDealUtilizationPeriod);
|
||||
|
||||
if (_Utilizing && !value)
|
||||
{
|
||||
BuffInfo.RemoveBuff(Player, BuffIcon.CityTradeDeal);
|
||||
|
||||
CityLoyaltySystem.RemoveTradeDeal(Player);
|
||||
|
||||
if (Player.NetState != null)
|
||||
{
|
||||
Player.SendLocalizedMessage(1154074); // The benefit from your City's Trade Deal has expired! Visit the City Stone to reclaim it.
|
||||
}
|
||||
|
||||
Player.Delta(MobileDelta.WeaponDamage);
|
||||
}
|
||||
|
||||
_Utilizing = value;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime TradeDealExpires { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool TradeDealExpired { get { return TradeDealExpires < DateTime.UtcNow; } }
|
||||
|
||||
public CityLoyaltyEntry(PlayerMobile pm, City city) : base(pm)
|
||||
{
|
||||
City = city;
|
||||
ShowGainMessage = true;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format("{0} {1}", City.ToString(), IsCitizen ? "[Citizen]" : String.Empty);
|
||||
}
|
||||
|
||||
public void DeclareCitizenship()
|
||||
{
|
||||
IsCitizen = true;
|
||||
AddTitle(CityTitle.Citizen);
|
||||
}
|
||||
|
||||
public void RenounceCitizenship()
|
||||
{
|
||||
foreach (int i in Enum.GetValues(typeof(CityTitle)))
|
||||
{
|
||||
Player.RemoveRewardTitle(CityLoyaltySystem.GetTitleLocalization(Player, (CityTitle)i, City), true);
|
||||
}
|
||||
|
||||
CustomTitle = null;
|
||||
Player.RemoveRewardTitle(1154017, true);
|
||||
|
||||
IsCitizen = false;
|
||||
Titles = CityTitle.None;
|
||||
}
|
||||
|
||||
public virtual void AddTitle(CityTitle title)
|
||||
{
|
||||
if ((Titles & title) == 0)
|
||||
{
|
||||
int loc = CityLoyaltySystem.GetTitleLocalization(Player, title, City);
|
||||
Player.AddRewardTitle(loc);
|
||||
|
||||
Titles |= title;
|
||||
Player.SendLocalizedMessage(1073625, String.Format("#{0}", loc.ToString())); // The title "~1_TITLE~" has been bestowed upon you.
|
||||
}
|
||||
}
|
||||
|
||||
public void CheckTradeDeal()
|
||||
{
|
||||
if (TradeDealExpired)
|
||||
{
|
||||
UtilizingTradeDeal = false;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(1);
|
||||
|
||||
writer.Write(ShowGainMessage);
|
||||
|
||||
writer.Write(Love);
|
||||
writer.Write(Hate);
|
||||
writer.Write(Neutrality);
|
||||
|
||||
writer.Write((int)Titles);
|
||||
writer.Write(TradeDealExpires);
|
||||
writer.Write(_Utilizing);
|
||||
writer.Write(CustomTitle);
|
||||
|
||||
writer.Write(IsCitizen);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
ShowGainMessage = reader.ReadBool();
|
||||
goto case 0;
|
||||
case 0:
|
||||
{
|
||||
if (version == 0)
|
||||
{
|
||||
ShowGainMessage = true;
|
||||
}
|
||||
|
||||
Love = reader.ReadInt();
|
||||
Hate = reader.ReadInt();
|
||||
Neutrality = reader.ReadInt();
|
||||
|
||||
Titles = (CityTitle)reader.ReadInt();
|
||||
TradeDealExpires = reader.ReadDateTime();
|
||||
_Utilizing = reader.ReadBool();
|
||||
CustomTitle = reader.ReadString();
|
||||
|
||||
CheckTradeDeal();
|
||||
IsCitizen = reader.ReadBool();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1512
Scripts/Services/City Loyalty System/CityLoyaltySystem.cs
Normal file
1512
Scripts/Services/City Loyalty System/CityLoyaltySystem.cs
Normal file
File diff suppressed because it is too large
Load Diff
659
Scripts/Services/City Loyalty System/Election.cs
Normal file
659
Scripts/Services/City Loyalty System/Election.cs
Normal file
@@ -0,0 +1,659 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Items;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Server.Accounting;
|
||||
using System.Linq;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
[PropertyObject]
|
||||
public class CityElection
|
||||
{
|
||||
public static readonly int VotePeriod = 7;
|
||||
public static readonly int NominationDeadline = 24;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CityLoyaltySystem City { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool ElectionEnded { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Ongoing { get { return CanNominate() || CanVote(); } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime AutoPickGovernor { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Time1
|
||||
{
|
||||
get { return StartTimes.Length > 0 ? StartTimes[0].ToShortDateString() : "Empty"; }
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Time2
|
||||
{
|
||||
get { return StartTimes.Length > 1 ? StartTimes[1].ToShortDateString() : "Empty"; }
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Time3
|
||||
{
|
||||
get { return StartTimes.Length > 2 ? StartTimes[2].ToShortDateString() : "Empty"; }
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Time4
|
||||
{
|
||||
get { return StartTimes.Length > 3 ? StartTimes[3].ToShortDateString() : "Empty"; }
|
||||
}
|
||||
|
||||
public List<BallotEntry> Candidates { get; set; }
|
||||
|
||||
public DateTime[] StartTimes { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool ForceStart
|
||||
{
|
||||
get { return false; }
|
||||
set
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
if (Ongoing)
|
||||
EndElection();
|
||||
|
||||
StartTimes = new DateTime[1];
|
||||
StartTimes[0] = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "...";
|
||||
}
|
||||
|
||||
public CityElection(CityLoyaltySystem city)
|
||||
{
|
||||
City = city;
|
||||
|
||||
ElectionEnded = true;
|
||||
Candidates = new List<BallotEntry>();
|
||||
|
||||
GetDefaultStartTimes();
|
||||
}
|
||||
|
||||
public bool TryNominate(PlayerMobile pm)
|
||||
{
|
||||
CityLoyaltyEntry pentry = City.GetPlayerEntry<CityLoyaltyEntry>(pm);
|
||||
|
||||
if (pm.Young)
|
||||
pm.SendMessage("Young players cannot be nominated for the ballot!");
|
||||
else if (!City.IsCitizen(pm) || pentry == null)
|
||||
pm.SendLocalizedMessage(1153890); // You must be a citizen of this City to nominate yourself for the ballot!
|
||||
else if (City.GetLoyaltyRating(pm) < LoyaltyRating.Adored)
|
||||
pm.SendLocalizedMessage(1153891); // You must at least be adored within the City to nominate yourself for the ballot.
|
||||
else
|
||||
{
|
||||
Account a = pm.Account as Account;
|
||||
for (int i = 0; i < a.Length; i++)
|
||||
{
|
||||
Mobile m = a[i];
|
||||
|
||||
if(!(m is PlayerMobile))
|
||||
continue;
|
||||
|
||||
BallotEntry ballot = Candidates.FirstOrDefault(entry => entry.Player == m);
|
||||
|
||||
if (ballot != null && m is PlayerMobile)
|
||||
{
|
||||
pm.SendLocalizedMessage(ballot.Endorsements.Count > 0 ? 1153917 : 1153889); // A character from this account is currently endorsed for Candidacy and cannot be nominated. // A character from this account has already been nominated to run for office.
|
||||
return false; // A character from this account has already been nominated to run for office.
|
||||
}
|
||||
|
||||
ballot = Candidates.FirstOrDefault(entry => entry.Endorsements.Contains(m));
|
||||
|
||||
if (ballot != null && m is PlayerMobile)
|
||||
{
|
||||
pm.SendLocalizedMessage(1153892); // A character from this account has already endorsed a nominee!
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Candidates.Add(new BallotEntry(pm, pentry.Love, pentry.Hate));
|
||||
pm.PrivateOverheadMessage(Network.MessageType.Regular, 0x3B2, 1153905, pm.NetState); // *You etch your name into the stone*
|
||||
pm.SendLocalizedMessage(1154087); // You have 24 hours to get your nomination endorsed. If you do not get an endorsement within that period you will need to re-nominate yourself.
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryEndorse(PlayerMobile pm, PlayerMobile nominee)
|
||||
{
|
||||
if (pm.Young)
|
||||
pm.SendMessage("Young players cannot endorose an nominee!");
|
||||
else if (!City.IsCitizen(pm))
|
||||
pm.SendLocalizedMessage(1153893); // You must be a citizen of this City to endorse a nominee for the ballot!
|
||||
else
|
||||
{
|
||||
Account a = pm.Account as Account;
|
||||
|
||||
for (int i = 0; i < a.Length; i++)
|
||||
{
|
||||
Mobile m = a[i];
|
||||
|
||||
if(!(m is PlayerMobile))
|
||||
continue;
|
||||
|
||||
BallotEntry ballot = Candidates.FirstOrDefault(entry => entry.Endorsements.Contains(m as PlayerMobile));
|
||||
|
||||
if (m is PlayerMobile && ballot != null)
|
||||
{
|
||||
pm.SendLocalizedMessage(1153892); // A character from this account has already endorsed a nominee!
|
||||
return false;
|
||||
}
|
||||
|
||||
BallotEntry ballot2 = Candidates.FirstOrDefault(entry => entry.Player == m);
|
||||
|
||||
if (m is PlayerMobile && ballot2 != null)
|
||||
{
|
||||
pm.SendLocalizedMessage(1153912); // A character from this account is currently nominated for candidacy and cannot offer an endorsement.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BallotEntry pentry = Candidates.FirstOrDefault(e => e.Player == nominee);
|
||||
|
||||
if (pentry != null)
|
||||
{
|
||||
//<CENTER>Are you sure you wish to endorse this nominee? All endorsements are final and cannot be changed!</CENTER>
|
||||
pm.SendGump(new ConfirmCallbackGump(pm, null, 1154091, pentry, null, (m, o) =>
|
||||
{
|
||||
BallotEntry e = o as BallotEntry;
|
||||
e.Endorsements.Add(m as PlayerMobile);
|
||||
m.PrivateOverheadMessage(Network.MessageType.Regular, 0x3B2, 1153913, m.NetState); // *You etch your endorsement for the nominee into the stone*
|
||||
|
||||
}));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryVote(PlayerMobile voter, PlayerMobile candidate)
|
||||
{
|
||||
if (!CanVote())
|
||||
voter.SendLocalizedMessage(1153919); // The stone is not currently accepting votes.
|
||||
else if (voter.Young)
|
||||
voter.SendMessage("Young players cannot vote in a city election!");
|
||||
else if (!City.IsCitizen(voter))
|
||||
voter.SendLocalizedMessage(1153894); // You must be a citizen of this City to vote!
|
||||
else if (City.GetLoyaltyRating(voter) < LoyaltyRating.Respected)
|
||||
voter.SendLocalizedMessage(1154579); // You must be at least respected within the city to vote.
|
||||
else
|
||||
{
|
||||
Account a = voter.Account as Account;
|
||||
|
||||
for (int i = 0; i < a.Length; i++)
|
||||
{
|
||||
Mobile m = a[i];
|
||||
|
||||
if (m is PlayerMobile && Candidates.FirstOrDefault(e => e.Votes.Contains(m)) != null)
|
||||
{
|
||||
voter.SendLocalizedMessage(1153922); // This account has already cast a vote in this election. You may only vote once.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BallotEntry pentry = Candidates.FirstOrDefault(e => e.Player == candidate);
|
||||
|
||||
if (pentry != null)
|
||||
{
|
||||
//<CENTER>Are you sure you wish to cast your vote for this candidate? All votes are final and cannot be changed!</CENTER>
|
||||
voter.SendGump(new ConfirmCallbackGump(voter, null, 1153921, pentry, null, (m, o) =>
|
||||
{
|
||||
BallotEntry e = o as BallotEntry;
|
||||
e.Votes.Add(voter);
|
||||
m.PrivateOverheadMessage(Network.MessageType.Regular, 0x3B2, 1153923, voter.NetState); // *You etch your vote into the stone*
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void TryWithdraw(PlayerMobile pm)
|
||||
{
|
||||
BallotEntry entry = Candidates.FirstOrDefault(e => e.Player == pm);
|
||||
|
||||
if (entry != null)
|
||||
{
|
||||
//Are you sure you wish to withdrawal?
|
||||
pm.SendGump(new ConfirmCallbackGump(pm, null, 1153918, entry, null, (m, o) =>
|
||||
{
|
||||
BallotEntry e = (BallotEntry)o;
|
||||
|
||||
if (Candidates.Contains(e))
|
||||
{
|
||||
Candidates.Remove(e);
|
||||
m.PrivateOverheadMessage(Network.MessageType.Regular, 0x3B2, 1153911, m.NetState); // *You smudge your name off the stone*
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
else
|
||||
pm.SendLocalizedMessage(1153924); // You are not currently on any ballot to withdraw from.
|
||||
}
|
||||
|
||||
public double GetStanding(BallotEntry entry)
|
||||
{
|
||||
if (Candidates.Contains(entry))
|
||||
{
|
||||
if (entry.Votes.Count <= 0)
|
||||
return 0.0;
|
||||
|
||||
return (entry.Votes.Count / GetTotalVotes()) * 100;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public int GetTotalVotes()
|
||||
{
|
||||
int votes = 0;
|
||||
|
||||
Candidates.ForEach(c =>
|
||||
{
|
||||
votes += c.Votes.Count;
|
||||
});
|
||||
|
||||
return votes;
|
||||
}
|
||||
|
||||
public void OnTick()
|
||||
{
|
||||
foreach(DateTime dt in StartTimes)
|
||||
{
|
||||
if (dt.Year == DateTime.Now.Year && DateTime.Now.Month == dt.Month && DateTime.Now.Day > 14 && !ElectionEnded)
|
||||
{
|
||||
EndElection();
|
||||
}
|
||||
else if (dt.Year == DateTime.Now.Year && DateTime.Now.Month == dt.Month && DateTime.Now.Day == dt.Day && ElectionEnded)
|
||||
{
|
||||
StartNewElection();
|
||||
}
|
||||
}
|
||||
|
||||
if (City.Governor == null && AutoPickGovernor != DateTime.MinValue && DateTime.Now > AutoPickGovernor)
|
||||
{
|
||||
if (City.GovernorElect != null)
|
||||
{
|
||||
if (Candidates.Count > 0)
|
||||
{
|
||||
BallotEntry entry = Candidates.FirstOrDefault(c => c.Player == City.GovernorElect);
|
||||
|
||||
if (entry != null)
|
||||
Candidates.Remove(entry);
|
||||
}
|
||||
|
||||
City.GovernorElect = null;
|
||||
}
|
||||
|
||||
if (Candidates.Count > 0)
|
||||
{
|
||||
Candidates.Sort();
|
||||
City.GovernorElect = Candidates[0].Player;
|
||||
}
|
||||
|
||||
AutoPickGovernor = DateTime.MinValue;
|
||||
}
|
||||
|
||||
if (CanNominate())
|
||||
{
|
||||
Candidates.ForEach(entry =>
|
||||
{
|
||||
if (entry.TimeOfNomination + TimeSpan.FromHours(NominationDeadline) < DateTime.Now && entry.Endorsements.Count == 0)
|
||||
Candidates.Remove(entry);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void StartNewElection()
|
||||
{
|
||||
ElectionEnded = false;
|
||||
|
||||
Candidates.Clear();
|
||||
Candidates.TrimExcess();
|
||||
|
||||
AutoPickGovernor = DateTime.MinValue;
|
||||
}
|
||||
|
||||
private static int[] _Periods = { 3, 6, 9, 12 };
|
||||
|
||||
public void GetDefaultStartTimes()
|
||||
{
|
||||
StartTimes = new DateTime[4];
|
||||
|
||||
for(int i = 0; i < _Periods.Length; i++)
|
||||
{
|
||||
DateTime dt = new DateTime(DateTime.Now.Year, _Periods[i], 1);
|
||||
|
||||
if (dt < DateTime.Now)
|
||||
dt = new DateTime(dt.Year + 1, dt.Month, dt.Day);
|
||||
|
||||
StartTimes[i] = dt;
|
||||
}
|
||||
}
|
||||
|
||||
public static DateTime[] ValidateStartTimes(Mobile m, int[] times)
|
||||
{
|
||||
if (times != null && times.Length > 0)
|
||||
{
|
||||
DateTime[] starttimes = new DateTime[times.Length];
|
||||
|
||||
for (int i = 0; i < times.Length; i++)
|
||||
{
|
||||
int month = times[i];
|
||||
|
||||
if (month <= 0 || month > 12)
|
||||
{
|
||||
m.SendMessage("Invalid month for #{0}. It must be between 0 and 12.", i + 1);
|
||||
return null;
|
||||
}
|
||||
|
||||
DateTime dt = new DateTime(DateTime.Now.Year, month, 1);
|
||||
|
||||
if (dt < DateTime.Now)
|
||||
dt = new DateTime(dt.Year + 1, dt.Month, dt.Day);
|
||||
|
||||
starttimes[i] = dt;
|
||||
}
|
||||
|
||||
if (CheckConflict(starttimes))
|
||||
{
|
||||
m.SendMessage("times are too close to another start time. Please try again.");
|
||||
return null;
|
||||
}
|
||||
|
||||
return starttimes;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static bool CheckConflict(DateTime[] times)
|
||||
{
|
||||
if (times == null || times.Length == 0)
|
||||
return false;
|
||||
|
||||
for(int i = 0; i < times.Length; i++)
|
||||
{
|
||||
DateTime t = times[i];
|
||||
|
||||
for (int j = 0; j < times.Length; j++)
|
||||
{
|
||||
if (i == j)
|
||||
continue;
|
||||
|
||||
if ((times[j] > t && times[j] - t < TimeSpan.FromDays(30)) || times[j] < t && t - times[j] < TimeSpan.FromDays(30))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public DateTime NextElection()
|
||||
{
|
||||
if (CanNominate() || CanVote())
|
||||
return DateTime.MinValue;
|
||||
|
||||
DateTime closest = DateTime.MinValue;
|
||||
|
||||
foreach (DateTime dt in StartTimes)
|
||||
{
|
||||
if (DateTime.Now < dt)
|
||||
{
|
||||
if (closest == DateTime.MinValue || dt - DateTime.Now < closest - DateTime.Now)
|
||||
{
|
||||
closest = dt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
public bool CanNominate()
|
||||
{
|
||||
DateTime until = DateTime.MinValue;
|
||||
return CanNominate(out until);
|
||||
}
|
||||
|
||||
public bool CanNominate(out DateTime until)
|
||||
{
|
||||
until = DateTime.Now;
|
||||
foreach (DateTime dt in StartTimes)
|
||||
{
|
||||
if (dt.Year == DateTime.Now.Year && DateTime.Now.Month == dt.Month && DateTime.Now <= dt.AddDays(VotePeriod))
|
||||
{
|
||||
until = dt.AddDays(VotePeriod);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool CanVote()
|
||||
{
|
||||
DateTime until = DateTime.MinValue;
|
||||
return CanVote(out until);
|
||||
}
|
||||
|
||||
public bool CanVote(out DateTime until)
|
||||
{
|
||||
until = DateTime.Now;
|
||||
foreach (DateTime dt in StartTimes)
|
||||
{
|
||||
if (dt.Year == DateTime.Now.Year && DateTime.Now.Month == dt.Month && DateTime.Now > dt.AddDays(VotePeriod) && DateTime.Now <= dt.AddDays(VotePeriod * 2))
|
||||
{
|
||||
until = dt.AddDays(VotePeriod * 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void EndElection()
|
||||
{
|
||||
ElectionEnded = true;
|
||||
|
||||
if (Candidates.Count > 0)
|
||||
{
|
||||
Candidates.Sort();
|
||||
City.GovernorElect = Candidates[0].Player;
|
||||
|
||||
AutoPickGovernor = DateTime.Now + TimeSpan.FromDays(7);
|
||||
}
|
||||
|
||||
if (City.GovernorElect == null)
|
||||
{
|
||||
City.PendingGovernor = true;
|
||||
AutoPickGovernor = DateTime.Now + TimeSpan.FromDays(Utility.RandomMinMax(2, 4));
|
||||
|
||||
if (City.Stone != null)
|
||||
City.Stone.InvalidateProperties();
|
||||
}
|
||||
|
||||
for(int i = 0; i < StartTimes.Length; i++)
|
||||
{
|
||||
DateTime dt = StartTimes[i];
|
||||
|
||||
if (dt == DateTime.MinValue)
|
||||
continue;
|
||||
|
||||
if (dt < DateTime.Now)
|
||||
dt = new DateTime(dt.Year + 1, dt.Month, dt.Day);
|
||||
}
|
||||
}
|
||||
|
||||
public void OnRejectOffice(PlayerMobile pm)
|
||||
{
|
||||
BallotEntry entry = Candidates.FirstOrDefault(c => c.Player == pm);
|
||||
|
||||
if (entry != null)
|
||||
Candidates.Remove(entry);
|
||||
|
||||
AutoPickGovernor = DateTime.Now + TimeSpan.FromDays(Utility.RandomMinMax(2, 4));
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(ElectionEnded);
|
||||
writer.Write(AutoPickGovernor);
|
||||
|
||||
writer.Write(StartTimes.Length);
|
||||
foreach (DateTime dt in StartTimes)
|
||||
writer.Write(dt);
|
||||
|
||||
writer.Write(Candidates.Count);
|
||||
Candidates.ForEach(entry => entry.Serialize(writer));
|
||||
}
|
||||
|
||||
public CityElection(CityLoyaltySystem city, GenericReader reader)
|
||||
{
|
||||
City = city;
|
||||
Candidates = new List<BallotEntry>();
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
ElectionEnded = reader.ReadBool();
|
||||
AutoPickGovernor = reader.ReadDateTime();
|
||||
|
||||
int c = reader.ReadInt();
|
||||
StartTimes = new DateTime[c];
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
DateTime time = reader.ReadDateTime();
|
||||
|
||||
if (time < DateTime.Now && ElectionEnded)
|
||||
time = new DateTime(time.Year + 1, time.Month, time.Day);
|
||||
|
||||
StartTimes[i] = time;
|
||||
}
|
||||
|
||||
c = reader.ReadInt();
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
BallotEntry entry = new BallotEntry(reader);
|
||||
if (entry.Player != null)
|
||||
Candidates.Add(entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class BallotEntry : IComparable<BallotEntry>
|
||||
{
|
||||
public PlayerMobile Player { get; set; }
|
||||
public DateTime TimeOfNomination { get; set; }
|
||||
|
||||
public int Love { get; set; }
|
||||
public int Hate { get; set; }
|
||||
|
||||
public List<PlayerMobile> Endorsements { get; set; }
|
||||
public List<PlayerMobile> Votes { get; set; }
|
||||
|
||||
public BallotEntry(PlayerMobile pm, int love, int hate)
|
||||
{
|
||||
Player = pm;
|
||||
TimeOfNomination = DateTime.Now;
|
||||
|
||||
Love = love;
|
||||
Hate = hate;
|
||||
|
||||
Endorsements = new List<PlayerMobile>();
|
||||
Votes = new List<PlayerMobile>();
|
||||
}
|
||||
|
||||
public int CompareTo(BallotEntry entry)
|
||||
{
|
||||
if (Player == null)
|
||||
return -1;
|
||||
|
||||
if (Votes.Count > entry.Votes.Count)
|
||||
return 1;
|
||||
else if (Votes.Count < entry.Votes.Count)
|
||||
return -1;
|
||||
else
|
||||
{
|
||||
if (Love > entry.Love || Hate < entry.Hate)
|
||||
return 1;
|
||||
else if (Love == entry.Love && Hate == entry.Hate && Utility.RandomBool())
|
||||
return 1;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Player);
|
||||
writer.Write(TimeOfNomination);
|
||||
|
||||
writer.Write(Love);
|
||||
writer.Write(Hate);
|
||||
|
||||
writer.Write(Endorsements.Count);
|
||||
Endorsements.ForEach(p => writer.Write(p));
|
||||
|
||||
writer.Write(Votes.Count);
|
||||
Votes.ForEach(p => writer.Write(p));
|
||||
}
|
||||
|
||||
public BallotEntry(GenericReader reader)
|
||||
{
|
||||
Endorsements = new List<PlayerMobile>();
|
||||
Votes = new List<PlayerMobile>();
|
||||
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Player = reader.ReadMobile() as PlayerMobile;
|
||||
TimeOfNomination = reader.ReadDateTime();
|
||||
|
||||
Love = reader.ReadInt();
|
||||
Hate = reader.ReadInt();
|
||||
|
||||
int c = reader.ReadInt();
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
PlayerMobile p = reader.ReadMobile() as PlayerMobile;
|
||||
if (p != null)
|
||||
Endorsements.Add(p);
|
||||
}
|
||||
|
||||
c = reader.ReadInt();
|
||||
for (int i = 0; i < c; i++)
|
||||
{
|
||||
PlayerMobile p = reader.ReadMobile() as PlayerMobile;
|
||||
if (p != null)
|
||||
Votes.Add(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1239
Scripts/Services/City Loyalty System/Gumps.cs
Normal file
1239
Scripts/Services/City Loyalty System/Gumps.cs
Normal file
File diff suppressed because it is too large
Load Diff
233
Scripts/Services/City Loyalty System/Items/Addons.cs
Normal file
233
Scripts/Services/City Loyalty System/Items/Addons.cs
Normal file
@@ -0,0 +1,233 @@
|
||||
using Server;
|
||||
using System;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using Server.Multis;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class InterchangeableAddonDeed : BaseAddonDeed
|
||||
{
|
||||
// This will need to be further implemented in any derived class
|
||||
public override BaseAddon Addon { get { return null; } }
|
||||
|
||||
public abstract int EastID { get; }
|
||||
public abstract int SouthID { get; }
|
||||
|
||||
public InterchangeableAddonDeed()
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if ( IsChildOf( from.Backpack ) )
|
||||
from.Target = new InternalTarget( this );
|
||||
else
|
||||
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
public InterchangeableAddonDeed Deed { get; set; }
|
||||
|
||||
public InternalTarget(InterchangeableAddonDeed deed) : base( -1, true, TargetFlags.None )
|
||||
{
|
||||
Deed = deed;
|
||||
}
|
||||
|
||||
protected override void OnTarget( Mobile from, object targeted )
|
||||
{
|
||||
IPoint3D p = targeted as IPoint3D;
|
||||
Map map = from.Map;
|
||||
|
||||
if(p == null || map == null || Deed.Deleted)
|
||||
return;
|
||||
|
||||
AddonFitResult result = AddonFitResult.Valid;
|
||||
|
||||
if(Deed.IsChildOf(from.Backpack))
|
||||
{
|
||||
BaseHouse house = null;
|
||||
|
||||
if ( !map.CanFit( p.X, p.Y, p.Z, 16, false, true, false ) )
|
||||
result = AddonFitResult.Blocked;
|
||||
else if ( !BaseAddon.CheckHouse( from, new Point3D(p), map, 16, ref house ) )
|
||||
result = AddonFitResult.NotInHouse;
|
||||
else
|
||||
{
|
||||
bool east = BaseAddon.IsWall(p.X - 1, p.Y, p.Z, map);
|
||||
bool south = BaseAddon.IsWall(p.X, p.Y - 1, p.Z, map);
|
||||
|
||||
if(!south && !east)
|
||||
result = AddonFitResult.NoWall;
|
||||
else if (south && east)
|
||||
from.SendGump(new AddonInterchangeableGump(from, Deed, p, map));
|
||||
else
|
||||
{
|
||||
BaseAddon addon = Deed.DeployAddon(east, p, map);
|
||||
house.Addons[addon] = from;
|
||||
}
|
||||
}
|
||||
|
||||
switch (result)
|
||||
{
|
||||
default: break;
|
||||
case AddonFitResult.Blocked: from.SendLocalizedMessage(500269); break; // You cannot build that there.
|
||||
case AddonFitResult.NotInHouse: from.SendLocalizedMessage(500274); break; // You can only place this in a house that you own!
|
||||
case AddonFitResult.NoWall: from.SendLocalizedMessage(500268); break; // This object needs to be mounted on something.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage( 1042001 ); // That must be in your pack for you to use it.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual BaseAddon DeployAddon(bool east, IPoint3D p, Map map)
|
||||
{
|
||||
BaseAddon addon = Addon;
|
||||
|
||||
if(addon != null)
|
||||
{
|
||||
if(addon is InterchangeableAddon)
|
||||
((InterchangeableAddon)addon).EastFacing = east;
|
||||
|
||||
Server.Spells.SpellHelper.GetSurfaceTop( ref p );
|
||||
|
||||
addon.MoveToWorld(new Point3D(p), map);
|
||||
|
||||
Delete();
|
||||
}
|
||||
|
||||
return addon;
|
||||
}
|
||||
|
||||
public InterchangeableAddonDeed(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class InterchangeableAddon : BaseAddon
|
||||
{
|
||||
private bool _EastFacing;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool EastFacing
|
||||
{
|
||||
get
|
||||
{
|
||||
return _EastFacing;
|
||||
}
|
||||
set
|
||||
{
|
||||
if(Components.Count == 1)
|
||||
{
|
||||
if(value)
|
||||
{
|
||||
Components[0].ItemID = EastID;
|
||||
}
|
||||
else
|
||||
{
|
||||
Components[0].ItemID = SouthID;
|
||||
}
|
||||
}
|
||||
|
||||
_EastFacing = value;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract int EastID { get; }
|
||||
public abstract int SouthID { get; }
|
||||
|
||||
// This will need to be further implemented in any derived class
|
||||
public override BaseAddonDeed Deed { get { return null; } }
|
||||
|
||||
public InterchangeableAddon(bool eastface = true, int loc = 0)
|
||||
{
|
||||
if(loc != 0)
|
||||
AddComponent(new LocalizedAddonComponent(eastface ? EastID : SouthID, loc), 0, 0, 0);
|
||||
else
|
||||
AddComponent(new AddonComponent(eastface ? EastID : SouthID), 0, 0, 0);
|
||||
}
|
||||
|
||||
public InterchangeableAddon(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class AddonInterchangeableGump : Gump
|
||||
{
|
||||
public InterchangeableAddonDeed Deed { get; private set; }
|
||||
public IPoint3D Point { get; private set; }
|
||||
public Map Map { get; private set; }
|
||||
|
||||
public AddonInterchangeableGump(Mobile user, InterchangeableAddonDeed deed, IPoint3D p, Map map) : base(50, 50)
|
||||
{
|
||||
Deed = deed;
|
||||
Point = p;
|
||||
Map = map;
|
||||
|
||||
AddGumpLayout();
|
||||
}
|
||||
|
||||
public void AddGumpLayout()
|
||||
{
|
||||
AddBackground(0, 0, 300, 200, 2600);
|
||||
|
||||
AddHtmlLocalized(0, 15, 300, 16, 1152360, false, false); // <CENTER>Choose a banner:</CENTER>
|
||||
|
||||
Rectangle2D b = ItemBounds.Table[Deed.EastID];
|
||||
AddItem(70 - b.Width / 2 - b.X, 75 - b.Height / 2 - b.Y, Deed.EastID);
|
||||
|
||||
b = ItemBounds.Table[Deed.SouthID];
|
||||
AddItem(180 - b.Width / 2 - b.X, 75 - b.Height / 2 - b.Y, Deed.SouthID);
|
||||
|
||||
AddButton(75, 50, 2103, 2104, 1, GumpButtonType.Reply, 0);
|
||||
AddButton(205, 50, 2103, 2104, 2, GumpButtonType.Reply, 0);
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
if (!state.Mobile.InRange(Point, 3))
|
||||
{
|
||||
state.Mobile.SendLocalizedMessage(500251); // That location is too far away.
|
||||
}
|
||||
else if (info.ButtonID == 1)
|
||||
{
|
||||
Deed.DeployAddon(true, Point, Map);
|
||||
}
|
||||
else if (info.ButtonID == 2)
|
||||
{
|
||||
Deed.DeployAddon(false, Point, Map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
122
Scripts/Services/City Loyalty System/Items/Banners.cs
Normal file
122
Scripts/Services/City Loyalty System/Items/Banners.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using Server.Targeting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
public class CityBanner : InterchangeableAddon
|
||||
{
|
||||
public override BaseAddonDeed Deed { get { return new CityBannerDeed(City); } }
|
||||
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public City City { get; private set; }
|
||||
|
||||
public override int EastID { get { return SouthID + 9; } }
|
||||
public override int SouthID { get { return BannerInfo[City][0]; } }
|
||||
|
||||
[Constructable]
|
||||
public CityBanner(City city)
|
||||
: base(true, BannerInfo[city][1])
|
||||
{
|
||||
City = city;
|
||||
}
|
||||
|
||||
public static Dictionary<City, int[]> BannerInfo { get; set; }
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
BannerInfo = new Dictionary<City, int[]>();
|
||||
//ID Cliloc
|
||||
BannerInfo[City.Moonglow] = new int[] { 0x4B63, 1098171 };
|
||||
BannerInfo[City.Britain] = new int[] { 0x4B64, 1098172 };
|
||||
BannerInfo[City.Jhelom] = new int[] { 0x4B65, 1098173 };
|
||||
BannerInfo[City.Yew] = new int[] { 0x4B66, 1098174 };
|
||||
BannerInfo[City.Minoc] = new int[] { 0x4B67, 1098175 };
|
||||
BannerInfo[City.Trinsic] = new int[] { 0x4B62, 1098170 };
|
||||
BannerInfo[City.SkaraBrae] = new int[] { 0x4B6A, 1098178 };
|
||||
BannerInfo[City.NewMagincia] = new int[] { 0x4B69, 1098177 };
|
||||
BannerInfo[City.Vesper] = new int[] { 0x4B68, 1098176 };
|
||||
}
|
||||
|
||||
public CityBanner(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)City);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
City = (City)reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class CityBannerDeed : InterchangeableAddonDeed
|
||||
{
|
||||
public override BaseAddon Addon { get { return new CityBanner(City); } }
|
||||
|
||||
public override int LabelNumber { get { return CityBanner.BannerInfo[City][1]; } }
|
||||
|
||||
public override int EastID { get { return SouthID + 9; } }
|
||||
public override int SouthID { get { return CityBanner.BannerInfo[City][0]; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public City City { get; private set; }
|
||||
|
||||
[Constructable]
|
||||
public CityBannerDeed(City city)
|
||||
{
|
||||
City = city;
|
||||
|
||||
LootType = LootType.Blessed;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack))
|
||||
{
|
||||
CityLoyaltySystem sys = CityLoyaltySystem.GetCityInstance(this.City);
|
||||
|
||||
if (CityLoyaltySystem.HasCitizenship(from, this.City) && sys.GetLoyaltyRating(from) >= LoyaltyRating.Commended)
|
||||
{
|
||||
base.OnDoubleClick(from);
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1152361, String.Format("#{0}", CityLoyaltySystem.GetCityLocalization(this.City))); // You are not sufficiently loyal to ~1_CITY~ to use this.
|
||||
}
|
||||
}
|
||||
|
||||
public CityBannerDeed(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)City);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
City = (City)reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
95
Scripts/Services/City Loyalty System/Items/BoxOfRopes.cs
Normal file
95
Scripts/Services/City Loyalty System/Items/BoxOfRopes.cs
Normal file
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
using Server.Engines.CityLoyalty;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class BoxOfRopes : Container
|
||||
{
|
||||
public City City { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CityLoyaltySystem CitySystem { get { return CityLoyaltySystem.GetCityInstance(City); } set { } }
|
||||
|
||||
public override int LabelNumber { get { return 1152262; } } // a box of ropes
|
||||
|
||||
public BoxOfRopes(City city) : base(3650)
|
||||
{
|
||||
Hue = 1944;
|
||||
Movable = false;
|
||||
|
||||
City = city;
|
||||
|
||||
if (CitySystem != null && CitySystem.Captain != null)
|
||||
CitySystem.Captain.Box = this;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (CityLoyaltySystem.Enabled && CityLoyaltySystem.IsSetup() && from.InRange(this.Location, 3))
|
||||
{
|
||||
if (_Cooldown == null || !_Cooldown.ContainsKey(from) || _Cooldown[from] < DateTime.UtcNow)
|
||||
{
|
||||
var rope = new GuardsmansRope();
|
||||
from.AddToBackpack(rope);
|
||||
|
||||
from.SendLocalizedMessage(1152263); // You take a rope from the chest. Use it to arrest rioters and subdued raiders.
|
||||
|
||||
if (_Cooldown == null)
|
||||
_Cooldown = new Dictionary<Mobile, DateTime>();
|
||||
|
||||
_Cooldown[from] = DateTime.UtcNow + TimeSpan.FromSeconds(60);
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1152264); // You must wait a moment before taking another rope.
|
||||
}
|
||||
else
|
||||
from.PrivateOverheadMessage(Server.Network.MessageType.Regular, 0x3B2, 1019045, from.NetState); // I can't reach that.
|
||||
}
|
||||
|
||||
public static Dictionary<Mobile, DateTime> _Cooldown { get; set; }
|
||||
|
||||
public static void Defrag()
|
||||
{
|
||||
if (_Cooldown == null)
|
||||
return;
|
||||
|
||||
List<Mobile> list = new List<Mobile>(_Cooldown.Keys);
|
||||
|
||||
foreach (Mobile m in list.Where(mob => _Cooldown[mob] < DateTime.UtcNow))
|
||||
_Cooldown.Remove(m);
|
||||
|
||||
list.Clear();
|
||||
list.TrimExcess();
|
||||
}
|
||||
|
||||
public BoxOfRopes(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)City);
|
||||
|
||||
Defrag();
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
City = (City)reader.ReadInt();
|
||||
|
||||
if (CitySystem != null && CitySystem.Captain != null)
|
||||
CitySystem.Captain.Box = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
184
Scripts/Services/City Loyalty System/Items/CityMessageBoard.cs
Normal file
184
Scripts/Services/City Loyalty System/Items/CityMessageBoard.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using System.Collections.Generic;
|
||||
using Server.Engines.CityLoyalty;
|
||||
using System.Linq;
|
||||
using Server.Prompts;
|
||||
using Server.ContextMenus;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class CityMessageBoard : BasePlayerBB
|
||||
{
|
||||
public City City { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CityLoyaltySystem CitySystem { get { return CityLoyaltySystem.GetCityInstance(City); } set { } }
|
||||
|
||||
public override int LabelNumber { get { return 1027774; } } // bulletin board
|
||||
public override bool Public { get { return true; } }
|
||||
public override bool ForceShowProperties { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public CityMessageBoard(City city, int id) : base(id)
|
||||
{
|
||||
Movable = false;
|
||||
City = city;
|
||||
}
|
||||
|
||||
public override bool CanPostGreeting(Server.Multis.BaseHouse house, Mobile m)
|
||||
{
|
||||
var sys = CitySystem;
|
||||
|
||||
return sys != null && (m.AccessLevel >= AccessLevel.GameMaster || sys.Governor == m);
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!CityLoyaltySystem.Enabled || CitySystem == null)
|
||||
return;
|
||||
|
||||
if (CitySystem.IsCitizen(from, true))
|
||||
{
|
||||
if (from.InRange(this.Location, 3))
|
||||
{
|
||||
from.SendGump(new PlayerBBGump(from, null, this, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
from.PrivateOverheadMessage(Server.Network.MessageType.Regular, 0x3B2, 1019045, from.NetState);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1154275); // Only Citizens of this City may use this.
|
||||
}
|
||||
}
|
||||
|
||||
/*public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
if (!CityLoyaltySystem.Enabled || CitySystem == null || !CitySystem.IsGovernor(from))
|
||||
return;
|
||||
|
||||
list.Add(new SimpleContextMenuEntry(from, 1154912, m => // Set New Announcement
|
||||
{
|
||||
if (m.Prompt != null)
|
||||
m.SendLocalizedMessage(1079166); // You already have a text entry request pending.
|
||||
else if (CitySystem.Herald != null)
|
||||
{
|
||||
m.SendMessage("Enter message board headline:");
|
||||
m.BeginPrompt(
|
||||
(mob, text) =>
|
||||
{
|
||||
if (Server.Guilds.BaseGuildGump.CheckProfanity(text, 150))
|
||||
{
|
||||
CitySystem.Herald.Announcement = text;
|
||||
}
|
||||
else
|
||||
mob.SendLocalizedMessage(1112587); // Invalid entry.
|
||||
},
|
||||
(mob, text) =>
|
||||
{
|
||||
mob.SendMessage("Herald message unchanged.");
|
||||
});
|
||||
}
|
||||
}, enabled: CitySystem.Herald != null));
|
||||
|
||||
list.Add(new SimpleContextMenuEntry(from, 1154913, m => // Set Headline
|
||||
{
|
||||
if (m.Prompt != null)
|
||||
m.SendLocalizedMessage(1079166); // You already have a text entry request pending.
|
||||
else
|
||||
{
|
||||
m.SendMessage("Enter message board headline:");
|
||||
m.BeginPrompt(
|
||||
(mob, text) =>
|
||||
{
|
||||
if (Server.Guilds.BaseGuildGump.CheckProfanity(text, 150))
|
||||
{
|
||||
if (String.IsNullOrEmpty(text))
|
||||
{
|
||||
CitySystem.Headline = null;
|
||||
CitySystem.Body = null;
|
||||
CitySystem.PostedOn = DateTime.Now;
|
||||
mob.SendMessage("{0} message board headline removed!", CitySystem.Definition.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
CitySystem.Headline = text;
|
||||
CitySystem.PostedOn = DateTime.Now;
|
||||
mob.SendMessage("{0} message board headline changed!", CitySystem.Definition.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
mob.SendLocalizedMessage(1112587); // Invalid entry.
|
||||
},
|
||||
(mob, text) =>
|
||||
{
|
||||
mob.SendMessage("Message headline unchanged.");
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
list.Add(new SimpleContextMenuEntry(from, 1154914, m => // Set Body
|
||||
{
|
||||
if (m.Prompt != null)
|
||||
m.SendLocalizedMessage(1079166); // You already have a text entry request pending.
|
||||
else
|
||||
{
|
||||
m.SendMessage("Enter message board body:");
|
||||
m.BeginPrompt(
|
||||
(mob, text) =>
|
||||
{
|
||||
if (Server.Guilds.BaseGuildGump.CheckProfanity(text, 150))
|
||||
{
|
||||
if (String.IsNullOrEmpty(text))
|
||||
{
|
||||
CitySystem.Body = null;
|
||||
CitySystem.PostedOn = DateTime.Now;
|
||||
mob.SendMessage("{0} message board body removed!", CitySystem.Definition.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
CitySystem.Body = text;
|
||||
CitySystem.PostedOn = DateTime.Now;
|
||||
mob.SendMessage("{0} message board body removed!", CitySystem.Definition.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
mob.SendLocalizedMessage(1112587); // Invalid entry.
|
||||
},
|
||||
(mob, text) =>
|
||||
{
|
||||
mob.SendMessage("Message body unchanged.");
|
||||
});
|
||||
}
|
||||
}));
|
||||
}*/
|
||||
|
||||
public CityMessageBoard(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)City);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
City = (City)reader.ReadInt();
|
||||
CitySystem.Board = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
260
Scripts/Services/City Loyalty System/Items/CityStone.cs
Normal file
260
Scripts/Services/City Loyalty System/Items/CityStone.cs
Normal file
@@ -0,0 +1,260 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Items;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Server.ContextMenus;
|
||||
using Server.Targeting;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
public class CityStone : Item
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CityLoyaltySystem City { get; set; }
|
||||
|
||||
public List<BallotBox> Boxes { get; set; }
|
||||
|
||||
public CityStone(CityLoyaltySystem city) : base(0xED4)
|
||||
{
|
||||
City = city;
|
||||
Movable = false;
|
||||
|
||||
City.Stone = this;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (CityLoyaltySystem.Enabled && CityLoyaltySystem.IsSetup() && from is PlayerMobile && from.InRange(from.Location, 3))
|
||||
{
|
||||
if (from is PlayerMobile && City != null && City.IsCitizen(from))
|
||||
BaseGump.SendGump(new CityStoneGump(from as PlayerMobile, City));
|
||||
else
|
||||
from.SendLocalizedMessage(1153888); // Only Citizens of this City may use the Election Stone.
|
||||
}
|
||||
}
|
||||
|
||||
public override void AddNameProperty(ObjectPropertyList list)
|
||||
{
|
||||
if(City != null)
|
||||
list.Add(1153887, String.Format("#{0}", CityLoyaltySystem.GetCityLocalization(City.City)));
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (!CityLoyaltySystem.Enabled || City == null)
|
||||
return;
|
||||
|
||||
if (City.GovernorElect != null)
|
||||
list.Add(1154066, City.GovernorElect.Name); // Governor-Elect: ~1_NAME~
|
||||
else
|
||||
list.Add(1154067, City.PendingGovernor ? "#1154102" : City.Governor != null ? City.Governor.Name : "#1154072"); // Governor: ~1_NAME~
|
||||
|
||||
if (City.Election != null)
|
||||
{
|
||||
DateTime dt;
|
||||
|
||||
if (City.Election.CanNominate(out dt))
|
||||
list.Add(1155756, dt.ToShortDateString()); // Nomination period ends after: ~1_DATE~
|
||||
|
||||
if (City.Election.CanVote(out dt))
|
||||
list.Add(1155757, dt.ToShortDateString()); // Voting Period Ends After: ~1_DATE~
|
||||
}
|
||||
|
||||
list.Add(1154023, City.Treasury > 0 ? City.Treasury.ToString("N0", CultureInfo.GetCultureInfo("en-US")) : City.Treasury.ToString()); // City Treasury Balance: ~1_AMT~
|
||||
list.Add(1154059, String.Format("#{0}", City.ActiveTradeDeal == TradeDeal.None ? 1011051 : (int)City.ActiveTradeDeal - 12)); // Current Trade Deal: ~1_GUILD~
|
||||
list.Add(1154907, City.CompletedTrades.ToString(CultureInfo.GetCultureInfo("en-US"))); // Trade Orders Delivered: ~1_val~
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> list)
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
if (!CityLoyaltySystem.Enabled || City == null)
|
||||
return;
|
||||
|
||||
if (!City.IsCitizen(from))
|
||||
{
|
||||
if (City.Herald != null)
|
||||
City.Herald.SayTo(from, 1154061, City.Definition.Name); // Only citizens of ~1_CITY~ may use the City Stone!
|
||||
else
|
||||
from.SendLocalizedMessage(1154061, City.Definition.Name); // Only citizens of ~1_CITY~ may use the City Stone!
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
list.Add(new SimpleContextMenuEntry(from, 1154018, m => // Grant Citizen Title
|
||||
{
|
||||
if(City.IsGovernor(m))
|
||||
{
|
||||
m.SendLocalizedMessage(1154027); // Which Citizen do you wish to bestow a title?
|
||||
m.BeginTarget(10, false, TargetFlags.None, (mob, targeted) =>
|
||||
{
|
||||
PlayerMobile pm = targeted as PlayerMobile;
|
||||
|
||||
if (pm != null)
|
||||
{
|
||||
if (City.IsCitizen(pm))
|
||||
{
|
||||
BaseGump.SendGump(new PlayerTitleGump(mob as PlayerMobile, pm, City));
|
||||
}
|
||||
else
|
||||
mob.SendLocalizedMessage(1154029); // You may only bestow a title on citizens of this city!
|
||||
}
|
||||
else
|
||||
mob.SendLocalizedMessage(1154028); // You can only bestow a title on a player!
|
||||
});
|
||||
}
|
||||
}, enabled: City.IsGovernor(from)));
|
||||
|
||||
list.Add(new SimpleContextMenuEntry(from, 1154031, m => // Open Trade Deal
|
||||
{
|
||||
if (City.IsGovernor(m))
|
||||
{
|
||||
BaseGump.SendGump(new ChooseTradeDealGump(m as PlayerMobile, City));
|
||||
}
|
||||
}, enabled: City.IsGovernor(from)));
|
||||
|
||||
list.Add(new SimpleContextMenuEntry(from, 1154277, m => // Open Inventory WTF is this?
|
||||
{
|
||||
if (m is PlayerMobile && City.IsGovernor(m))
|
||||
{
|
||||
BaseGump.SendGump(new OpenInventoryGump((PlayerMobile)m, City));
|
||||
}
|
||||
}, enabled: City.IsGovernor(from)));
|
||||
|
||||
list.Add(new SimpleContextMenuEntry(from, 1154278, m => // Place Ballot Box
|
||||
{
|
||||
if (City.IsGovernor(m))
|
||||
{
|
||||
if (Boxes != null && Boxes.Count >= CityLoyaltySystem.MaxBallotBoxes)
|
||||
{
|
||||
m.SendMessage("You have reached the maximum amount of ballot boxes in your city.");
|
||||
return;
|
||||
}
|
||||
|
||||
m.SendMessage("Where would you like to place a ballot box?");
|
||||
m.BeginTarget(3, true, TargetFlags.None, (mob, targeted) =>
|
||||
{
|
||||
if (targeted is IPoint3D)
|
||||
{
|
||||
IPoint3D p = targeted as IPoint3D;
|
||||
Server.Spells.SpellHelper.GetSurfaceTop(ref p);
|
||||
BallotBox box = new BallotBox();
|
||||
|
||||
if (CheckLocation(m, box, p))
|
||||
{
|
||||
box.Owner = m;
|
||||
box.Movable = false;
|
||||
|
||||
if (Boxes == null)
|
||||
Boxes = new List<BallotBox>();
|
||||
|
||||
Boxes.Add(box);
|
||||
box.MoveToWorld(new Point3D(p), this.Map);
|
||||
|
||||
m.SendMessage("{0} of {1} ballot boxes placed.", Boxes.Count.ToString(), CityLoyaltySystem.MaxBallotBoxes.ToString());
|
||||
}
|
||||
else
|
||||
box.Delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, enabled: City.IsGovernor(from)));
|
||||
|
||||
list.Add(new SimpleContextMenuEntry(from, 1154060, m => // Utilize Trade Deal
|
||||
{
|
||||
City.TryUtilizeTradeDeal(from);
|
||||
}, enabled: City.ActiveTradeDeal != TradeDeal.None));
|
||||
|
||||
CityLoyaltyEntry entry = City.GetPlayerEntry<CityLoyaltyEntry>(from);
|
||||
|
||||
list.Add(new SimpleContextMenuEntry(from, 1154019, m => // Remove City Title
|
||||
{
|
||||
if (entry != null && entry.CustomTitle != null)
|
||||
{
|
||||
entry.CustomTitle = null;
|
||||
|
||||
if(m is PlayerMobile)
|
||||
((PlayerMobile)m).RemoveRewardTitle(1154017, true);
|
||||
|
||||
m.SendMessage("City Title removed.");
|
||||
}
|
||||
}, enabled: entry != null && entry.CustomTitle != null));
|
||||
|
||||
list.Add(new SimpleContextMenuEntry(from, 1154068, m => // Accept Office
|
||||
{
|
||||
if (m is PlayerMobile && m == City.GovernorElect && City.Governor == null)
|
||||
{
|
||||
BaseGump.SendGump(new AcceptOfficeGump(m as PlayerMobile, City));
|
||||
}
|
||||
}, enabled: City.GovernorElect == from && City.Governor == null && City.GetLoyaltyRating(from) >= LoyaltyRating.Unknown));
|
||||
}
|
||||
|
||||
public bool CheckLocation(Mobile m, BallotBox box, IPoint3D p)
|
||||
{
|
||||
Region r = Region.Find(new Point3D(p), this.Map);
|
||||
|
||||
if (!r.IsPartOf(City.Definition.Region))
|
||||
{
|
||||
m.SendMessage("You can only place a ballot box within the {0} city limits!", City.Definition.Name);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!box.DropToWorld(new Point3D(p), this.Map))
|
||||
{
|
||||
m.SendMessage("You cannot place a ballot box there!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public CityStone(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)City.City);
|
||||
|
||||
writer.Write(Boxes == null ? 0 : Boxes.Count);
|
||||
if (Boxes != null)
|
||||
{
|
||||
Boxes.ForEach(b => writer.Write(b));
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
City = CityLoyaltySystem.GetCityInstance((City)reader.ReadInt());
|
||||
|
||||
if(City != null)
|
||||
City.Stone = this;
|
||||
|
||||
int count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
BallotBox box = reader.ReadItem() as BallotBox;
|
||||
|
||||
if (box != null)
|
||||
{
|
||||
if (Boxes == null)
|
||||
Boxes = new List<BallotBox>();
|
||||
|
||||
Boxes.Add(box);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Scripts/Services/City Loyalty System/Items/GuardsmansRope.cs
Normal file
70
Scripts/Services/City Loyalty System/Items/GuardsmansRope.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.CityLoyalty;
|
||||
using Server.Targeting;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class GuardsmansRope : BaseDecayingItem
|
||||
{
|
||||
public override int LabelNumber { get { return 1152261; } } // guardsman's rope
|
||||
public override int Lifespan { get { return 3600; } }
|
||||
|
||||
public GuardsmansRope() : base(0x14F8)
|
||||
{
|
||||
Hue = 1944;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (IsChildOf(from.Backpack))
|
||||
{
|
||||
from.SendLocalizedMessage(1152244); // What would you like to arrest?
|
||||
from.BeginTarget(10, false, TargetFlags.None, (m, targeted) =>
|
||||
{
|
||||
if (targeted is Raider)
|
||||
{
|
||||
Raider raider = targeted as Raider;
|
||||
|
||||
if (raider.InRange(m.Location, 1))
|
||||
{
|
||||
if (raider.TryArrest(from))
|
||||
Delete();
|
||||
}
|
||||
else
|
||||
m.SendLocalizedMessage(1152242); // You cannot reach that.
|
||||
}
|
||||
else
|
||||
m.SendLocalizedMessage(1152243); // You cannot arrest that.
|
||||
});
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1116249); // That must be in your backpack for you to use it.
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public GuardsmansRope(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
213
Scripts/Services/City Loyalty System/Mobiles/CityHerald.cs
Normal file
213
Scripts/Services/City Loyalty System/Mobiles/CityHerald.cs
Normal file
@@ -0,0 +1,213 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.ContextMenus;
|
||||
using Server.Items;
|
||||
using Server.Misc;
|
||||
using Server.Prompts;
|
||||
using Server.Network;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
public class CityHerald : BaseCreature
|
||||
{
|
||||
public City City { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CityLoyaltySystem CitySystem { get { return CityLoyaltySystem.GetCityInstance(City); } set { } }
|
||||
|
||||
public override bool IsInvulnerable { get { return true; } }
|
||||
|
||||
private string _Announcement;
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string Announcement
|
||||
{
|
||||
get
|
||||
{
|
||||
return _Announcement;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (String.IsNullOrEmpty(value))
|
||||
{
|
||||
AnnouncementExpires = DateTime.MinValue;
|
||||
|
||||
if (Timer != null)
|
||||
{
|
||||
Timer.Stop();
|
||||
Timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (value != _Announcement)
|
||||
{
|
||||
AnnouncementExpires = DateTime.UtcNow + TimeSpan.FromHours(CityLoyaltySystem.AnnouncementPeriod);
|
||||
|
||||
if (Timer != null)
|
||||
Timer.Stop();
|
||||
|
||||
Timer = Timer.DelayCall(TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(3), DoAnnouncement);
|
||||
Timer.Start();
|
||||
}
|
||||
|
||||
_Announcement = value;
|
||||
|
||||
if (_Announcement != null)
|
||||
DoAnnouncement();
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime AnnouncementExpires { get; set; }
|
||||
|
||||
public Timer Timer { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public CityHerald(City city) : base(AIType.AI_Vendor, FightMode.None, 10, 1, .4, .2)
|
||||
{
|
||||
City = city;
|
||||
SpeechHue = 0x3B2;
|
||||
Female = Utility.RandomDouble() > 0.75;
|
||||
Blessed = true;
|
||||
|
||||
Name = Female ? NameList.RandomName("female") : NameList.RandomName("male");
|
||||
Title = "the city herald";
|
||||
|
||||
Body = Female ? 0x191 : 0x190;
|
||||
HairItemID = Race.RandomHair(Female);
|
||||
FacialHairItemID = Race.RandomFacialHair(Female);
|
||||
HairHue = Race.RandomHairHue();
|
||||
Hue = Race.RandomSkinHue();
|
||||
|
||||
SetStr(150);
|
||||
SetInt(50);
|
||||
SetDex(150);
|
||||
|
||||
EquipItem(new Doublet(1157));
|
||||
EquipItem(new FancyShirt(1908));
|
||||
EquipItem(new FeatheredHat(1157));
|
||||
EquipItem(new LongPants(1908));
|
||||
|
||||
var boots = new Boots();
|
||||
boots.Hue = 2012;
|
||||
EquipItem(boots);
|
||||
|
||||
EquipItem(new GoldRing());
|
||||
|
||||
CantWalk = true;
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
|
||||
{
|
||||
base.GetContextMenuEntries( from, list );
|
||||
|
||||
list.Add(new DonateGoldEntry(from, this));
|
||||
}
|
||||
|
||||
private class DonateGoldEntry : ContextMenuEntry
|
||||
{
|
||||
public CityHerald Herald { get; private set; }
|
||||
public Mobile Player { get; private set; }
|
||||
|
||||
public DonateGoldEntry(Mobile player, CityHerald herald) : base(1156237, 3) // Donate Gold
|
||||
{
|
||||
Player = player;
|
||||
Herald = herald;
|
||||
|
||||
Enabled = player.InRange(herald.Location, 5);
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (Player.Prompt != null)
|
||||
{
|
||||
Player.SendLocalizedMessage(1079166); // You already have a text entry request pending.
|
||||
}
|
||||
else
|
||||
{
|
||||
Player.SendLocalizedMessage(1155865); // Enter amount to deposit:
|
||||
Player.BeginPrompt(
|
||||
(from, text) =>
|
||||
{
|
||||
int amount = Utility.ToInt32(text);
|
||||
|
||||
if (amount > 0)
|
||||
{
|
||||
if (Banker.Withdraw(from, amount, true))
|
||||
{
|
||||
CityLoyaltySystem.GetCityInstance(Herald.City).AddToTreasury(from, amount, true);
|
||||
|
||||
Herald.SayTo(from, 1152926); // The City thanks you for your generosity!
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1155867); // The amount entered is invalid. Verify that there are sufficient funds to complete this transaction.
|
||||
}
|
||||
else
|
||||
from.SendLocalizedMessage(1155867); // The amount entered is invalid. Verify that there are sufficient funds to complete this transaction.
|
||||
},
|
||||
(from, text) =>
|
||||
{
|
||||
from.SendLocalizedMessage(1155867); // The amount entered is invalid. Verify that there are sufficient funds to complete this transaction.
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DoAnnouncement()
|
||||
{
|
||||
if (!String.IsNullOrEmpty(_Announcement))
|
||||
{
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, 502976); // Hear ye! Hear ye!
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(3), () =>
|
||||
{
|
||||
PublicOverheadMessage(MessageType.Regular, 0x3B2, false, _Announcement);
|
||||
});
|
||||
}
|
||||
|
||||
if (DateTime.UtcNow > AnnouncementExpires)
|
||||
{
|
||||
AnnouncementExpires = DateTime.MinValue;
|
||||
|
||||
if (Timer != null)
|
||||
{
|
||||
Timer.Stop();
|
||||
Timer = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CityHerald(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
writer.Write((int)City);
|
||||
writer.Write(_Announcement);
|
||||
writer.Write(AnnouncementExpires);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int v = reader.ReadInt();
|
||||
City = (City)reader.ReadInt();
|
||||
_Announcement = reader.ReadString();
|
||||
AnnouncementExpires = reader.ReadDateTime();
|
||||
|
||||
if (CitySystem != null)
|
||||
CitySystem.Herald = this;
|
||||
|
||||
if (DateTime.UtcNow < AnnouncementExpires)
|
||||
{
|
||||
Timer = Timer.DelayCall(TimeSpan.FromMinutes(3), TimeSpan.FromMinutes(3), DoAnnouncement);
|
||||
Timer.Start();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
221
Scripts/Services/City Loyalty System/Mobiles/GuardCaptain.cs
Normal file
221
Scripts/Services/City Loyalty System/Mobiles/GuardCaptain.cs
Normal file
@@ -0,0 +1,221 @@
|
||||
using Server.Items;
|
||||
using Server.Mobiles;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Server.ContextMenus;
|
||||
using System.Globalization;
|
||||
using Server.Gumps;
|
||||
using System.Linq;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
public class GuardCaptain : BaseCreature
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public City City { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public BoxOfRopes Box { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime NextShout { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CityLoyaltySystem CitySystem { get { return CityLoyaltySystem.GetCityInstance(City); } set { } }
|
||||
|
||||
public override bool IsInvulnerable { get { return true; } }
|
||||
|
||||
private Dictionary<PlayerMobile, DateTime> _BannerCooldown;
|
||||
|
||||
[Constructable]
|
||||
public GuardCaptain(City city) : base(AIType.AI_Vendor, FightMode.None, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
City = city;
|
||||
Female = Utility.RandomDouble() > 0.75;
|
||||
Blessed = true;
|
||||
|
||||
Name = Female ? NameList.RandomName("female") : NameList.RandomName("male");
|
||||
Title = "the guard captain";
|
||||
|
||||
Body = Female ? 0x191 : 0x190;
|
||||
HairItemID = Race.RandomHair(Female);
|
||||
FacialHairItemID = Race.RandomFacialHair(Female);
|
||||
HairHue = Race.RandomHairHue();
|
||||
Hue = Race.RandomSkinHue();
|
||||
|
||||
SetStr(150);
|
||||
SetInt(50);
|
||||
SetDex(150);
|
||||
|
||||
SetWearable(new ShortPants(1508));
|
||||
|
||||
if (Female)
|
||||
SetWearable(new FemaleStuddedChest());
|
||||
else
|
||||
SetWearable(new PlateChest());
|
||||
|
||||
SetWearable(new BodySash(1326));
|
||||
SetWearable(new Halberd());
|
||||
|
||||
CantWalk = true;
|
||||
}
|
||||
|
||||
public override void OnMovement(Mobile m, Point3D oldLocation)
|
||||
{
|
||||
if (CitySystem != null && m is PlayerMobile && InRange(m.Location, 2))
|
||||
{
|
||||
Raider raider = ((PlayerMobile)m).AllFollowers.FirstOrDefault(mob => mob is Raider && mob.InRange(this.Location, 2)) as Raider;
|
||||
|
||||
if (raider != null)
|
||||
{
|
||||
CitySystem.AwardLove(m, 1000);
|
||||
|
||||
SayTo(m, 1152250, m.Name); // Thank you, ~1_name~, for your assistance during these difficult times.
|
||||
raider.Delete();
|
||||
}
|
||||
}
|
||||
|
||||
base.OnMovement(m, oldLocation);
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries(Mobile from, List<ContextMenuEntry> entries)
|
||||
{
|
||||
base.GetContextMenuEntries(from, entries);
|
||||
|
||||
if(from is PlayerMobile)
|
||||
entries.Add(new InternalEntry(from as PlayerMobile, this));
|
||||
}
|
||||
|
||||
public class InternalEntry : ContextMenuEntry
|
||||
{
|
||||
public PlayerMobile Player { get; set; }
|
||||
public GuardCaptain Guard { get; set; }
|
||||
|
||||
public InternalEntry(PlayerMobile from, GuardCaptain guard)
|
||||
: base(1152366, 3) // City Banner
|
||||
{
|
||||
Player = from;
|
||||
Guard = guard;
|
||||
|
||||
Enabled = CityLoyaltySystem.HasCitizenship(from, Guard.City);
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
CityLoyaltySystem thisSystem = CityLoyaltySystem.GetCityInstance(Guard.City);
|
||||
CityLoyaltySystem theirSystem = CityLoyaltySystem.GetCitizenship(Player);
|
||||
|
||||
Guard.CheckBannerCooldown();
|
||||
|
||||
if (theirSystem != null && thisSystem != null && CityLoyaltySystem.HasCitizenship(Player, Guard.City))
|
||||
{
|
||||
if(Guard.IsInBannerCooldown(Player))
|
||||
Guard.SayTo(Player, 1152364, String.Format("#{0}", CityLoyaltySystem.BannerLocalization(thisSystem.City))); // I have quite a backlog of orders and I cannot satisfy your request for a ~1_ITEM~ right now.
|
||||
if (theirSystem.GetLoyaltyRating(Player) < LoyaltyRating.Adored)
|
||||
Guard.SayTo(Player, 1152363, String.Format("#{0}", CityLoyaltySystem.GetCityLocalization(thisSystem.City))); // I apologize, but you are not well-enough renowned in the city of ~1_CITY~ to make this purchase.
|
||||
else
|
||||
{
|
||||
string args = String.Format("#{0}\t{1}", CityLoyaltySystem.BannerLocalization(thisSystem.City), CityLoyaltySystem.BannerCost.ToString("N0", CultureInfo.GetCultureInfo("en-US")));
|
||||
Player.SendGump(new ConfirmCallbackGump(Player, 1049004, 1152365, Player, args, Guard.OnConfirm));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnConfirm(Mobile m, object o)
|
||||
{
|
||||
PlayerMobile pm = m as PlayerMobile;
|
||||
|
||||
if(pm != null)
|
||||
{
|
||||
if (Banker.Withdraw(pm, CityLoyaltySystem.BannerCost))
|
||||
{
|
||||
CityBannerDeed deed = new CityBannerDeed(City);
|
||||
CitySystem.AddToTreasury(m, CityLoyaltySystem.BannerCost);
|
||||
|
||||
if(pm.Backpack == null || !pm.Backpack.TryDropItem(pm, deed, false))
|
||||
{
|
||||
pm.BankBox.DropItem(deed);
|
||||
pm.SendMessage("The deed has been placed in your bank box.");
|
||||
}
|
||||
else
|
||||
pm.SendMessage("The deed has been placed in your backpack.");
|
||||
|
||||
AddToCooldown(pm);
|
||||
}
|
||||
else
|
||||
SayTo(pm, 1152302); // I am afraid your bank box does not contain the funds needed to complete this transaction.
|
||||
}
|
||||
}
|
||||
|
||||
public void AddToCooldown(PlayerMobile pm)
|
||||
{
|
||||
if (_BannerCooldown == null)
|
||||
_BannerCooldown = new Dictionary<PlayerMobile, DateTime>();
|
||||
|
||||
_BannerCooldown[pm] = DateTime.UtcNow + TimeSpan.FromHours(CityLoyaltySystem.BannerCooldownDuration);
|
||||
}
|
||||
|
||||
public bool IsInBannerCooldown(PlayerMobile m)
|
||||
{
|
||||
if (_BannerCooldown != null && m is PlayerMobile)
|
||||
{
|
||||
if (_BannerCooldown.ContainsKey((PlayerMobile)m))
|
||||
return _BannerCooldown[m] > DateTime.UtcNow;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CheckBannerCooldown()
|
||||
{
|
||||
if (_BannerCooldown == null || _BannerCooldown.Count == 0)
|
||||
return;
|
||||
|
||||
List<PlayerMobile> list = new List<PlayerMobile>(_BannerCooldown.Keys);
|
||||
|
||||
foreach (PlayerMobile pm in list)
|
||||
{
|
||||
if (_BannerCooldown[pm] < DateTime.UtcNow)
|
||||
_BannerCooldown.Remove(pm);
|
||||
}
|
||||
|
||||
list.Clear();
|
||||
list.TrimExcess();
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
if (NextShout < DateTime.UtcNow)
|
||||
{
|
||||
Say(Utility.Random(1152252, 6));
|
||||
NextShout = DateTime.UtcNow + TimeSpan.FromSeconds(Utility.RandomMinMax(45, 65));
|
||||
}
|
||||
}
|
||||
|
||||
public GuardCaptain(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)City);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
City = (City)reader.ReadInt();
|
||||
|
||||
if (CitySystem != null)
|
||||
CitySystem.Captain = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
166
Scripts/Services/City Loyalty System/Mobiles/Raider.cs
Normal file
166
Scripts/Services/City Loyalty System/Mobiles/Raider.cs
Normal file
@@ -0,0 +1,166 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Items;
|
||||
using System.Linq;
|
||||
using Server.Network;
|
||||
using Server.Engines.CityLoyalty;
|
||||
|
||||
namespace Server.Mobiles
|
||||
{
|
||||
public class Raider : BaseCreature
|
||||
{
|
||||
public DateTime DeleteTime { get; set; }
|
||||
|
||||
public override bool Commandable { get { return false; } }
|
||||
public override bool ReduceSpeedWithDamage { get { return false; } }
|
||||
public override bool AlwaysMurderer { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public Raider()
|
||||
: base(AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4)
|
||||
{
|
||||
Title = "the raider";
|
||||
Hue = Utility.RandomSkinHue();
|
||||
Utility.AssignRandomHair(this);
|
||||
|
||||
SetStr(150, 200);
|
||||
SetDex(125, 150);
|
||||
SetInt(95, 110);
|
||||
|
||||
SetHits(400, 650);
|
||||
SetDamage(21, 28);
|
||||
|
||||
if (this.Female = Utility.RandomBool())
|
||||
{
|
||||
Body = 0x191;
|
||||
Name = NameList.RandomName("female");
|
||||
EquipItem(new Skirt(Utility.RandomNeutralHue()));
|
||||
}
|
||||
else
|
||||
{
|
||||
Body = 0x190;
|
||||
Name = NameList.RandomName("male");
|
||||
EquipItem(new ShortPants(Utility.RandomNeutralHue()));
|
||||
}
|
||||
|
||||
SetDamageType(ResistanceType.Physical, 100);
|
||||
|
||||
SetResistance(ResistanceType.Physical, 45, 55);
|
||||
SetResistance(ResistanceType.Fire, 45, 55);
|
||||
SetResistance(ResistanceType.Cold, 45, 55);
|
||||
SetResistance(ResistanceType.Poison, 45, 55);
|
||||
SetResistance(ResistanceType.Energy, 45, 55);
|
||||
|
||||
SetSkill(SkillName.MagicResist, 50.0, 75.5);
|
||||
SetSkill(SkillName.Archery, 90.0, 105.5);
|
||||
SetSkill(SkillName.Tactics, 90.0, 105.5);
|
||||
SetSkill(SkillName.Anatomy, 90.0, 105.5);
|
||||
|
||||
Fame = 7500;
|
||||
Karma = -7500;
|
||||
|
||||
SetWearable(new TricorneHat());
|
||||
SetWearable(new LeatherArms());
|
||||
SetWearable(new FancyShirt());
|
||||
SetWearable(new Cutlass());
|
||||
SetWearable(new Boots(Utility.RandomNeutralHue()));
|
||||
SetWearable(new GoldEarrings());
|
||||
|
||||
Item bow;
|
||||
|
||||
switch (Utility.Random(4))
|
||||
{
|
||||
default:
|
||||
case 0: bow = new CompositeBow(); PackItem(new Arrow(25)); break;
|
||||
case 1: bow = new Crossbow(); PackItem(new Bolt(25)); break;
|
||||
case 2: bow = new Bow(); PackItem(new Arrow(25)); break;
|
||||
case 3: bow = new HeavyCrossbow(); PackItem(new Bolt(25)); break;
|
||||
}
|
||||
|
||||
SetWearable(bow);
|
||||
|
||||
ControlSlots = 0;
|
||||
}
|
||||
|
||||
public bool TryArrest(Mobile m)
|
||||
{
|
||||
if (ControlMaster != null)
|
||||
{
|
||||
m.SendLocalizedMessage(1152247); // That person is already under arrest.
|
||||
}
|
||||
else if (m is PlayerMobile && ((PlayerMobile)m).AllFollowers.FirstOrDefault(mob => mob is Raider) != null)
|
||||
{
|
||||
m.SendLocalizedMessage(1152249); // You already have a prisoner.
|
||||
}
|
||||
else if (Hits > ((double)HitsMax / 10))
|
||||
{
|
||||
m.SendLocalizedMessage(1152229); // That person won't sit still for it! A more aggressive approach is in order.
|
||||
m.NonlocalOverheadMessage(MessageType.Regular, 0x3B2, 1152237, String.Format("{0}\t{1}", m.Name, this.Name, "raider"));
|
||||
}
|
||||
else
|
||||
{
|
||||
DeleteTime = DateTime.UtcNow + TimeSpan.FromHours(1);
|
||||
|
||||
SetControlMaster(m);
|
||||
IsBonded = false;
|
||||
ControlTarget = m;
|
||||
ControlOrder = OrderType.Follow;
|
||||
|
||||
m.SendLocalizedMessage(1152236, this.Name); // You arrest the ~1_name~. Take the criminal to the guard captain.
|
||||
m.NonlocalOverheadMessage(MessageType.Regular, 0x3B2, 1152238, String.Format("{0}\t{1}", m.Name, this.Name));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void OnThink()
|
||||
{
|
||||
base.OnThink();
|
||||
|
||||
CheckDelete();
|
||||
}
|
||||
|
||||
public void CheckDelete()
|
||||
{
|
||||
if (DeleteTime != DateTime.MinValue && DateTime.UtcNow > DeleteTime)
|
||||
{
|
||||
if (ControlMaster != null && ControlMaster.NetState != null)
|
||||
{
|
||||
ControlMaster.SendLocalizedMessage(1152248); // You did not take your prisoner to the Guard Captain in time.
|
||||
}
|
||||
|
||||
Delete();
|
||||
}
|
||||
}
|
||||
|
||||
public override void GenerateLoot()
|
||||
{
|
||||
AddLoot(LootPack.FilthyRich, 2);
|
||||
}
|
||||
|
||||
public Raider(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write((int)0);
|
||||
|
||||
Timer.DelayCall(TimeSpan.FromSeconds(10), CheckDelete);
|
||||
|
||||
writer.Write(DeleteTime);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
DeleteTime = reader.ReadDateTime();
|
||||
}
|
||||
}
|
||||
}
|
||||
226
Scripts/Services/City Loyalty System/Setup.cs
Normal file
226
Scripts/Services/City Loyalty System/Setup.cs
Normal file
@@ -0,0 +1,226 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Items;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Server.Commands;
|
||||
using Server.Regions;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
public class CityLoyaltySetup
|
||||
{
|
||||
public static void Initialize()
|
||||
{
|
||||
if (CityLoyaltySystem.Enabled)
|
||||
{
|
||||
CommandSystem.Register("SetupCityLoyaltySystem", AccessLevel.GameMaster, Setup);
|
||||
CommandSystem.Register("DeleteCityLoyaltySystem", AccessLevel.GameMaster, Delete);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Delete(CommandEventArgs e)
|
||||
{
|
||||
Mobile m = e.Mobile;
|
||||
|
||||
CityLoyaltySystem.Cities.ForEach(city =>
|
||||
{
|
||||
if (city.Stone != null) city.Stone.Delete();
|
||||
if (city.Herald != null) city.Herald.Delete();
|
||||
|
||||
if (city.Captain != null)
|
||||
{
|
||||
if (city.Captain.Box != null)
|
||||
city.Captain.Box.Delete();
|
||||
|
||||
city.Captain.Delete();
|
||||
}
|
||||
|
||||
if (city.Minister != null)
|
||||
{
|
||||
if (city.Minister.DonationCrate != null)
|
||||
city.Minister.DonationCrate.Delete();
|
||||
|
||||
if (city.Minister.DonationPost != null)
|
||||
city.Minister.DonationPost.Delete();
|
||||
|
||||
city.Minister.Delete();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void Setup(CommandEventArgs e)
|
||||
{
|
||||
Mobile m = e.Mobile;
|
||||
|
||||
TradeMinister minister;
|
||||
CityHerald herald;
|
||||
GuardCaptain capt;
|
||||
CityStone stone;
|
||||
CityItemDonation itemdonation;
|
||||
CityPetDonation petdonation;
|
||||
BoxOfRopes box;
|
||||
CityMessageBoard board;
|
||||
|
||||
foreach (int c in Enum.GetValues(typeof(City)))
|
||||
{
|
||||
City city = (City)c;
|
||||
CityLoyaltySystem sys = null;
|
||||
|
||||
switch (city)
|
||||
{
|
||||
case City.Moonglow: sys = CityLoyaltySystem.Moonglow; break;
|
||||
case City.Britain: sys = CityLoyaltySystem.Britain; break;
|
||||
case City.Jhelom: sys = CityLoyaltySystem.Jhelom; break;
|
||||
case City.Yew: sys = CityLoyaltySystem.Yew; break;
|
||||
case City.Minoc: sys = CityLoyaltySystem.Minoc; break;
|
||||
case City.Trinsic: sys = CityLoyaltySystem.Trinsic; break;
|
||||
case City.SkaraBrae: sys = CityLoyaltySystem.SkaraBrae; break;
|
||||
case City.NewMagincia: sys = CityLoyaltySystem.NewMagincia; break;
|
||||
case City.Vesper: sys = CityLoyaltySystem.Vesper; break;
|
||||
}
|
||||
|
||||
if (sys != null)
|
||||
{
|
||||
minister = new TradeMinister(sys.City);
|
||||
herald = new CityHerald(sys.City);
|
||||
capt = new GuardCaptain(sys.City);
|
||||
stone = new CityStone(sys);
|
||||
itemdonation = new CityItemDonation(sys.City, minister);
|
||||
petdonation = new CityPetDonation(sys.City, minister);
|
||||
box = new BoxOfRopes(sys.City);
|
||||
board = new CityMessageBoard(sys.City, 0xA0C5);
|
||||
|
||||
if (!HasType(sys, minister.GetType()))
|
||||
{
|
||||
sys.Minister = minister;
|
||||
minister.MoveToWorld(sys.Definition.TradeMinisterLocation, CityLoyaltySystem.SystemMap);
|
||||
}
|
||||
else
|
||||
minister.Delete();
|
||||
|
||||
if (!HasType(sys, herald.GetType()))
|
||||
{
|
||||
sys.Herald = herald;
|
||||
herald.MoveToWorld(sys.Definition.HeraldLocation, CityLoyaltySystem.SystemMap);
|
||||
}
|
||||
else
|
||||
herald.Delete();
|
||||
|
||||
if (!HasType(sys, capt.GetType()))
|
||||
{
|
||||
sys.Captain = capt;
|
||||
capt.MoveToWorld(sys.Definition.GuardsmanLocation, CityLoyaltySystem.SystemMap);
|
||||
}
|
||||
else
|
||||
capt.Delete();
|
||||
|
||||
if (!HasType(sys, stone.GetType()))
|
||||
{
|
||||
sys.Stone = stone;
|
||||
stone.MoveToWorld(sys.Definition.StoneLocation, CityLoyaltySystem.SystemMap);
|
||||
}
|
||||
else
|
||||
stone.Delete();
|
||||
|
||||
if (!HasType(sys, itemdonation.GetType()))
|
||||
itemdonation.MoveToWorld(new Point3D(sys.Definition.TradeMinisterLocation.X, sys.Definition.TradeMinisterLocation.Y - 1, sys.Definition.TradeMinisterLocation.Z), CityLoyaltySystem.SystemMap);
|
||||
else
|
||||
itemdonation.Delete();
|
||||
|
||||
if (!HasType(sys, petdonation.GetType()))
|
||||
petdonation.MoveToWorld(new Point3D(sys.Definition.TradeMinisterLocation.X, sys.Definition.TradeMinisterLocation.Y - 2, sys.Definition.TradeMinisterLocation.Z), CityLoyaltySystem.SystemMap);
|
||||
else
|
||||
petdonation.Delete();
|
||||
|
||||
if (!HasType(sys, box.GetType()))
|
||||
box.MoveToWorld(new Point3D(sys.Definition.GuardsmanLocation.X, sys.Definition.GuardsmanLocation.Y - 1, sys.Definition.GuardsmanLocation.Z), CityLoyaltySystem.SystemMap);
|
||||
else
|
||||
box.Delete();
|
||||
|
||||
if (!HasType(sys, board.GetType()))
|
||||
{
|
||||
board.MoveToWorld(sys.Definition.BoardLocation, CityLoyaltySystem.SystemMap);
|
||||
sys.Board = board;
|
||||
}
|
||||
else
|
||||
board.Delete();
|
||||
|
||||
sys.CanUtilize = true;
|
||||
|
||||
m.SendMessage("{0} setup!", sys.Definition.Name);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
string name;
|
||||
Point3D p;
|
||||
|
||||
switch (i)
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
name = "Ocllo";
|
||||
p = new Point3D(3674, 2648, 0);
|
||||
break;
|
||||
case 1:
|
||||
name = "Nujel'm";
|
||||
p = new Point3D(3765, 1219, 0);
|
||||
break;
|
||||
case 2:
|
||||
name = "Serpent's Hold";
|
||||
p = new Point3D(3017, 3452, 15);
|
||||
break;
|
||||
}
|
||||
|
||||
Region r = Region.Regions.FirstOrDefault(reg => reg.Map == Map.Felucca && reg.Name == name);
|
||||
|
||||
if (r != null)
|
||||
{
|
||||
var slim = new SlimTheFence();
|
||||
|
||||
if (!HasType(r, slim.GetType()))
|
||||
slim.MoveToWorld(p, Map.Felucca);
|
||||
else
|
||||
slim.Delete();
|
||||
}
|
||||
else
|
||||
Console.WriteLine("WARNING: {0} Region not found!", name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static bool HasType(CityLoyaltySystem system, Type t)
|
||||
{
|
||||
return HasType(system.Definition.Region, t);
|
||||
}
|
||||
|
||||
public static bool HasType(Region r, Type t)
|
||||
{
|
||||
if (r == null)
|
||||
return false;
|
||||
|
||||
if (t.IsSubclassOf(typeof(Mobile)))
|
||||
{
|
||||
foreach (Mobile m in r.GetEnumeratedMobiles())
|
||||
{
|
||||
if (m.GetType() == t)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (t.IsSubclassOf(typeof(Item)))
|
||||
{
|
||||
foreach (Item i in r.GetEnumeratedItems())
|
||||
{
|
||||
if (i.GetType() == t)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
313
Scripts/Services/City Loyalty System/Trading/DonationCrate.cs
Normal file
313
Scripts/Services/City Loyalty System/Trading/DonationCrate.cs
Normal file
@@ -0,0 +1,313 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Gumps;
|
||||
using Server.Engines.Points;
|
||||
using System.Collections.Generic;
|
||||
using Server.Targeting;
|
||||
using Server.Items;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
public class CityDonationItem : Item
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CityLoyaltySystem CitySystem { get { return CityLoyaltySystem.GetCityInstance(City); } set { } }
|
||||
|
||||
public City City { get; protected set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TradeMinister Minister { get; set; }
|
||||
|
||||
public Dictionary<Type, int> Table { get; protected set; }
|
||||
|
||||
public virtual bool Animals { get { return false; } }
|
||||
|
||||
public CityDonationItem(City city, TradeMinister minister, int itemid) : base(itemid)
|
||||
{
|
||||
City = city;
|
||||
Minister = minister;
|
||||
Movable = false;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if (!CityLoyaltySystem.IsSetup())
|
||||
return;
|
||||
|
||||
if(Animals && Table != null && Table.Count > 0)
|
||||
{
|
||||
from.Target = new InternalTarget(this);
|
||||
from.SendLocalizedMessage(1152936); // Which animal do you wish to donate?
|
||||
}
|
||||
else if (!Animals)
|
||||
{
|
||||
SendMessageTo(from, 1152928); // If you wish to donate to the City simply drop the items into the crate.
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnDragDrop(Mobile from, Item dropped)
|
||||
{
|
||||
if (!CityLoyaltySystem.IsSetup())
|
||||
return false;
|
||||
|
||||
if(!Animals && Table != null && Table.Count > 0)
|
||||
{
|
||||
int love = 0;
|
||||
|
||||
if (dropped is Container)
|
||||
{
|
||||
List<Item> items = new List<Item>(dropped.Items);
|
||||
|
||||
foreach (Item item in items)
|
||||
{
|
||||
love += CheckTurnin(item);
|
||||
}
|
||||
|
||||
items.Clear();
|
||||
items.TrimExcess();
|
||||
}
|
||||
else
|
||||
{
|
||||
love = CheckTurnin(dropped);
|
||||
}
|
||||
|
||||
if (love > 0)
|
||||
{
|
||||
CityLoyaltySystem.GetCityInstance(City).AwardLove(from, love);
|
||||
SendMessageTo(from, 1152926); // The City thanks you for your generosity!
|
||||
return !(dropped is Container);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendMessageTo(from, 1152927); // Your generosity is appreciated but the City does not require this item.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private int CheckTurnin(Item item)
|
||||
{
|
||||
Type dropType = item.GetType();
|
||||
int love = 0;
|
||||
|
||||
foreach (KeyValuePair<Type, int> kvp in Table)
|
||||
{
|
||||
Type checkType = kvp.Key;
|
||||
|
||||
if (checkType == dropType || dropType.IsSubclassOf(checkType))
|
||||
{
|
||||
CityLoyaltySystem sys = CityLoyaltySystem.GetCityInstance(City);
|
||||
|
||||
if (sys != null)
|
||||
{
|
||||
// TODO: If anything adds to treasure, change this
|
||||
if (item is MaritimeCargo)
|
||||
{
|
||||
AddToTreasury(sys, (MaritimeCargo)item);
|
||||
}
|
||||
|
||||
item.Delete();
|
||||
love = Table[checkType] * item.Amount;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return love;
|
||||
}
|
||||
|
||||
private void AddToTreasury(CityLoyaltySystem system, MaritimeCargo cargo)
|
||||
{
|
||||
if (system != null)
|
||||
{
|
||||
if (cargo.City == City)
|
||||
{
|
||||
system.AddToTreasury(null, cargo.GetAwardAmount() * 1000);
|
||||
}
|
||||
else
|
||||
{
|
||||
system.AddToTreasury(null, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
public CityDonationItem Item { get; private set; }
|
||||
|
||||
public InternalTarget(CityDonationItem item) : base(3, false, TargetFlags.None)
|
||||
{
|
||||
Item = item;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
if(targeted is BaseCreature)
|
||||
{
|
||||
BaseCreature bc = targeted as BaseCreature;
|
||||
Type t = bc.GetType();
|
||||
|
||||
if(bc.Controlled && !bc.Summoned && bc.GetMaster() == from)
|
||||
{
|
||||
if(Item.Table.ContainsKey(t))
|
||||
{
|
||||
CityLoyaltySystem sys = CityLoyaltySystem.GetCityInstance(Item.City);
|
||||
|
||||
if(sys != null)
|
||||
{
|
||||
bc.Delete();
|
||||
sys.AwardLove(from, Item.Table[t]);
|
||||
|
||||
Item.SendMessageTo(from, 1152926); // The City thanks you for your generosity!
|
||||
}
|
||||
}
|
||||
else
|
||||
Item.SendMessageTo(from, 1152929); // That does not look like an animal the City is in need of.
|
||||
}
|
||||
else
|
||||
Item.SendMessageTo(from, 1152930); // Erm. Uhh. I don't think that'd enjoy the stables much...
|
||||
}
|
||||
else
|
||||
Item.SendMessageTo(from, 1152930); // Erm. Uhh. I don't think that'd enjoy the stables much...
|
||||
}
|
||||
}
|
||||
|
||||
private void SendMessageTo(Mobile m, int message)
|
||||
{
|
||||
if (Minister != null)
|
||||
Minister.SayTo(m, message);
|
||||
else
|
||||
m.SendLocalizedMessage(message);
|
||||
}
|
||||
|
||||
public CityDonationItem(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)City);
|
||||
writer.Write(Minister);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int v = reader.ReadInt();
|
||||
|
||||
City = (City)reader.ReadInt();
|
||||
Minister = reader.ReadMobile() as TradeMinister;
|
||||
}
|
||||
}
|
||||
|
||||
public class CityItemDonation : CityDonationItem
|
||||
{
|
||||
[Constructable]
|
||||
public CityItemDonation(City city, TradeMinister minister) : base(city, minister, 0xE3C)
|
||||
{
|
||||
Table = ItemTable;
|
||||
|
||||
if (CitySystem != null && CitySystem.Minister != null)
|
||||
CitySystem.Minister.DonationCrate = this;
|
||||
}
|
||||
|
||||
public static Dictionary<Type, int> ItemTable { get; set; }
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
ItemTable = new Dictionary<Type, int>();
|
||||
|
||||
ItemTable.Add(typeof(BaseWoodBoard), 10);
|
||||
ItemTable.Add(typeof(BaseIngot), 10);
|
||||
ItemTable.Add(typeof(BaseHides), 10);
|
||||
ItemTable.Add(typeof(BaseLeather), 10);
|
||||
ItemTable.Add(typeof(RawRibs), 10);
|
||||
ItemTable.Add(typeof(BreadLoaf), 10);
|
||||
ItemTable.Add(typeof(RawFishSteak), 10);
|
||||
ItemTable.Add(typeof(BaseCrabAndLobster), 15);
|
||||
ItemTable.Add(typeof(BasePotion), 15);
|
||||
ItemTable.Add(typeof(Bow), 20);
|
||||
ItemTable.Add(typeof(Crossbow), 20);
|
||||
ItemTable.Add(typeof(MaritimeCargo), 50);
|
||||
}
|
||||
|
||||
public CityItemDonation(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int v = reader.ReadInt();
|
||||
|
||||
Table = ItemTable;
|
||||
|
||||
if (CitySystem != null && CitySystem.Minister != null)
|
||||
CitySystem.Minister.DonationCrate = this;
|
||||
}
|
||||
}
|
||||
|
||||
public class CityPetDonation : CityDonationItem
|
||||
{
|
||||
public override bool Animals { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public CityPetDonation(City city, TradeMinister minister) : base(city, minister, 0x14E7)
|
||||
{
|
||||
Table = PetTable;
|
||||
|
||||
if (CitySystem != null && CitySystem.Minister != null)
|
||||
CitySystem.Minister.DonationPost = this;
|
||||
}
|
||||
|
||||
public static Dictionary<Type, int> PetTable { get; set; }
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
PetTable = new Dictionary<Type, int>();
|
||||
|
||||
PetTable.Add(typeof(Dog), 10);
|
||||
PetTable.Add(typeof(Cat), 10);
|
||||
PetTable.Add(typeof(Cow), 10);
|
||||
PetTable.Add(typeof(Goat), 10);
|
||||
PetTable.Add(typeof(Horse), 10);
|
||||
PetTable.Add(typeof(Sheep), 10);
|
||||
PetTable.Add(typeof(Pig), 10);
|
||||
PetTable.Add(typeof(Chicken), 10);
|
||||
}
|
||||
|
||||
public CityPetDonation(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int v = reader.ReadInt();
|
||||
|
||||
Table = PetTable;
|
||||
|
||||
if (CitySystem != null && CitySystem.Minister != null)
|
||||
CitySystem.Minister.DonationPost = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
326
Scripts/Services/City Loyalty System/Trading/Items/CityBooks.cs
Normal file
326
Scripts/Services/City Loyalty System/Trading/Items/CityBooks.cs
Normal file
@@ -0,0 +1,326 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.CityLoyalty;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public abstract class CityBook : Item
|
||||
{
|
||||
public abstract int Title { get; }
|
||||
public abstract int Content { get; }
|
||||
|
||||
public CityBook() : base(4030)
|
||||
{
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if(Title > 0)
|
||||
list.Add(Title);
|
||||
|
||||
list.Add(1154760, "Adamu Edom"); // By: ~1_NAME~
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile m)
|
||||
{
|
||||
if (IsChildOf(m.Backpack))
|
||||
{
|
||||
Gump g = new Gump(150, 150);
|
||||
g.AddImage(0, 0, 30236);
|
||||
g.AddHtmlLocalized(110, 30, 350, 630, Content, false, false);
|
||||
|
||||
m.SendGump(g);
|
||||
}
|
||||
}
|
||||
|
||||
public static CityBook GetRandom()
|
||||
{
|
||||
switch (Utility.Random(9))
|
||||
{
|
||||
default:
|
||||
case 0: return new LoyaltyBookBritain();
|
||||
case 1: return new LoyaltyBookYew();
|
||||
case 2: return new LoyaltyBookMoonglow();
|
||||
case 3: return new LoyaltyBookNewMagincia();
|
||||
case 4: return new LoyaltyBookVesper();
|
||||
case 5: return new LoyaltyBookSkaraBrae();
|
||||
case 6: return new LoyaltyBookJhelom();
|
||||
case 7: return new LoyaltyBookMinoc();
|
||||
case 8: return new LoyaltyBookTrinsic();
|
||||
}
|
||||
}
|
||||
|
||||
public CityBook(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class LoyaltyBookYew : CityBook
|
||||
{
|
||||
public override int Title { get { return 1153933; } }
|
||||
public override int Content { get { return 1152698; } }
|
||||
|
||||
[Constructable]
|
||||
public LoyaltyBookYew()
|
||||
{
|
||||
}
|
||||
|
||||
public LoyaltyBookYew(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class LoyaltyBookJhelom : CityBook
|
||||
{
|
||||
public override int Title { get { return 1153934; } }
|
||||
public override int Content { get { return 1153436; } }
|
||||
|
||||
[Constructable]
|
||||
public LoyaltyBookJhelom()
|
||||
{
|
||||
}
|
||||
|
||||
public LoyaltyBookJhelom(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class LoyaltyBookMoonglow : CityBook
|
||||
{
|
||||
public override int Title { get { return 1153935; } }
|
||||
public override int Content { get { return 1153437; } }
|
||||
|
||||
[Constructable]
|
||||
public LoyaltyBookMoonglow()
|
||||
{
|
||||
}
|
||||
|
||||
public LoyaltyBookMoonglow(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class LoyaltyBookTrinsic : CityBook
|
||||
{
|
||||
public override int Title { get { return 1153727; } }
|
||||
public override int Content { get { return 1151755; } }
|
||||
|
||||
[Constructable]
|
||||
public LoyaltyBookTrinsic()
|
||||
{
|
||||
}
|
||||
|
||||
public LoyaltyBookTrinsic(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class LoyaltyBookMinoc : CityBook
|
||||
{
|
||||
public override int Title { get { return 1153728; } }
|
||||
public override int Content { get { return 1152317; } }
|
||||
|
||||
[Constructable]
|
||||
public LoyaltyBookMinoc()
|
||||
{
|
||||
}
|
||||
|
||||
public LoyaltyBookMinoc(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class LoyaltyBookNewMagincia : CityBook
|
||||
{
|
||||
public override int Title { get { return 1153008; } }
|
||||
public override int Content { get { return 1153723; } }
|
||||
|
||||
[Constructable]
|
||||
public LoyaltyBookNewMagincia()
|
||||
{
|
||||
}
|
||||
|
||||
public LoyaltyBookNewMagincia(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class LoyaltyBookVesper : CityBook
|
||||
{
|
||||
public override int Title { get { return 1153012; } }
|
||||
public override int Content { get { return 1153724; } }
|
||||
|
||||
[Constructable]
|
||||
public LoyaltyBookVesper()
|
||||
{
|
||||
}
|
||||
|
||||
public LoyaltyBookVesper(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class LoyaltyBookSkaraBrae : CityBook
|
||||
{
|
||||
public override int Title { get { return 0; } }
|
||||
public override int Content { get { return 1153725; } }
|
||||
|
||||
[Constructable]
|
||||
public LoyaltyBookSkaraBrae()
|
||||
{
|
||||
}
|
||||
|
||||
public LoyaltyBookSkaraBrae(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
|
||||
public class LoyaltyBookBritain : CityBook
|
||||
{
|
||||
public override int Title { get { return 1153726; } }
|
||||
public override int Content { get { return 1151754; } }
|
||||
|
||||
[Constructable]
|
||||
public LoyaltyBookBritain()
|
||||
{
|
||||
}
|
||||
|
||||
public LoyaltyBookBritain(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.CityLoyalty;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ExpiredVoucher : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1151749; } } // Expired Voucher for a Free Drink at the Fortune's Fire Casino
|
||||
|
||||
[Constructable]
|
||||
public ExpiredVoucher()
|
||||
: base(0x2831)
|
||||
{
|
||||
}
|
||||
|
||||
public ExpiredVoucher(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.CityLoyalty;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class ForgedArtwork : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1151750; } } // Forged Artwork from King Blackthorn's Collection
|
||||
|
||||
[Constructable]
|
||||
public ForgedArtwork() : base(Utility.Random(0x1224, 5))
|
||||
{
|
||||
Weight = 10;
|
||||
}
|
||||
|
||||
public ForgedArtwork(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.CityLoyalty;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class LittleBlackBook : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1151751; } } // Slim the Fence's little black book
|
||||
|
||||
[Constructable]
|
||||
public LittleBlackBook()
|
||||
: base(4030)
|
||||
{
|
||||
Hue = 1932;
|
||||
}
|
||||
|
||||
public LittleBlackBook(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.CityLoyalty;
|
||||
using Server.Gumps;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class MysteriousNote : Item
|
||||
{
|
||||
public override int LabelNumber { get { return 1151753; } } // A Mysterious Note
|
||||
|
||||
[Constructable]
|
||||
public MysteriousNote()
|
||||
: base(0x14ED)
|
||||
{
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
Gump g = new Gump(100, 100);
|
||||
|
||||
g.AddBackground(0, 0, 404, 325, 9380);
|
||||
|
||||
/*You unfurl the parchment, it appears to be a handwritten note*<br><br>Taking up delivery of goods fer
|
||||
* the crown are ya? Well...maybe yer interested in a bit of something fer yerself? Look fer me in Felucca...
|
||||
* the taverns of Ocllo, Nujelm, & Serpent's Hold if ye want to fence yer goods.<br><br>-A Friend*/
|
||||
|
||||
g.AddHtmlLocalized(37, 50, 340, 225, 1151735, 0xC63, false, true);
|
||||
|
||||
from.SendGump(g);
|
||||
}
|
||||
|
||||
public MysteriousNote(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.CityLoyalty;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class RewardSign : Sign, IEngravable
|
||||
{
|
||||
public string EngravedText { get; set; }
|
||||
|
||||
[Constructable]
|
||||
public RewardSign() : base((SignType)Utility.RandomMinMax(31, 58), Utility.RandomBool() ? SignFacing.North : SignFacing.West)
|
||||
{
|
||||
Movable = true;
|
||||
}
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
if (!String.IsNullOrEmpty(EngravedText))
|
||||
{
|
||||
list.Add(1072305, EngravedText); // Engraved: ~1_INSCRIPTION~
|
||||
}
|
||||
}
|
||||
|
||||
public RewardSign(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(EngravedText);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
EngravedText = reader.ReadString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.Engines.CityLoyalty;
|
||||
|
||||
namespace Server.Items
|
||||
{
|
||||
public class SlimsShadowVeil : LeatherMempo
|
||||
{
|
||||
public override int LabelNumber { get { return 1154906; } } // Slim's Shadow Veil
|
||||
|
||||
[Constructable]
|
||||
public SlimsShadowVeil()
|
||||
{
|
||||
Hue = 1932;
|
||||
Attributes.CastSpeed = 1;
|
||||
}
|
||||
|
||||
public SlimsShadowVeil(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
162
Scripts/Services/City Loyalty System/Trading/Mobiles/Slim.cs
Normal file
162
Scripts/Services/City Loyalty System/Trading/Mobiles/Slim.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Points;
|
||||
using Server.Targeting;
|
||||
using Server.Gumps;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Misc;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
public class SlimTheFence : BaseCreature
|
||||
{
|
||||
public override bool IsInvulnerable { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public SlimTheFence() : base(AIType.AI_Vendor, FightMode.None, 10, 1, .4, .2)
|
||||
{
|
||||
Body = 0x190;
|
||||
SpeechHue = 0x3B2;
|
||||
Blessed = true;
|
||||
|
||||
Name = "Slim";
|
||||
Title = "the Fence";
|
||||
|
||||
HairItemID = 8264;
|
||||
FacialHairItemID = 8269;
|
||||
|
||||
HairHue = 1932;
|
||||
FacialHairHue = 1932;
|
||||
Hue = Race.RandomSkinHue();
|
||||
|
||||
SetStr(150);
|
||||
SetInt(50);
|
||||
SetDex(150);
|
||||
|
||||
EquipItem(new JinBaori(1932));
|
||||
EquipItem(new FancyShirt(1932));
|
||||
EquipItem(new LongPants(1));
|
||||
|
||||
var boots = new Boots();
|
||||
boots.Hue = 1;
|
||||
EquipItem(boots);
|
||||
|
||||
CantWalk = true;
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
|
||||
{
|
||||
base.GetContextMenuEntries( from, list );
|
||||
|
||||
list.Add(new TurnInEntry(from, this));
|
||||
}
|
||||
|
||||
private class TurnInEntry : ContextMenuEntry
|
||||
{
|
||||
public SlimTheFence Slim { get; private set; }
|
||||
public Mobile Player { get; private set; }
|
||||
|
||||
public TurnInEntry(Mobile player, SlimTheFence slim) : base(1151729, 3) // Turn in a trade order
|
||||
{
|
||||
Player = player;
|
||||
Slim = slim;
|
||||
|
||||
Enabled = CityTradeSystem.HasTrade(Player);
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (CityTradeSystem.HasTrade(Player))
|
||||
{
|
||||
Player.Target = new InternalTarget(Slim);
|
||||
Player.SendLocalizedMessage(1151730); // Target the trade order you wish to turn in.
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
public SlimTheFence Slim { get; private set; }
|
||||
|
||||
public InternalTarget(SlimTheFence slim) : base(-1, false, TargetFlags.None)
|
||||
{
|
||||
Slim = slim;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
TradeOrderCrate order = targeted as TradeOrderCrate;
|
||||
|
||||
if(order != null)
|
||||
{
|
||||
if (CityLoyaltySystem.CityTrading.TryTurnInToSlim(from, order, Slim))
|
||||
{
|
||||
if (order.Entry != null && order.Entry.Distance > 0)
|
||||
{
|
||||
from.AddToBackpack(Slim.GiveAward());
|
||||
from.SendLocalizedMessage(1073621); // Your reward has been placed in your backpack.
|
||||
}
|
||||
|
||||
Titles.AwardKarma(from, -100, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1151731); // That is not a valid trade order. Please try again.
|
||||
from.Target = new InternalTarget(Slim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Item GiveAward()
|
||||
{
|
||||
if (0.05 > Utility.RandomDouble())
|
||||
{
|
||||
switch (Utility.Random(4))
|
||||
{
|
||||
case 0: return new ExpiredVoucher();
|
||||
case 1: return new ForgedArtwork();
|
||||
case 2: return new LittleBlackBook();
|
||||
case 3: return new SlimsShadowVeil();
|
||||
}
|
||||
}
|
||||
|
||||
switch (Utility.Random(3))
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
return new Skeletonkey();
|
||||
case 1:
|
||||
Item item = Loot.RandomArmorOrShieldOrWeaponOrJewelry(false, false, true);
|
||||
|
||||
int min, max;
|
||||
TreasureMapChest.GetRandomItemStat(out min, out max, 1.0);
|
||||
|
||||
RunicReforging.GenerateRandomItem(item, 0, min, max, this.Map);
|
||||
return item;
|
||||
case 2:
|
||||
return ScrollOfTranscendence.CreateRandom(1, 10);
|
||||
}
|
||||
}
|
||||
|
||||
public SlimTheFence(Serial serial)
|
||||
: base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int v = reader.ReadInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,343 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Points;
|
||||
using Server.Targeting;
|
||||
using Server.Gumps;
|
||||
using Server.Network;
|
||||
using System.Collections.Generic;
|
||||
using Server.Items;
|
||||
using Server.Misc;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
public class TradeMinister : BaseCreature
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public City City { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CityLoyaltySystem CitySystem { get { return CityLoyaltySystem.GetCityInstance(City); } set { } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CityItemDonation DonationCrate { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public CityPetDonation DonationPost { get; set; }
|
||||
|
||||
public override bool IsInvulnerable { get { return true; } }
|
||||
|
||||
[Constructable]
|
||||
public TradeMinister(City city) : base(AIType.AI_Vendor, FightMode.None, 10, 1, .4, .2)
|
||||
{
|
||||
City = city;
|
||||
SpeechHue = 0x3B2;
|
||||
Female = Utility.RandomDouble() > 0.75;
|
||||
Blessed = true;
|
||||
|
||||
Name = Female ? NameList.RandomName("female") : NameList.RandomName("male");
|
||||
Title = "the minister of trade";
|
||||
|
||||
Body = Female ? 0x191 : 0x190;
|
||||
HairItemID = Race.RandomHair(Female);
|
||||
FacialHairItemID = Race.RandomFacialHair(Female);
|
||||
HairHue = Race.RandomHairHue();
|
||||
Hue = Race.RandomSkinHue();
|
||||
|
||||
SetStr(150);
|
||||
SetInt(50);
|
||||
SetDex(150);
|
||||
|
||||
EquipItem(new Cloak(1157));
|
||||
EquipItem(new BodySash(1326));
|
||||
|
||||
var chest = new ChainChest();
|
||||
chest.Hue = 1908;
|
||||
EquipItem(chest);
|
||||
|
||||
var boots = new ThighBoots();
|
||||
boots.Hue = 1908;
|
||||
EquipItem(boots);
|
||||
|
||||
EquipItem(new GoldRing());
|
||||
|
||||
Ministers.Add(this);
|
||||
|
||||
CantWalk = true;
|
||||
}
|
||||
|
||||
public override void OnDoubleClick(Mobile from)
|
||||
{
|
||||
if(from.InRange(this.Location, 4))
|
||||
{
|
||||
from.SendGump(new InternalGump());
|
||||
}
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
|
||||
{
|
||||
base.GetContextMenuEntries( from, list );
|
||||
|
||||
list.Add(new TradeOrderEntry(from, this));
|
||||
list.Add(new TurnInEntry(from, this));
|
||||
}
|
||||
|
||||
private class TradeOrderEntry : ContextMenuEntry
|
||||
{
|
||||
public TradeMinister Minister { get; private set; }
|
||||
public Mobile Player { get; private set; }
|
||||
|
||||
public TradeOrderEntry(Mobile player, TradeMinister minister) : base(1114453, 5) // Get Trade Order
|
||||
{
|
||||
Player = player;
|
||||
Minister = minister;
|
||||
|
||||
Enabled = !CityTradeSystem.HasTrade(Player);
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (!CityTradeSystem.HasTrade(Player))
|
||||
{
|
||||
Player.SendGump(new InternalTradeOrderGump(Player as PlayerMobile, Minister));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class TurnInEntry : ContextMenuEntry
|
||||
{
|
||||
public TradeMinister Minister { get; private set; }
|
||||
public Mobile Player { get; private set; }
|
||||
|
||||
public TurnInEntry(Mobile player, TradeMinister minister) : base(1151729, 3) // Turn in a trade order
|
||||
{
|
||||
Player = player;
|
||||
Minister = minister;
|
||||
|
||||
Enabled = CityTradeSystem.HasTrade(Player);
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if (CityTradeSystem.HasTrade(Player))
|
||||
{
|
||||
Player.Target = new InternalTarget(Minister);
|
||||
Player.SendLocalizedMessage(1151730); // Target the trade order you wish to turn in.
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTarget : Target
|
||||
{
|
||||
public TradeMinister Minister { get; private set; }
|
||||
|
||||
public InternalTarget(TradeMinister minister) : base(-1, false, TargetFlags.None)
|
||||
{
|
||||
Minister = minister;
|
||||
}
|
||||
|
||||
protected override void OnTarget(Mobile from, object targeted)
|
||||
{
|
||||
TradeOrderCrate order = targeted as TradeOrderCrate;
|
||||
|
||||
if(order != null)
|
||||
{
|
||||
if (CityLoyaltySystem.CityTrading.TryTurnIn(from, order, Minister))
|
||||
{
|
||||
if (order.Entry != null && order.Entry.Distance > 0)
|
||||
{
|
||||
from.AddToBackpack(Minister.GiveReward(order.Entry));
|
||||
from.SendLocalizedMessage(1073621); // Your reward has been placed in your backpack.
|
||||
}
|
||||
|
||||
Titles.AwardKarma(from, 100, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
from.SendLocalizedMessage(1151731); // That is not a valid trade order. Please try again.
|
||||
from.Target = new InternalTarget(Minister);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Item GiveReward(TradeEntry entry)
|
||||
{
|
||||
if (0.01 > Utility.RandomDouble())
|
||||
{
|
||||
switch (Utility.Random(2))
|
||||
{
|
||||
default:
|
||||
case 0: return CityBook.GetRandom();
|
||||
case 1: return new RewardSign();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Utility.Random(2))
|
||||
{
|
||||
default:
|
||||
case 1: return RandomResource(entry);
|
||||
case 2: return ScrollOfTranscendence.CreateRandom(1, 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Item RandomResource(TradeEntry entry)
|
||||
{
|
||||
int amount = 40;
|
||||
|
||||
if (entry.Details.Count > 1)
|
||||
amount = 40 + Utility.RandomMinMax(10, entry.Details.Count * 20);
|
||||
|
||||
switch (Utility.Random(4))
|
||||
{
|
||||
case 0:
|
||||
switch (Utility.Random(9))
|
||||
{
|
||||
case 0: return new IronIngot(amount);
|
||||
case 1: return new DullCopperIngot(amount);
|
||||
case 2: return new ShadowIronIngot(amount);
|
||||
case 3: return new CopperIngot(amount);
|
||||
case 4: return new BronzeIngot(amount);
|
||||
case 5: return new GoldIngot(amount);
|
||||
case 6: return new AgapiteIngot(amount);
|
||||
case 7: return new VeriteIngot(amount);
|
||||
case 8: return new ValoriteIngot(amount);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
switch (Utility.Random(4))
|
||||
{
|
||||
case 0: return new Leather(amount);
|
||||
case 1: return new SpinedLeather(amount);
|
||||
case 2: return new HornedLeather(amount);
|
||||
case 3: return new BarbedLeather(amount);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
switch (Utility.Random(7))
|
||||
{
|
||||
case 0: return new Board(amount);
|
||||
case 1: return new OakBoard(amount);
|
||||
case 2: return new AshBoard(amount);
|
||||
case 3: return new YewBoard(amount);
|
||||
case 4: return new BloodwoodBoard(amount);
|
||||
case 5: return new HeartwoodBoard(amount);
|
||||
case 6: return new FrostwoodBoard(amount);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
Item item = Loot.Construct(SkillHandlers.Imbuing.IngredTypes[Utility.Random(SkillHandlers.Imbuing.IngredTypes.Length)]);
|
||||
|
||||
amount /= 10;
|
||||
|
||||
if (item != null && item.Stackable)
|
||||
item.Amount = amount;
|
||||
|
||||
return item;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class InternalGump : Gump
|
||||
{
|
||||
public InternalGump() : base(40, 40)
|
||||
{
|
||||
AddBackground(0, 0, 500, 400, 9380);
|
||||
|
||||
AddHtmlLocalized(30, 50, 400, 16, 1152962, 0x4800, false, false); // City Trade Minister
|
||||
AddHtmlLocalized(30, 80, 440, 320, 1152963, 0x001F, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
public class InternalTradeOrderGump : Gump
|
||||
{
|
||||
public TradeMinister Minister { get; private set; }
|
||||
public PlayerMobile User { get; set; }
|
||||
|
||||
public InternalTradeOrderGump(PlayerMobile user, TradeMinister minister)
|
||||
: base(100, 100)
|
||||
{
|
||||
Minister = minister;
|
||||
User = user;
|
||||
|
||||
AddGumpLayout();
|
||||
}
|
||||
|
||||
public void AddGumpLayout()
|
||||
{
|
||||
AddBackground(0, 0, 370, 420, 9300);
|
||||
|
||||
AddHtmlLocalized(10, 30, 350, 18, 1114513, "#1114454", 0x3442, false, false); // An Offer For a trade Order
|
||||
|
||||
/*
|
||||
* Greetings! His majesty thanks you for furthering the economic interests of the City!
|
||||
* The Trade Association hath decreed that all goods shall be transported without the use of magic,
|
||||
* for fear that use of such magics will corrupt the quality of the goods held within.
|
||||
* Be forewarned! The life of a trader is sure to be met with peril as highwayman and pirates
|
||||
* alike seek to profit a bit of coin for the goods. Good luck!
|
||||
*/
|
||||
AddHtmlLocalized(10, 61, 350, 162, 1114455, 0x10, false, false);
|
||||
|
||||
/*
|
||||
* <i>Should you accept this trade order your ability to magically teleport to another location will be disabled.
|
||||
* You may cancel the trade order at any time by accessing the context menu on the trade crate by single left clicking</i>
|
||||
*/
|
||||
AddHtmlLocalized(10, 225, 350, 90, 1151721, 0x3442, false, false);
|
||||
|
||||
AddButton(10, 390, 4005, 4007, 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(50, 390, 100, 20, 1049011, 0x10, false, false); // I Accept!
|
||||
|
||||
AddButton(330, 390, 4017, 4019, 0, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(220, 390, 100, 20, 1114514, "#1006045", 0x4000, false, false); // Cancel
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState state, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 1)
|
||||
{
|
||||
if (!Minister.InRange(User, 5))
|
||||
{
|
||||
User.SendLocalizedMessage(500295); // You are too far away to do that.
|
||||
}
|
||||
else
|
||||
{
|
||||
CityLoyaltySystem.CityTrading.TryOfferTrade(User, Minister);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TradeMinister(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
writer.Write((int)City);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int v = reader.ReadInt();
|
||||
City = (City)reader.ReadInt();
|
||||
|
||||
if (CitySystem != null)
|
||||
CitySystem.Minister = this;
|
||||
|
||||
Ministers.Add(this);
|
||||
}
|
||||
|
||||
public static void Configure()
|
||||
{
|
||||
Ministers = new List<TradeMinister>();
|
||||
}
|
||||
|
||||
public static List<TradeMinister> Ministers { get; private set; }
|
||||
}
|
||||
}
|
||||
344
Scripts/Services/City Loyalty System/Trading/TradeCrate.cs
Normal file
344
Scripts/Services/City Loyalty System/Trading/TradeCrate.cs
Normal file
@@ -0,0 +1,344 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Server;
|
||||
using Server.ContextMenus;
|
||||
using Server.Items;
|
||||
using Server.Gumps;
|
||||
using System.Linq;
|
||||
using Server.Network;
|
||||
using Server.Engines.SeasonalEvents;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
public class TradeOrderCrate : Container
|
||||
{
|
||||
public override int LabelNumber { get { return CityTradeSystem.KrampusEncounterActive ? 1123594 : base.LabelNumber; } }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public TradeEntry Entry { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public Mobile Owner { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public bool Fulfilled
|
||||
{
|
||||
get
|
||||
{
|
||||
if(Entry == null)
|
||||
return false;
|
||||
|
||||
foreach (var details in Entry.Details)
|
||||
{
|
||||
if (GetAmount(details.ItemType) < details.Amount)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime Expires { get; set; }
|
||||
|
||||
public bool Expired { get { return Expires < DateTime.UtcNow; } }
|
||||
|
||||
public override int DefaultMaxWeight { get { return 1000; } }
|
||||
|
||||
public TradeOrderCrate(Mobile from, TradeEntry entry)
|
||||
: base(GetID())
|
||||
{
|
||||
Owner = from;
|
||||
Entry = entry;
|
||||
|
||||
if (CityTradeSystem.KrampusEncounterActive)
|
||||
{
|
||||
Weight = 10.0;
|
||||
Hue = Utility.Random(100);
|
||||
}
|
||||
|
||||
Expires = DateTime.UtcNow + TimeSpan.FromHours(CityTradeSystem.CrateDuration);
|
||||
}
|
||||
|
||||
private static int GetID()
|
||||
{
|
||||
if (CityTradeSystem.KrampusEncounterActive)
|
||||
{
|
||||
return Utility.Random(0x46A2, 6);
|
||||
}
|
||||
|
||||
return Utility.Random(0xE3C, 4);
|
||||
}
|
||||
|
||||
public override int DefaultGumpID
|
||||
{
|
||||
get
|
||||
{
|
||||
switch(ItemID)
|
||||
{
|
||||
default:
|
||||
return base.DefaultGumpID;
|
||||
case 0x46A2:
|
||||
return 0x11B;
|
||||
case 0x46A3:
|
||||
return 0x11C;
|
||||
case 0x46A4:
|
||||
return 0x11D;
|
||||
case 0x46A5:
|
||||
case 0x46A6:
|
||||
return 0x11E;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override bool DisplaysContent { get { return false; } }
|
||||
|
||||
public override void GetProperties(ObjectPropertyList list)
|
||||
{
|
||||
base.GetProperties(list);
|
||||
|
||||
list.Add(1151737, String.Format("#{0}", CityLoyaltySystem.CityLocalization(Entry.Destination))); // Destination City: ~1_city~
|
||||
list.Add(1076255); // NO-TRADE
|
||||
|
||||
int weight = Items.Sum(x => x.Amount);
|
||||
|
||||
list.Add(1072241, "{0}\t{1}\t{2}\t{3}", Items.Count, DefaultMaxItems, weight, DefaultMaxWeight); // Contents: ~1_COUNT~/~2_MAXCOUNT items, ~3_WEIGHT~/~4_MAXWEIGHT~ stones
|
||||
|
||||
list.Add(1072210, "75"); // Weight reduction: ~1_PERCENTAGE~%
|
||||
|
||||
if (Entry.Details != null)
|
||||
{
|
||||
for (int i = 0; i < Entry.Details.Count; i++)
|
||||
{
|
||||
if(Utility.ToInt32(Entry.Details[i].Name) > 0)
|
||||
list.Add(1116453 + i, String.Format("#{0}\t{1}\t{2}", Entry.Details[i].Name, GetAmount(Entry.Details[i].ItemType), Entry.Details[i].Amount)); // ~1_val~: ~2_val~/~3_val~
|
||||
else
|
||||
list.Add(1116453 + i, String.Format("{0}\t{1}\t{2}", Entry.Details[i].Name, GetAmount(Entry.Details[i].ItemType), Entry.Details[i].Amount)); // ~1_val~: ~2_val~/~3_val~
|
||||
}
|
||||
}
|
||||
|
||||
if (!Expired)
|
||||
{
|
||||
int hours = (int)Math.Max(1, (Expires - DateTime.UtcNow).TotalHours);
|
||||
list.Add(1153090, hours.ToString()); // Lifespan: ~1_val~ hours
|
||||
}
|
||||
}
|
||||
|
||||
public override void Delete()
|
||||
{
|
||||
CityLoyaltySystem.CityTrading.RemoveCrate(Owner, this);
|
||||
|
||||
base.Delete();
|
||||
}
|
||||
|
||||
public override bool TryDropItem(Mobile from, Item item, bool message)
|
||||
{
|
||||
if(Entry == null)
|
||||
return false;
|
||||
|
||||
if(TryAddItem(from, item, message))
|
||||
return base.TryDropItem(from, item, message);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryAddItem(Mobile from, Item item, bool message = true)
|
||||
{
|
||||
bool canAdd = false;
|
||||
|
||||
foreach (var details in Entry.Details)
|
||||
{
|
||||
if (item.GetType() == details.ItemType)
|
||||
{
|
||||
int hasAmount = GetAmount(item.GetType());
|
||||
|
||||
if (hasAmount + item.Amount > details.Amount)
|
||||
{
|
||||
if (message)
|
||||
from.SendLocalizedMessage(1151726); // You are trying to add too many of this item to the trade order. Only add the required quantity
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
canAdd = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!canAdd && message)
|
||||
from.SendLocalizedMessage(1151725); // This trade order does not require this item.
|
||||
|
||||
return canAdd;
|
||||
}
|
||||
|
||||
public override int GetTotal(TotalType type)
|
||||
{
|
||||
if (type == TotalType.Weight)
|
||||
{
|
||||
int weight = base.GetTotal(type);
|
||||
|
||||
if (weight > 0)
|
||||
return (int)Math.Max(1, (base.GetTotal(type) * .25));
|
||||
}
|
||||
|
||||
return base.GetTotal(type);
|
||||
}
|
||||
|
||||
public override void GetContextMenuEntries( Mobile from, List<ContextMenuEntry> list )
|
||||
{
|
||||
base.GetContextMenuEntries(from, list);
|
||||
|
||||
if(IsChildOf(from.Backpack))
|
||||
{
|
||||
list.Add(new FillFromPackEntry(this, from));
|
||||
list.Add(new CancelOrderEntry(this, from));
|
||||
}
|
||||
}
|
||||
|
||||
private class FillFromPackEntry : ContextMenuEntry
|
||||
{
|
||||
public TradeOrderCrate Crate { get; private set; }
|
||||
public Mobile Player { get; private set; }
|
||||
|
||||
public FillFromPackEntry(TradeOrderCrate crate, Mobile player) : base(1154908, 3) // Fill from pack
|
||||
{
|
||||
Crate = crate;
|
||||
Player = player;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
if(Crate.IsChildOf(Player.Backpack) && !Crate.Deleted && Crate.Entry != null)
|
||||
{
|
||||
foreach (TradeEntry.TradeDetails detail in Crate.Entry.Details)
|
||||
{
|
||||
Item[] items = Player.Backpack.FindItemsByType(detail.ItemType);
|
||||
|
||||
foreach (Item item in items)
|
||||
{
|
||||
if (item.Amount == 1 && Crate.TryAddItem(Player, item, false))
|
||||
Crate.DropItem(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CancelOrderEntry : ContextMenuEntry
|
||||
{
|
||||
public TradeOrderCrate Crate { get; private set; }
|
||||
public Mobile Player { get; private set; }
|
||||
|
||||
public CancelOrderEntry(TradeOrderCrate crate, Mobile player) : base(1151727, 3) // cancel trade order
|
||||
{
|
||||
Crate = crate;
|
||||
Player = player;
|
||||
}
|
||||
|
||||
public override void OnClick()
|
||||
{
|
||||
Player.CloseGump(typeof(CancelTradeOrderGump));
|
||||
Player.SendGump(new CancelTradeOrderGump(Crate, Player));
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnDroppedOnto(Mobile from, Item target)
|
||||
{
|
||||
from.SendLocalizedMessage(1076254); // That item cannot be dropped.
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnDroppedInto(Mobile from, Container target, Point3D p)
|
||||
{
|
||||
if (target == from.Backpack)
|
||||
return base.OnDroppedInto(from, target, p);
|
||||
|
||||
from.SendLocalizedMessage(1076254); // That item cannot be dropped.
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnDragDropInto(Mobile from, Item item, Point3D p)
|
||||
{
|
||||
from.SendLocalizedMessage(1076254); // That item cannot be dropped.
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool OnDroppedToWorld(Mobile from, Point3D point)
|
||||
{
|
||||
from.SendLocalizedMessage(1076254); // That item cannot be dropped.
|
||||
return false;
|
||||
}
|
||||
|
||||
public override bool AllowSecureTrade(Mobile from, Mobile to, Mobile newOwner, bool accepted)
|
||||
{
|
||||
from.SendLocalizedMessage(1076256); // That item cannot be traded.
|
||||
return false;
|
||||
}
|
||||
|
||||
public TradeOrderCrate(Serial serial) : base(serial)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(Owner);
|
||||
writer.Write(Expires);
|
||||
|
||||
Entry.Serialize(writer);
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int v = reader.ReadInt();
|
||||
|
||||
Owner = reader.ReadMobile();
|
||||
Expires = reader.ReadDateTime();
|
||||
|
||||
Entry = new TradeEntry(reader);
|
||||
}
|
||||
}
|
||||
|
||||
public class CancelTradeOrderGump : Gump
|
||||
{
|
||||
public TradeOrderCrate Crate { get; private set; }
|
||||
public Mobile Player { get; private set; }
|
||||
|
||||
public CancelTradeOrderGump(TradeOrderCrate crate, Mobile player)
|
||||
: base(100, 100)
|
||||
{
|
||||
Crate = crate;
|
||||
Player = player;
|
||||
|
||||
AddPage(0);
|
||||
|
||||
AddBackground(0, 0, 291, 93, 0x13BE);
|
||||
AddImageTiled(5, 5, 280, 60, 0xA40);
|
||||
|
||||
AddHtmlLocalized(9, 9, 272, 60, 1151728, 0x7FFF, false, false); // Are you sure you wish to cancel this trade order? All contents of the trade crate will be placed in your backpack.
|
||||
|
||||
AddButton(160, 67, 0xFB7, 0xFB8, 1, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(195, 69, 120, 20, 1006044, 0x7FFF, false, false); // OKAY
|
||||
|
||||
AddButton(5, 67, 0xFB1, 0xFB2, 0, GumpButtonType.Reply, 0);
|
||||
AddHtmlLocalized(40, 69, 100, 20, 1060051, 0x7FFF, false, false); // CANCEL
|
||||
}
|
||||
|
||||
public override void OnResponse(NetState sender, RelayInfo info)
|
||||
{
|
||||
if (info.ButtonID == 1)
|
||||
{
|
||||
if (Crate != null && Crate.IsChildOf(Player.Backpack))
|
||||
{
|
||||
CityTradeSystem.CancelTradeOrder(Player, Crate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
146
Scripts/Services/City Loyalty System/Trading/TradeEntry.cs
Normal file
146
Scripts/Services/City Loyalty System/Trading/TradeEntry.cs
Normal file
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.ContextMenus;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
[PropertyObject]
|
||||
public class TradeEntry
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public City Origin { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public City Destination { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Kills { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Distance { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public DateTime LastAmbush { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public string TurnIn
|
||||
{
|
||||
get
|
||||
{
|
||||
string str = "";
|
||||
Details.ForEach(d =>
|
||||
{
|
||||
str += d.ItemType.Name + ", ";
|
||||
});
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
public List<TradeDetails> Details { get; set; }
|
||||
|
||||
public TradeEntry(City destination, City origin, int distance)
|
||||
{
|
||||
Origin = origin;
|
||||
Destination = destination;
|
||||
Distance = distance;
|
||||
|
||||
Details = new List<TradeDetails>();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "...";
|
||||
}
|
||||
|
||||
public int CalculateGold()
|
||||
{
|
||||
if (Distance == 0)
|
||||
return 0;
|
||||
|
||||
int gold = 0;
|
||||
|
||||
Details.ForEach(d =>
|
||||
{
|
||||
gold += d.Worth * 3;
|
||||
});
|
||||
|
||||
return Math.Max(CityTradeSystem.TurnInGold, gold + (Distance * 10) + Math.Min(25000, (Kills * 500)));
|
||||
}
|
||||
|
||||
public class TradeDetails
|
||||
{
|
||||
public Type ItemType { get; set; }
|
||||
public int Amount { get; set; }
|
||||
public int Worth { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public TradeDetails(Type type, int worth, int amount, string fallbackname)
|
||||
{
|
||||
ItemType = type;
|
||||
Worth = worth;
|
||||
Amount = amount;
|
||||
|
||||
Name = CityLoyaltySystem.CityTrading.GetNameFor(type, fallbackname);
|
||||
}
|
||||
|
||||
public TradeDetails(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
ItemType = ScriptCompiler.FindTypeByName(reader.ReadString());
|
||||
Worth = reader.ReadInt();
|
||||
Amount = reader.ReadInt();
|
||||
Name = reader.ReadString();
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(ItemType.Name);
|
||||
writer.Write(Worth);
|
||||
writer.Write(Amount);
|
||||
writer.Write(Name);
|
||||
}
|
||||
}
|
||||
|
||||
public TradeEntry(GenericReader reader)
|
||||
{
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Origin = (City)reader.ReadInt();
|
||||
Destination = (City)reader.ReadInt();
|
||||
|
||||
LastAmbush = reader.ReadDateTime();
|
||||
|
||||
Kills = reader.ReadInt();
|
||||
Distance = reader.ReadInt();
|
||||
|
||||
Details = new List<TradeDetails>();
|
||||
|
||||
int count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Details.Add(new TradeDetails(reader));
|
||||
}
|
||||
}
|
||||
|
||||
public void Serialize(GenericWriter writer)
|
||||
{
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write((int)Origin);
|
||||
writer.Write((int)Destination);
|
||||
|
||||
writer.Write(LastAmbush);
|
||||
|
||||
writer.Write(Kills);
|
||||
writer.Write(Distance);
|
||||
|
||||
writer.Write(Details.Count);
|
||||
Details.ForEach(d => d.Serialize(writer));
|
||||
}
|
||||
}
|
||||
}
|
||||
833
Scripts/Services/City Loyalty System/Trading/TradeSystem.cs
Normal file
833
Scripts/Services/City Loyalty System/Trading/TradeSystem.cs
Normal file
@@ -0,0 +1,833 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
using Server;
|
||||
using Server.Mobiles;
|
||||
using Server.ContextMenus;
|
||||
using Server.Engines.Points;
|
||||
using Server.Engines;
|
||||
using Server.Items;
|
||||
using Server.Multis;
|
||||
using Server.Regions;
|
||||
using Server.Engines.SeasonalEvents;
|
||||
|
||||
namespace Server.Engines.CityLoyalty
|
||||
{
|
||||
public enum TradeTitle
|
||||
{
|
||||
Trader = 1151739,
|
||||
Exporter = 1151741,
|
||||
Broker = 1151743,
|
||||
Tycoon = 1151745,
|
||||
Smuggler = 1151747,
|
||||
Magnate = 1155481
|
||||
}
|
||||
|
||||
public class CityTradeSystem : PointsSystem
|
||||
{
|
||||
public static readonly int TurnInGold = Config.Get("CityTrading.TurnInGold", 10000);
|
||||
public static readonly int CrateDuration = Config.Get("CityTrading.CrateDuration", 24);
|
||||
public static readonly int AmbushWaitDuration = Config.Get("CityTrading.AmbushWaitDuration", 5);
|
||||
public static readonly int AmbusherDelete = Config.Get("CityTrading.AmbusherDelete", 10);
|
||||
|
||||
public override TextDefinition Name { get { return new TextDefinition("City Trading"); } }
|
||||
public override PointsType Loyalty { get { return PointsType.CityTrading; } }
|
||||
public override bool AutoAdd { get { return false; } }
|
||||
public override double MaxPoints { get { return double.MaxValue; } }
|
||||
public override bool ShowOnLoyaltyGump { get { return false; } }
|
||||
|
||||
public static bool KrampusEncounterActive { get { return KrampusEncounter.Enabled && KrampusEncounter.Encounter != null; } }
|
||||
|
||||
public static Dictionary<Mobile, TradeOrderCrate> ActiveTrades { get; private set; }
|
||||
public static Dictionary<BaseCreature, DateTime> Ambushers { get; private set; }
|
||||
|
||||
public CityTradeSystem()
|
||||
{
|
||||
ActiveTrades = new Dictionary<Mobile, TradeOrderCrate>();
|
||||
|
||||
_NameBuffer = new Dictionary<Type, string>();
|
||||
}
|
||||
|
||||
public override PointsEntry GetSystemEntry(PlayerMobile pm)
|
||||
{
|
||||
return new CityTradeEntry(pm);
|
||||
}
|
||||
|
||||
public int GetMaxTrades(Mobile m)
|
||||
{
|
||||
CityTradeEntry entry = GetPlayerEntry<CityTradeEntry>(m as PlayerMobile);
|
||||
|
||||
if(entry == null)
|
||||
return 1;
|
||||
|
||||
return Math.Min(8, Math.Max(1, (entry.Completed / 25) + 1));
|
||||
}
|
||||
|
||||
public static bool HasTrade(Mobile from)
|
||||
{
|
||||
return ActiveTrades.ContainsKey(from);
|
||||
}
|
||||
|
||||
public bool HasTurnIn(Mobile from, TradeMinister minister)
|
||||
{
|
||||
if(from == null || minister == null || !ActiveTrades.ContainsKey(from) || ActiveTrades[from] == null)
|
||||
return false;
|
||||
|
||||
TradeOrderCrate crate = ActiveTrades[from];
|
||||
|
||||
return crate.Entry != null && crate.Entry.Origin != minister.City;
|
||||
}
|
||||
|
||||
public bool TryOfferTrade(Mobile from, TradeMinister minister)
|
||||
{
|
||||
if(from == null || from.Backpack == null)
|
||||
return true;
|
||||
|
||||
if (ActiveTrades.ContainsKey(from))
|
||||
{
|
||||
minister.SayTo(from, 1151722); // It appears you are already delivering a trade order. Deliver your current order before requesting another.
|
||||
}
|
||||
else if (KrampusEncounterActive && (KrampusEncounter.Encounter.Krampus != null || KrampusEncounter.Encounter.KrampusSpawning))
|
||||
{
|
||||
var p = KrampusEncounter.Encounter.SpawnLocation;
|
||||
var map = KrampusEncounter.Encounter.SpawnMap;
|
||||
|
||||
minister.SayTo(
|
||||
from,
|
||||
1158790,
|
||||
String.Format("{0}\t{1}",
|
||||
WorldLocationInfo.GetLocationString(p, map),
|
||||
Sextant.GetCoords(p, map)), 1150);
|
||||
// Take notice! The vile Krampus has been spotted near ~2_where~ at ~1_coords~! New Trade Orders are suspended until Krampus has been defeated!
|
||||
}
|
||||
else
|
||||
{
|
||||
City origin = minister.City;
|
||||
City destination;
|
||||
|
||||
do
|
||||
{
|
||||
destination = CityLoyaltySystem.GetRandomCity();
|
||||
}
|
||||
while (destination == origin);
|
||||
|
||||
int distance = GetDistance(minister, destination);
|
||||
int trades = Utility.RandomMinMax(1, GetMaxTrades(from));
|
||||
TradeEntry entry = new TradeEntry(destination, origin, distance);
|
||||
TradeOrderCrate crate = new TradeOrderCrate(from, entry);
|
||||
|
||||
GetPlayerEntry<CityTradeEntry>(from as PlayerMobile, true);
|
||||
|
||||
for (int i = 0; i < trades; i++)
|
||||
{
|
||||
int worth = 1;
|
||||
string name = null;
|
||||
|
||||
Type t = GetRandomTrade(origin, destination, ref worth, ref name);
|
||||
|
||||
if (t != null)
|
||||
{
|
||||
int amount = Utility.RandomList(5, 10, 15, 20);
|
||||
entry.Details.Add(new TradeEntry.TradeDetails(t, worth, amount, name));
|
||||
}
|
||||
else
|
||||
{
|
||||
minister.SayTo(from, "There are no trades available at this time.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (from.Backpack == null || !from.Backpack.TryDropItem(from, crate, false))
|
||||
{
|
||||
crate.Delete();
|
||||
from.SendLocalizedMessage(114456); // Your backpack cannot hold the Trade Order. Free up space and speak to the Trade Minister again.
|
||||
}
|
||||
|
||||
ActiveTrades[from] = crate;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryTurnIn(Mobile from, TradeOrderCrate order, Mobile turninMobile)
|
||||
{
|
||||
if (order == null || from == null || turninMobile == null || order.Entry == null)
|
||||
return false;
|
||||
|
||||
TradeEntry entry = order.Entry;
|
||||
TradeMinister minister = turninMobile as TradeMinister;
|
||||
|
||||
if(from.AccessLevel == AccessLevel.Player && minister != null && minister.City != entry.Destination)
|
||||
turninMobile.SayTo(from, 1151738, String.Format("#{0}", CityLoyaltySystem.GetCityLocalization(entry.Destination))); // Begging thy pardon, but those goods are destined for the City of ~1_city~
|
||||
else if(!order.Fulfilled)
|
||||
turninMobile.SayTo(from, 1151732); // This trade order has not been fulfilled. Fill the trade order with all necessary items and try again.
|
||||
else
|
||||
{
|
||||
CityLoyaltySystem.OnTradeComplete(from, order.Entry);
|
||||
CityTradeEntry pentry = GetPlayerEntry<CityTradeEntry>(from as PlayerMobile);
|
||||
|
||||
if (pentry != null)
|
||||
{
|
||||
pentry.Points++;
|
||||
pentry.DistanceTraveled += entry.Distance;
|
||||
pentry.Completed++;
|
||||
CheckTitle(pentry);
|
||||
}
|
||||
|
||||
order.Delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool TryTurnInToSlim(Mobile from, TradeOrderCrate order, SlimTheFence slim)
|
||||
{
|
||||
if (order == null || from == null || slim == null || order.Entry == null)
|
||||
return false;
|
||||
|
||||
TradeEntry entry = order.Entry;
|
||||
|
||||
if (!order.Fulfilled)
|
||||
slim.SayTo(from, 1151732); // This trade order has not been fulfilled. Fill the trade order with all necessary items and try again.
|
||||
else
|
||||
{
|
||||
CityLoyaltySystem.OnSlimTradeComplete(from, order.Entry);
|
||||
CityTradeEntry pentry = GetPlayerEntry<CityTradeEntry>(from as PlayerMobile, true);
|
||||
|
||||
if (pentry != null)
|
||||
{
|
||||
pentry.Points++;
|
||||
pentry.DistanceTraveled += entry.Distance;
|
||||
pentry.CompletedSlim++;
|
||||
CheckTitle(pentry);
|
||||
}
|
||||
|
||||
slim.SayTo(from, 1151736); // Haha! These goods will fetch me quite a bit o' coin! Thanks fer yer help! Here's a little something I was able to get me hands on...
|
||||
|
||||
order.Delete();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CheckTitle(CityTradeEntry entry)
|
||||
{
|
||||
switch (entry.Completed)
|
||||
{
|
||||
case 1: entry.Player.AddRewardTitle((int)TradeTitle.Trader); break;
|
||||
case 25: entry.Player.AddRewardTitle((int)TradeTitle.Exporter); break;
|
||||
case 50: entry.Player.AddRewardTitle((int)TradeTitle.Broker); break;
|
||||
case 100: entry.Player.AddRewardTitle((int)TradeTitle.Tycoon); break;
|
||||
case 150: entry.Player.AddRewardTitle((int)TradeTitle.Magnate); break;
|
||||
}
|
||||
|
||||
if(entry.CompletedSlim == 50)
|
||||
entry.Player.AddRewardTitle((int)TradeTitle.Smuggler);
|
||||
}
|
||||
|
||||
public override void OnPlayerAdded(PlayerMobile m)
|
||||
{
|
||||
m.Backpack.DropItem(new MysteriousNote());
|
||||
m.PrivateOverheadMessage(Server.Network.MessageType.Regular, 1150, 1151734, m.NetState); // *A passerby slips a rolled bit of parchment into your hand...*
|
||||
}
|
||||
|
||||
public static void CancelTradeOrder(Mobile from, TradeOrderCrate crate)
|
||||
{
|
||||
if (from == null)
|
||||
from = crate.Owner;
|
||||
|
||||
if (from != null)
|
||||
{
|
||||
crate.Items.ForEach(i =>
|
||||
{
|
||||
from.Backpack.DropItem(i);
|
||||
});
|
||||
|
||||
CityTradeEntry entry = CityLoyaltySystem.CityTrading.GetPlayerEntry<CityTradeEntry>(from as PlayerMobile, true);
|
||||
|
||||
if (entry != null)
|
||||
entry.Canceled++;
|
||||
}
|
||||
|
||||
crate.Delete();
|
||||
}
|
||||
|
||||
private Dictionary<Type, string> _NameBuffer;
|
||||
|
||||
public string GetNameFor(Type t, string fallbackname)
|
||||
{
|
||||
if (_NameBuffer.ContainsKey(t))
|
||||
return _NameBuffer[t];
|
||||
|
||||
Item item = Loot.Construct(t);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
string name;
|
||||
|
||||
if (item.Name != null)
|
||||
{
|
||||
name = item.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
name = item.LabelNumber.ToString();
|
||||
}
|
||||
|
||||
_NameBuffer[t] = name;
|
||||
item.Delete();
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
Console.WriteLine("WARNING: Using Fallback name for: {0}", t.Name);
|
||||
return fallbackname;
|
||||
}
|
||||
|
||||
public void RemoveCrate(Mobile from, TradeOrderCrate crate)
|
||||
{
|
||||
if(ActiveTrades.ContainsKey(from))
|
||||
{
|
||||
ActiveTrades.Remove(from);
|
||||
}
|
||||
}
|
||||
|
||||
public static void OnPublicMoongateUsed(Mobile from)
|
||||
{
|
||||
if (ActiveTrades.ContainsKey(from))
|
||||
{
|
||||
ActiveTrades[from].Entry.Distance = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetDistance(TradeMinister origin, City destination)
|
||||
{
|
||||
TradeMinister destMinister = TradeMinister.Ministers.FirstOrDefault(m => m.City == destination);
|
||||
|
||||
if(destMinister != null)
|
||||
{
|
||||
return (int)origin.GetDistanceToSqrt(destMinister.Location);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static Type GetRandomTrade(City originCity, City dest, ref int worth, ref string name)
|
||||
{
|
||||
Region region = CityLoyaltySystem.GetCityInstance(originCity).Definition.Region;
|
||||
List<BaseVendor> list = new List<BaseVendor>(region.GetEnumeratedMobiles().OfType<BaseVendor>().Where(bv => bv.GetBuyInfo() != null && bv.GetBuyInfo().Length > 0));
|
||||
|
||||
if (list.Count == 0)
|
||||
return null;
|
||||
|
||||
do
|
||||
{
|
||||
BaseVendor vendor = list[Utility.Random(list.Count)];
|
||||
IBuyItemInfo[] buyInfo = vendor.GetBuyInfo();
|
||||
|
||||
GenericBuyInfo info = buyInfo[Utility.Random(buyInfo.Length)] as GenericBuyInfo;
|
||||
|
||||
if (!(info is BeverageBuyInfo) && !(info is AnimalBuyInfo) && info != null && info.Type != null && info.Args == null && info.Price < 5000)
|
||||
{
|
||||
list.Clear();
|
||||
list.TrimExcess();
|
||||
|
||||
worth = info.Price;
|
||||
name = info.Name;
|
||||
|
||||
return info.Type;
|
||||
}
|
||||
else
|
||||
list.Remove(vendor);
|
||||
}
|
||||
while (list.Count > 0);
|
||||
|
||||
list.Clear();
|
||||
list.TrimExcess();
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void OnTick()
|
||||
{
|
||||
List<TradeOrderCrate> crates = new List<TradeOrderCrate>(ActiveTrades.Values);
|
||||
List<BaseCreature> toDelete = new List<BaseCreature>();
|
||||
|
||||
foreach (var c in crates)
|
||||
{
|
||||
if (c.Expired)
|
||||
{
|
||||
CancelTradeOrder(c.Owner, c);
|
||||
}
|
||||
else if (c.Entry != null)
|
||||
{
|
||||
CheckAmbush(c);
|
||||
}
|
||||
}
|
||||
|
||||
if (Ambushers != null)
|
||||
{
|
||||
foreach (KeyValuePair<BaseCreature, DateTime> kvp in Ambushers)
|
||||
{
|
||||
if (kvp.Value < DateTime.UtcNow)
|
||||
toDelete.Add(kvp.Key);
|
||||
}
|
||||
|
||||
toDelete.ForEach(bc =>
|
||||
{
|
||||
if (!bc.Deleted)
|
||||
bc.Delete();
|
||||
|
||||
Ambushers.Remove(bc);
|
||||
});
|
||||
}
|
||||
|
||||
toDelete.Clear();
|
||||
toDelete.TrimExcess();
|
||||
crates.Clear();
|
||||
crates.TrimExcess();
|
||||
}
|
||||
|
||||
public static void CheckAmbush(TradeOrderCrate crate)
|
||||
{
|
||||
if (crate == null || crate.Deleted || crate.Entry == null || crate.Expired || crate.Entry.LastAmbush + TimeSpan.FromMinutes(AmbushWaitDuration) > DateTime.UtcNow)
|
||||
return;
|
||||
|
||||
if (crate.RootParentEntity is Mobile && !((Mobile)crate.RootParentEntity).Region.IsPartOf<GuardedRegion>())
|
||||
{
|
||||
Mobile m = crate.RootParentEntity as Mobile;
|
||||
|
||||
if (m.NetState != null && m.Map != null && m.Map != Map.Internal)
|
||||
{
|
||||
double chance = crate.Entry.LastAmbush == DateTime.MinValue ? 0.25 : .05;
|
||||
|
||||
if (chance > Utility.RandomDouble())
|
||||
{
|
||||
double dif = (double)(Math.Min(7200, m.SkillsTotal) + m.RawStr + m.RawInt + m.RawDex) / 10000;
|
||||
|
||||
m.RevealingAction();
|
||||
|
||||
SpawnCreatures(m, dif);
|
||||
crate.Entry.LastAmbush = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SpawnCreatures(Mobile m, double difficulty)
|
||||
{
|
||||
BaseBoat boat = BaseBoat.FindBoatAt(m.Location, m.Map);
|
||||
|
||||
Type[] types = GetCreatureType(m, boat != null);
|
||||
|
||||
if (types == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int amount = Utility.RandomMinMax(3, 5);
|
||||
|
||||
for (int i = 0; i < amount; i++)
|
||||
{
|
||||
BaseCreature bc = Activator.CreateInstance(types[Utility.Random(types.Length)]) as BaseCreature;
|
||||
|
||||
if (bc != null)
|
||||
{
|
||||
if (KrampusEncounterActive)
|
||||
{
|
||||
bc.Name = "An Icy Creature";
|
||||
}
|
||||
|
||||
Rectangle2D zone;
|
||||
|
||||
if (boat != null)
|
||||
{
|
||||
if (boat.Facing == Direction.North || boat.Facing == Direction.South)
|
||||
{
|
||||
if (Utility.RandomBool())
|
||||
{
|
||||
zone = new Rectangle2D(boat.X - 7, m.Y - 4, 3, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
zone = new Rectangle2D(boat.X + 4, m.Y - 4, 3, 3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Utility.RandomBool())
|
||||
{
|
||||
zone = new Rectangle2D(m.X + 4, boat.Y - 7, 3, 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
zone = new Rectangle2D(m.X + 4, boat.Y + 4, 3, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
zone = new Rectangle2D(m.X - 3, m.Y - 3, 6, 6);
|
||||
}
|
||||
|
||||
Point3D p = m.Location;
|
||||
|
||||
if (m.Map != null)
|
||||
{
|
||||
for (int j = 0; j < 25; j++)
|
||||
{
|
||||
Point3D check = m.Map.GetRandomSpawnPoint(zone);
|
||||
|
||||
if (CanFit(check.X, check.Y, check.Z, m.Map, bc))
|
||||
{
|
||||
p = check;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Skill sk in bc.Skills.Where(s => s.Base > 0))
|
||||
{
|
||||
sk.Base += sk.Base * (difficulty);
|
||||
}
|
||||
|
||||
bc.RawStr += (int)(bc.RawStr * difficulty);
|
||||
bc.RawInt += (int)(bc.RawInt * difficulty);
|
||||
bc.RawDex += (int)(bc.RawDex * difficulty);
|
||||
|
||||
if (bc.HitsMaxSeed == -1)
|
||||
bc.HitsMaxSeed = bc.RawStr;
|
||||
|
||||
if (bc.StamMaxSeed == -1)
|
||||
bc.StamMaxSeed = bc.RawDex;
|
||||
|
||||
if (bc.ManaMaxSeed == -1)
|
||||
bc.ManaMaxSeed = bc.RawInt;
|
||||
|
||||
bc.HitsMaxSeed += (int)(bc.HitsMaxSeed * difficulty);
|
||||
bc.StamMaxSeed += (int)(bc.StamMaxSeed * difficulty);
|
||||
bc.ManaMaxSeed += (int)(bc.ManaMaxSeed * difficulty);
|
||||
|
||||
bc.Hits = bc.HitsMaxSeed;
|
||||
bc.Stam = bc.RawDex;
|
||||
bc.Mana = bc.RawInt;
|
||||
|
||||
bc.PhysicalResistanceSeed += (int)(bc.PhysicalResistanceSeed * (difficulty / 3));
|
||||
bc.FireResistSeed += (int)(bc.FireResistSeed * (difficulty / 3));
|
||||
bc.ColdResistSeed += (int)(bc.ColdResistSeed * (difficulty / 3));
|
||||
bc.PoisonResistSeed += (int)(bc.PoisonResistSeed * (difficulty / 3));
|
||||
bc.EnergyResistSeed += (int)(bc.EnergyResistSeed * (difficulty / 3));
|
||||
|
||||
bc.IsAmbusher = true;
|
||||
|
||||
if (Ambushers == null)
|
||||
Ambushers = new Dictionary<BaseCreature, DateTime>();
|
||||
|
||||
Ambushers.Add(bc, DateTime.UtcNow + TimeSpan.FromMinutes(AmbusherDelete));
|
||||
|
||||
bc.MoveToWorld(p, m.Map);
|
||||
Timer.DelayCall(() => bc.Combatant = m);
|
||||
}
|
||||
}
|
||||
|
||||
m.LocalOverheadMessage(Server.Network.MessageType.Regular, 1150, 1155479); // *Your keen senses alert you to an incoming ambush of attackers!*
|
||||
m.SendLocalizedMessage(1049330, "", 0x22); // You have been ambushed! Fight for your honor!!!
|
||||
}
|
||||
|
||||
public static Type[] GetCreatureType(Mobile m, bool wet)
|
||||
{
|
||||
if (KrampusEncounterActive)
|
||||
{
|
||||
return KrampusEncounter.Encounter.GetCreatureTypes(m, wet);
|
||||
}
|
||||
|
||||
return wet ? _SeaTypes : _LandTypes;
|
||||
}
|
||||
|
||||
public override void ProcessKill(Mobile victim, Mobile damager)
|
||||
{
|
||||
if (victim is BaseCreature && Ambushers != null && Ambushers.ContainsKey((BaseCreature)victim))
|
||||
{
|
||||
if (ActiveTrades.ContainsKey(damager))
|
||||
{
|
||||
TradeOrderCrate crate = ActiveTrades[damager];
|
||||
|
||||
if (crate.Entry != null)
|
||||
crate.Entry.Kills++;
|
||||
}
|
||||
|
||||
Ambushers.Remove((BaseCreature)victim);
|
||||
}
|
||||
}
|
||||
|
||||
private static Type[] _SeaTypes =
|
||||
{
|
||||
typeof(SeaSerpent), typeof(DeepSeaSerpent), typeof(Kraken), typeof(WaterElemental)
|
||||
};
|
||||
|
||||
private static Type[] _LandTypes =
|
||||
{
|
||||
typeof(Troll), typeof(Ettin), typeof(GiantSpider), typeof(Brigand)
|
||||
};
|
||||
|
||||
public static bool CanFit(int x, int y, int z, Map map, Mobile mob, int height = 16, bool checkMobiles = true, bool requireSurface = true)
|
||||
{
|
||||
if (map == null || map == Map.Internal)
|
||||
return false;
|
||||
|
||||
if (x < 0 || y < 0 || x >= map.Width || y >= map.Height)
|
||||
return false;
|
||||
|
||||
bool hasSurface = false;
|
||||
bool canswim = mob.CanSwim;
|
||||
bool cantwalk = mob.CantWalk;
|
||||
|
||||
LandTile lt = map.Tiles.GetLandTile(x, y);
|
||||
int lowZ = 0, avgZ = 0, topZ = 0;
|
||||
|
||||
bool surface, impassable;
|
||||
|
||||
map.GetAverageZ(x, y, ref lowZ, ref avgZ, ref topZ);
|
||||
TileFlag landFlags = TileData.LandTable[lt.ID & TileData.MaxLandValue].Flags;
|
||||
|
||||
impassable = (landFlags & TileFlag.Impassable) != 0;
|
||||
|
||||
bool wet = (landFlags & TileFlag.Wet) != 0;
|
||||
|
||||
if (cantwalk && !wet)
|
||||
{
|
||||
impassable = true;
|
||||
}
|
||||
|
||||
if (canswim && wet)
|
||||
{
|
||||
impassable = false;
|
||||
}
|
||||
|
||||
if (impassable && avgZ > z && (z + height) > lowZ)
|
||||
return false;
|
||||
else if (!impassable && z == avgZ && !lt.Ignored)
|
||||
hasSurface = true;
|
||||
|
||||
StaticTile[] staticTiles = map.Tiles.GetStaticTiles(x, y, true);
|
||||
|
||||
for (int i = 0; i < staticTiles.Length; ++i)
|
||||
{
|
||||
ItemData id = TileData.ItemTable[staticTiles[i].ID & TileData.MaxItemValue];
|
||||
surface = id.Surface;
|
||||
impassable = id.Impassable;
|
||||
|
||||
wet = (id.Flags & TileFlag.Wet) != 0;
|
||||
|
||||
if (cantwalk && !wet)
|
||||
{
|
||||
impassable = true;
|
||||
}
|
||||
if (canswim && wet)
|
||||
{
|
||||
surface = true;
|
||||
impassable = false;
|
||||
}
|
||||
|
||||
if ((surface || impassable) && (staticTiles[i].Z + id.CalcHeight) > z && (z + height) > staticTiles[i].Z)
|
||||
return false;
|
||||
else if (surface && !impassable && z == (staticTiles[i].Z + id.CalcHeight))
|
||||
hasSurface = true;
|
||||
}
|
||||
|
||||
IPooledEnumerable eable = map.GetItemsInRange(new Point3D(x, y, z), 0);
|
||||
|
||||
foreach(Item item in eable)
|
||||
{
|
||||
if (item.ItemID < 0x4000)
|
||||
{
|
||||
ItemData id = item.ItemData;
|
||||
surface = id.Surface;
|
||||
impassable = id.Impassable;
|
||||
|
||||
wet = (id.Flags & TileFlag.Wet) != 0;
|
||||
if (cantwalk && !wet)
|
||||
{
|
||||
impassable = true;
|
||||
}
|
||||
if (canswim && wet)
|
||||
{
|
||||
surface = true;
|
||||
impassable = false;
|
||||
}
|
||||
|
||||
if ((surface || impassable) && (item.Z + id.CalcHeight) > z && (z + height) > item.Z)
|
||||
{
|
||||
eable.Free();
|
||||
return false;
|
||||
}
|
||||
else if (surface && !impassable && !item.Movable && z == (item.Z + id.CalcHeight))
|
||||
{
|
||||
hasSurface = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
|
||||
if (checkMobiles)
|
||||
{
|
||||
eable = map.GetMobilesInRange(new Point3D(x, y, z), 0);
|
||||
|
||||
foreach(Mobile m in eable)
|
||||
{
|
||||
if (m.AccessLevel == AccessLevel.Player || !m.Hidden)
|
||||
{
|
||||
if ((m.Z + 16) > z && (z + height) > m.Z)
|
||||
{
|
||||
eable.Free();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
eable.Free();
|
||||
}
|
||||
|
||||
return !requireSurface || hasSurface;
|
||||
}
|
||||
|
||||
[PropertyObject]
|
||||
public class CityTradeEntry : PointsEntry
|
||||
{
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Canceled { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int DistanceTraveled { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int Completed { get; set; }
|
||||
|
||||
[CommandProperty(AccessLevel.GameMaster)]
|
||||
public int CompletedSlim { get; set; }
|
||||
|
||||
public CityTradeEntry(PlayerMobile pm) : base(pm)
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "...";
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(1);
|
||||
|
||||
writer.Write(Canceled);
|
||||
writer.Write(DistanceTraveled);
|
||||
writer.Write(Completed);
|
||||
|
||||
writer.Write(Ambushers == null ? 0 : Ambushers.Count);
|
||||
if (Ambushers != null)
|
||||
{
|
||||
foreach (KeyValuePair<BaseCreature, DateTime> kvp in Ambushers)
|
||||
{
|
||||
writer.Write(kvp.Key);
|
||||
writer.Write(kvp.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
Canceled = reader.ReadInt();
|
||||
DistanceTraveled = reader.ReadInt();
|
||||
Completed = reader.ReadInt();
|
||||
|
||||
int count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
BaseCreature bc = reader.ReadMobile() as BaseCreature;
|
||||
DateTime dt = reader.ReadDateTime();
|
||||
|
||||
if (bc != null)
|
||||
{
|
||||
if (dt < DateTime.UtcNow)
|
||||
bc.Delete();
|
||||
else
|
||||
{
|
||||
if (Ambushers == null)
|
||||
Ambushers = new Dictionary<BaseCreature, DateTime>();
|
||||
|
||||
bc.IsAmbusher = true;
|
||||
|
||||
Ambushers[bc] = dt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (version == 0)
|
||||
{
|
||||
Timer.DelayCall(() =>
|
||||
{
|
||||
if (Player.RemoveRewardTitle(2303807, true))
|
||||
Player.AddRewardTitle(1151739);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Serialize(GenericWriter writer)
|
||||
{
|
||||
base.Serialize(writer);
|
||||
writer.Write(0);
|
||||
|
||||
writer.Write(ActiveTrades.Count);
|
||||
foreach (KeyValuePair<Mobile, TradeOrderCrate> kvp in ActiveTrades)
|
||||
{
|
||||
writer.Write(kvp.Key);
|
||||
writer.Write(kvp.Value);
|
||||
}
|
||||
|
||||
writer.Write(_NameBuffer.Count);
|
||||
foreach (KeyValuePair<Type, string> kvp in _NameBuffer)
|
||||
{
|
||||
writer.Write(kvp.Key.Name);
|
||||
writer.Write(kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Deserialize(GenericReader reader)
|
||||
{
|
||||
base.Deserialize(reader);
|
||||
int version = reader.ReadInt();
|
||||
|
||||
int count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Mobile m = reader.ReadMobile();
|
||||
TradeOrderCrate crate = reader.ReadItem() as TradeOrderCrate;
|
||||
|
||||
if (m != null && crate != null)
|
||||
ActiveTrades[m] = crate;
|
||||
}
|
||||
|
||||
_NameBuffer = new Dictionary<Type, string>();
|
||||
|
||||
count = reader.ReadInt();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
Type t = ScriptCompiler.FindTypeByName(reader.ReadString());
|
||||
string name = reader.ReadString();
|
||||
|
||||
if (t != null)
|
||||
_NameBuffer[t] = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user