using System; using Server; using Server.Items; using Server.Mobiles; using Server.Targeting; using Server.Gumps; using System.Collections.Generic; namespace Server.Engines.LotterySystem { public class PowerBall : Item { public static PowerBall PowerBallInstance { get; set; } #region Getters/Setters private int m_TimeOfDay; //Time Powerball numbers are Picked in military time private int m_TicketCost; //Price per empty ticket private int m_TicketEntryPrice; //Price per entry, ie picks - 10 Max per ticket private int m_PowerBallPrice; //Price per powerball pick private int m_MaxWhiteBalls; //Determines amount of white balls rolled per game private int m_MaxRedBalls; //Determines amount of Powerballs rolled per game private bool m_GuaranteedJackpot; //Chance to pick a jackpot - minimum 5 games without a winner, chances increasing each jackpotless game private int m_GameNumber; //Current Game Number private bool m_HasProcessed; //Has current game been processed? private TimeSpan m_GameDelay; //Time inbetween Picks private TimeSpan m_DeadLine; //Deadline before Picks you can purchase a ticket private static List m_SatList = new List(); public static List SatList { get { return m_SatList; } } private static PowerBallGame m_Instance; //Convenience accessor for current game instance private static int m_GoldSink; //Profit - Payouts = Total goldsink private static PowerBall m_Game; //Easily Accessed instance of the powerball item private static bool m_Announcement; [CommandProperty(AccessLevel.GameMaster)] public int TimeOfDay { get { return m_TimeOfDay; } set { m_TimeOfDay = value; m_NextGame = GetNextGameTime(); } } [CommandProperty(AccessLevel.GameMaster)] public int TicketCost { get { return m_TicketCost; } set { m_TicketCost = value; } } [CommandProperty(AccessLevel.GameMaster)] public int TicketEntryPrice { get { return m_TicketEntryPrice; } set { m_TicketEntryPrice = value; } } [CommandProperty(AccessLevel.GameMaster)] public int PowerBallPrice { get { return m_PowerBallPrice; } set { m_PowerBallPrice = value; } } [CommandProperty(AccessLevel.GameMaster)] public int MaxWhiteBalls { get { return m_MaxWhiteBalls; } set { m_MaxWhiteBalls = value; } } [CommandProperty(AccessLevel.GameMaster)] public int MaxRedBalls { get { return m_MaxRedBalls; } set { m_MaxRedBalls = value; } } [CommandProperty(AccessLevel.GameMaster)] public bool GuaranteedJackpot { get { return m_GuaranteedJackpot; } set { m_GuaranteedJackpot = value; } } [CommandProperty(AccessLevel.GameMaster)] public TimeSpan GameDelay { get { return m_GameDelay; } set { m_GameDelay = value; } } [CommandProperty(AccessLevel.GameMaster)] public TimeSpan DeadLine { get { return m_DeadLine; } set { m_DeadLine = value; } } [CommandProperty(AccessLevel.GameMaster)] public int NoWins { get { if (m_Instance != null) return m_Instance.NoWins; return 0; } } [CommandProperty(AccessLevel.GameMaster)] public int GameNumber { get { return m_GameNumber; } set { m_GameNumber = value; } } [CommandProperty(AccessLevel.GameMaster)] public bool HasProcessed { get { return m_HasProcessed; } set { m_HasProcessed = value; } } [CommandProperty(AccessLevel.GameMaster)] public static bool Announcement { get { return m_Announcement; } set { m_Announcement = value; } } public static PowerBallGame Instance { get { return m_Instance; } set { m_Instance = value; } } //These 2 are backwards, but oh well! public static PowerBall Game { get { return m_Game; } } [CommandProperty(AccessLevel.GameMaster)] public static int GoldSink { get { return m_GoldSink; } set { m_GoldSink = value; } } private DateTime m_NextGame; private bool m_Active; private bool m_DoJackpot; private Timer m_Timer; [CommandProperty(AccessLevel.GameMaster)] public DateTime LastGame { get { return m_NextGame - GameDelay; } } [CommandProperty(AccessLevel.GameMaster)] public DateTime NextGame { get { return m_NextGame; } set { m_NextGame = value; } } [CommandProperty(AccessLevel.GameMaster)] public bool DoJackpot { get { return m_DoJackpot; } set { m_DoJackpot = value; } } [CommandProperty(AccessLevel.GameMaster)] public bool IsActive { get { return m_Active; } set { m_Active = value; if (m_Active) { if (m_Instance == null) m_Instance = new PowerBallGame(this); if (m_Timer != null) { m_Timer.Stop(); m_Timer = null; } m_NextGame = GetNextGameTime(); m_Timer = new PowerBallTimer(this); m_Timer.Start(); } else { if (m_Timer != null) { m_Timer.Stop(); m_Timer = null; } } UpdateSatellites(); InvalidateProperties(); } } #endregion [Constructable] public PowerBall() : base(0xED4) { if (PowerBallInstance != null) { Console.WriteLine("You can only have one shard PowerBall Item."); Delete(); return; } Hue = 592; Name = "Let's Play Powerball!"; m_Game = this; m_Instance = new PowerBallGame(this); m_Timer = new PowerBallTimer(this); m_Timer.Start(); m_Active = true; Movable = false; m_HasProcessed = false; /*Modify below for custom values. See readme file for info*/ m_TicketCost = 100; m_TicketEntryPrice = 1000; m_PowerBallPrice = 500; m_MaxWhiteBalls = 20; m_MaxRedBalls = 8; m_GuaranteedJackpot = true; m_Announcement = true; m_GameNumber = 1; m_GameDelay = TimeSpan.FromHours(24); m_DeadLine = TimeSpan.FromMinutes(30); m_TimeOfDay = 18; m_NextGame = GetNextGameTime(); PowerBallInstance = this; } public override void OnDoubleClick(Mobile from) { if (!m_Active && from.AccessLevel == AccessLevel.Player) from.SendMessage("Powerball is currenlty inactive at this time."); else if (from.InRange(Location, 3)) { if (from.HasGump(typeof(PowerBallStatsGump))) from.CloseGump(typeof(PowerBallStatsGump)); from.SendGump(new PowerBallStatsGump(this, from)); } else if (from.AccessLevel > AccessLevel.Player) from.SendGump(new PropertiesGump(from, this)); else from.SendLocalizedMessage(500446); // That is too far away. } public override void GetProperties(ObjectPropertyList list) { base.GetProperties(list); if (!m_Active) list.Add(1060658, "Status\tOffline"); else list.Add(1060658, "Status\tActive"); if (PowerBallStats.JackpotStats.Count > 0) { int index = PowerBallStats.JackpotStats.Count - 1; //Most Recent Jackpot! string name = PowerBallStats.JackpotStats[index].JackpotWinner != null ? PowerBallStats.JackpotStats[index].JackpotWinner.Name : "unknown"; list.Add(1060659, "Last Jackpot\t{0}", name); list.Add(1060660, "Date\t{0}", PowerBallStats.JackpotStats[index].JackpotTime); list.Add(1060661, "Amount\t{0}", PowerBallStats.JackpotStats[index].JackpotAmount); } } public DateTime GetNextGameTime() { DateTime now = DateTime.Now; DateTime nDT; if (now.Hour >= m_TimeOfDay && now.Second >= 0) { DateTime check = new DateTime(now.Year, now.Month, now.Day, m_TimeOfDay, 1, 0) + m_GameDelay; if (check < now) nDT = now + m_GameDelay; else nDT = check; } else nDT = new DateTime(now.Year, now.Month, now.Day, m_TimeOfDay, 0, 0); return nDT; } public void UpdateSatellites() { foreach (PowerBallSatellite sat in m_SatList) { if (sat != null && !sat.Deleted) sat.InvalidateProperties(); } } public override void OnAfterDelete() { if (m_Timer != null) m_Timer.Stop(); for (int i = 0; i < m_SatList.Count; ++i) { if (m_SatList[i] != null && !m_SatList[i].Deleted) m_SatList[i].Delete(); } base.OnAfterDelete(); } public PowerBall(Serial serial) : base(serial) { } public override void Serialize(GenericWriter writer) { base.Serialize(writer); writer.Write((int)1); //Version writer.Write(m_TimeOfDay); writer.Write(m_TicketCost); writer.Write(m_TicketEntryPrice); writer.Write(m_PowerBallPrice); writer.Write(m_MaxWhiteBalls); writer.Write(m_MaxRedBalls); writer.Write(m_GuaranteedJackpot); writer.Write(m_GoldSink); writer.Write(m_NextGame); writer.Write(m_Active); writer.Write(m_GameNumber); writer.Write(m_GameDelay); writer.Write(m_DeadLine); writer.Write(m_Announcement); //writer.Write(m_HasProcessed); if (m_Instance == null) m_Instance = new PowerBallGame(this); writer.Write(m_Instance.Profit); writer.Write(m_Instance.NoWins); writer.Write(PowerBallStats.JackpotStats.Count); for (int i = 0; i < PowerBallStats.JackpotStats.Count; ++i) { PowerBallStats.JackpotStats[i].Serialize(writer); } writer.Write(PowerBallStats.PicksStats.Count); for (int i = 0; i < PowerBallStats.PicksStats.Count; ++i) { PowerBallStats.PicksStats[i].Serialize(writer); } InvalidateProperties(); } public override void Deserialize(GenericReader reader) { base.Deserialize(reader); m_Game = this; int version = reader.ReadInt(); m_TimeOfDay = reader.ReadInt(); m_TicketCost = reader.ReadInt(); m_TicketEntryPrice = reader.ReadInt(); m_PowerBallPrice = reader.ReadInt(); m_MaxWhiteBalls = reader.ReadInt(); m_MaxRedBalls = reader.ReadInt(); m_GuaranteedJackpot = reader.ReadBool(); m_GoldSink = reader.ReadInt(); m_NextGame = reader.ReadDateTime(); m_Active = reader.ReadBool(); m_GameNumber = reader.ReadInt(); m_GameDelay = reader.ReadTimeSpan(); m_DeadLine = reader.ReadTimeSpan(); m_Announcement = reader.ReadBool(); if (version == 0) m_HasProcessed = reader.ReadBool(); else m_HasProcessed = false; if (m_Active) { m_Timer = new PowerBallTimer(this); m_Timer.Start(); } if (m_Instance == null) m_Instance = new PowerBallGame(this); m_Instance.Profit = reader.ReadInt(); m_Instance.NoWins = reader.ReadInt(); int jackpotCount = reader.ReadInt(); for (int i = 0; i < jackpotCount; i++) { new PowerBallStats(reader); } int picksCount = reader.ReadInt(); for (int i = 0; i < picksCount; i++) { new PowerBallStats(reader); } PowerBallInstance = this; } public static void AddToArchive(List numbers, int payOut) { if (numbers == null || PowerBall.Game == null) return; new PowerBallStats(numbers, PowerBall.Game.GameNumber, payOut); } public static void AddToArchive(Mobile mob, int amount) //Jackpot entry { if (mob == null || PowerBall.Game == null) return; new PowerBallStats(mob, amount, PowerBall.Game.GameNumber); PowerBall.Game.UpdateSatellites(); } public void AddToSatList(PowerBallSatellite satellite) { if (m_SatList != null && !m_SatList.Contains(satellite)) m_SatList.Add(satellite); } public void RemoveFromSatList(PowerBallSatellite satellite) { if (m_SatList != null && m_SatList.Contains(satellite)) m_SatList.Remove(satellite); } public void NewGame(bool hasjackpot) { if (hasjackpot || m_Instance == null) m_Instance = new PowerBallGame(this); else { int noWins = m_Instance.NoWins; int profit = m_Instance.Profit; m_Instance = new PowerBallGame(this, noWins, profit); //No jackpot? Sure! carry over how many non-wins and total profit } if (m_DoJackpot) m_DoJackpot = false; m_GameNumber++; m_NextGame = GetNextGameTime(); m_HasProcessed = false; } } public class PowerBallTimer : Timer { private PowerBall m_PowerBall; public PowerBallTimer(PowerBall pb) : base (TimeSpan.Zero, TimeSpan.FromSeconds(5)) { m_PowerBall = pb; Priority = TimerPriority.FiveSeconds; } protected override void OnTick() { if (PowerBall.Instance == null || PowerBall.Game == null || m_PowerBall == null) { Stop(); Console.WriteLine("There is a null error with Powerball."); return; } if (m_PowerBall.NextGame < DateTime.Now && !m_PowerBall.HasProcessed) { m_PowerBall.HasProcessed = true; PowerBall.Instance.ProcessGame(); } else if (m_PowerBall.NextGame != DateTime.MinValue && m_PowerBall.NextGame + TimeSpan.FromSeconds(30) < DateTime.Now) { int dur = 1000; foreach (PowerBallSatellite sat in PowerBall.SatList) { if (sat != null && !sat.Deleted) { Effects.SendLocationEffect(new Point3D(sat.X, sat.Y + 1, sat.Z + 3), sat.Map, 0x373A, dur, 0, 0); Effects.SendLocationEffect(new Point3D(sat.X + 1, sat.Y, sat.Z + 3), sat.Map, 0x373A, dur, 0, 0); Effects.SendLocationEffect(new Point3D(sat.X, sat.Y, sat.Z + 2), sat.Map, 0x373A, dur, 0, 0); } } Effects.SendLocationEffect(new Point3D(m_PowerBall.X, m_PowerBall.Y + 1, m_PowerBall.Z), m_PowerBall.Map, 0x373A, dur, 0, 0); Effects.SendLocationEffect(new Point3D(m_PowerBall.X + 1, m_PowerBall.Y, m_PowerBall.Z), m_PowerBall.Map, 0x373A, dur, 0, 0); Effects.SendLocationEffect(new Point3D(m_PowerBall.X, m_PowerBall.Y, m_PowerBall.Z - 1), m_PowerBall.Map, 0x373A, dur, 0, 0); } } } }