Overwrite

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

View File

@@ -0,0 +1,217 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Gumps;
using System.Collections.Generic;
/* To add additional ticket types, update the following scripts:
*
* This: TicketType enum
* ScratcherGump.cs: TicketType enum switches in the contructor and at in GetBackground() method.
* ScratcherStongGump.cs: The appropriate info in ticket info region, new page for its stats, and a new response to buy a ticket.
* Background length will need to be adjusted accordingly as well.
* ScratcherLotto: GetGameType() Method will need to reflect the ticket name.
* LottoTicketVendor: Add the new ticket, ID, Hue to the SBInfo
*/
namespace Server.Engines.LotterySystem
{
public enum TicketType
{
GoldenTicket = 1, //1 mil jackpot
CrazedCrafting = 2, //250k - bonus if owner is 100+ craft skill;
SkiesTheLimit = 3, //Progressive
Powerball = 4, //Standard Powerball 5white/1red
}
public class BaseLottoTicket : Item, IOwnerRestricted
{
//Serialized fields/props
private int m_Payout;
private bool m_CashedOut;
private bool m_Checked;
private Mobile m_Owner;
private TicketType m_Type;
private int m_Scratch1;
private int m_Scratch2;
private int m_Scratch3;
private bool m_FreeTicket;
[CommandProperty(AccessLevel.GameMaster)]
public int Payout { get { return m_Payout; } set { m_Payout = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool CashedOut { get { return m_CashedOut; } set { m_CashedOut = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool Checked { get { return m_Checked; } set { m_Checked = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public Mobile Owner { get { return m_Owner; } set { m_Owner = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public TicketType Type { get { return m_Type; } set { m_Type = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public int Scratch1 { get { return m_Scratch1; } set { m_Scratch1 = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public int Scratch2 { get { return m_Scratch2; } set { m_Scratch2 = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public int Scratch3 { get { return m_Scratch3; } set { m_Scratch3 = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool FreeTicket { get { return m_FreeTicket; } set { m_FreeTicket = value; } }
public virtual string OwnerName { get { return m_Owner != null ? m_Owner.Name : "unknown"; } set { } }
public BaseLottoTicket(Mobile owner, TicketType type, bool quickScratch) : base(0x0FF3)
{
m_Type = type;
m_Owner = owner;
m_CashedOut = false;
m_Payout = 0;
m_Checked = false;
m_FreeTicket = false;
if (quickScratch)
DoQuickScratch();
}
public virtual void CheckScratches()
{
}
public virtual bool DoScratch(int scratch, Mobile from)
{
return false;
}
public override void OnDoubleClick(Mobile from)
{
if (m_Owner == null)
m_Owner = from;
if (!IsChildOf(from.Backpack))
from.SendLocalizedMessage(1042001);
else if (from != m_Owner)
from.SendMessage("Only the owner can view this ticket.");
else if (this is PowerBallTicket)
{
if (from.HasGump(typeof(PowerballTicketGump)))
from.CloseGump(typeof(PowerballTicketGump));
from.SendGump(new PowerballTicketGump((PowerBallTicket)this, from));
}
else
{
if (from.HasGump(typeof(ScratcherGump)))
from.CloseGump(typeof(ScratcherGump));
from.SendGump(new ScratcherGump(this, from));
}
InvalidateProperties();
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
string amount = "0";
if (m_Payout > 0)
{
amount = String.Format("{0:##,###,###}", m_Payout);
list.Add(1060847, "{0}\t{1}", "Winnings:", amount);
}
if (m_FreeTicket)
list.Add("Free Ticket");
}
public override void OnItemLifted(Mobile from, Item item)
{
base.OnItemLifted(from, item);
if (this is PowerBallTicket)
{
from.CloseGump(typeof(PowerballTicketGump));
}
else
{
from.CloseGump(typeof(ScratcherGump));
}
}
private void DoQuickScratch()
{
if (m_Owner == null)
return;
for (int i = 1; i < 4; ++i)
DoScratch(i, m_Owner);
m_Owner.SendMessage("You quickly scratch your ticket once you purchase it.");
m_Owner.PlaySound(0x249);
if (m_Owner.HasGump(typeof(ScratcherGump)))
m_Owner.CloseGump(typeof(ScratcherGump));
m_Owner.SendGump(new ScratcherGump(this, m_Owner));
if (ScratcherLotto.Stone != null && ScratcherLotto.Stone.DeleteTicketOnLoss && m_Checked && !m_FreeTicket && m_Payout == 0)
Timer.DelayCall(TimeSpan.FromSeconds(0.5), new TimerCallback(TrashLosingTicket));
}
public void TrashLosingTicket()
{
if (m_Owner != null)
{
m_Owner.SendMessage("You trash the losing ticket.");
m_Owner.SendSound(0x48, m_Owner.Location);
}
Delete();
}
public BaseLottoTicket(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); //Version
writer.Write(m_Owner);
writer.Write(m_Payout);
writer.Write(m_CashedOut);
writer.Write(m_Checked);
writer.Write((int)m_Type);
writer.Write(m_Scratch1);
writer.Write(m_Scratch2);
writer.Write(m_Scratch3);
writer.Write(m_FreeTicket);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Owner = reader.ReadMobile();
m_Payout = reader.ReadInt();
m_CashedOut = reader.ReadBool();
m_Checked = reader.ReadBool();
m_Type = (TicketType)reader.ReadInt();
m_Scratch1 = reader.ReadInt();
m_Scratch2 = reader.ReadInt();
m_Scratch3 = reader.ReadInt();
m_FreeTicket = reader.ReadBool();
}
}
}

View File

@@ -0,0 +1,134 @@
using System;
using Server;
using Server.Factions;
using System.Collections;
using System.Collections.Generic;
using Server.Gumps;
using Server.Guilds;
using Server.Items;
using Server.Engines.LotterySystem;
namespace Server.Mobiles
{
public class LottoTicketVendor : Mobile
{
[Constructable]
public LottoTicketVendor()
{
Name = NameList.RandomName("female");
Title = "the lottery attendant";
Female = true;
NameHue = 0x35;
BodyValue = 401;
Frozen = true;
Blessed = true;
Hue = Utility.RandomSkinHue();
AddItem(new Sandals());
AddItem(new Kilt(Utility.RandomBlueHue()));
AddItem(new FeatheredHat(Utility.RandomGreenHue()));
AddItem(new FancyShirt(Utility.RandomBlueHue()));
Hits = HitsMax;
Stam = StamMax;
Mana = ManaMax;
}
public override bool OnDragDrop(Mobile from, Item dropped)
{
if (dropped is BaseLottoTicket)
{
BaseLottoTicket ticket = (BaseLottoTicket)dropped;
int payOut = ticket.Payout;
Container pack = from.Backpack;
if (!ticket.Checked)
{
Say("You haven't played this ticket yet!");
return false;
}
if (!ticket.CashedOut && ticket.FreeTicket)
GiveFreeTicket(from, ticket);
if (ticket.CashedOut)
Say("This ticket has already been cashed out!");
else if (payOut == 0)
Say("I'm sorry, but this ticket is not a winning ticket.");
else
{
if (payOut <= 1000000 && pack != null)
{
pack.DropItem(new BankCheck(payOut));
from.SendMessage("Your winnings of {0} has been placed into your backpack. Please play again.", payOut);
}
else
{
Banker.Deposit(from, payOut);
from.SendMessage("Your winnings of {0} has been deposited into your bankbox. Please play again.", payOut);
}
from.PlaySound(52);
from.PlaySound(53);
from.PlaySound(54);
from.PlaySound(55);
ticket.CashedOut = true;
}
dropped.Delete();
}
return false;
}
private void GiveFreeTicket(Mobile from, BaseLottoTicket ticket)
{
if (from == null) return;
Item item = null;
string name = "";
switch (ticket.Type)
{
default:
case TicketType.GoldenTicket: item = new GoldenTicket(from, false); name = "Golden Ticket"; break;
case TicketType.CrazedCrafting: item = new CrazedCrafting(from, false); name = "Crazed Crafting"; break;
case TicketType.SkiesTheLimit: item = new SkiesTheLimit(from, false); name = "Skies the Limit"; break;
}
if (item != null)
{
from.SendMessage("You have recived your free {0} ticket.", name);
if (from.Backpack != null)
from.Backpack.DropItem(item);
else
from.BankBox.DropItem(item);
}
ticket.FreeTicket = false;
}
public LottoTicketVendor( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( (int) 0 ); // version
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
Frozen = true;
}
}
}

View File

@@ -0,0 +1,373 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Network;
using Server.Engines.LotterySystem;
namespace Server.Gumps
{
public class PowerBallStatsGump : Gump
{
private const int labelColor = 2101;
private const int GMColor = 33;
private PowerBall m_PowerBall;
private Mobile m_From;
public PowerBallStatsGump(PowerBall item, Mobile from)
: base(50, 50)
{
m_PowerBall = item;
m_From = from;
int gameNumber = 0;
if (PowerBall.Game != null)
gameNumber = PowerBall.Game.GameNumber;
AddPage(0);
AddBackground(50, 0, 350, 350, 9250);
AddPage(1);
if (PowerBall.Game != null && PowerBall.Game.IsActive)
AddLabel(70, 15, labelColor, String.Format("Current Powerball Game: {0}", gameNumber));
else
AddLabel(70, 20, GMColor, "Offline");
if (m_From.AccessLevel > AccessLevel.Player)
{
AddLabel(70, 40, GMColor, String.Format("Gold Sink: {0}", PowerBall.GoldSink));
if (PowerBall.Instance != null)
{
AddLabel(225, 40, GMColor, "Current Game's Profit:");
AddLabel(325, 60, GMColor, String.Format("{0}", PowerBall.Instance.Profit));
}
AddLabel(70, 185, GMColor, "*Warning* GM Options *Warning*");
AddLabel(105, 215, GMColor, "Reset All Stats");
AddButton(70, 215, 0xFBD, 0xFBF, 2, GumpButtonType.Reply, 0);
AddLabel(105, 245, GMColor, "Current Game Guaratee Jackpot");
AddButton(70, 245, 0xFBD, 0xFBF, 3, GumpButtonType.Reply, 0);
AddLabel(105, 275, GMColor, m_PowerBall.IsActive ? "Set Game Inactive" : "Set Active");
AddButton(70, 275, 0xFBD, 0xFBF, 4, GumpButtonType.Reply, 0);
if (PowerBall.Game != null && PowerBall.Game.MaxWhiteBalls <= 20)
{
long odds = GetOdds();
if (odds > 6)
AddLabel(70, 305, GMColor, String.Format("Jackpot Odds: 1 in {0}", odds));
}
}
else
{
int hue = 2041;
AddImage(70, 200, 0x15A9, hue);
AddImage(115, 265, 0x15A9, hue);
AddImage(160, 200, 0x15A9, hue);
AddImage(205, 265, 0x15A9, hue);
AddImage(250, 200, 0x15A9, hue);
AddImage(295, 265, 0x15A9, 0x21);
TimeSpan ts = m_PowerBall.NextGame - DateTime.Now;
string text;
if (ts.TotalHours >= 1)
{
int minutes = (int)ts.TotalMinutes - (((int)ts.TotalHours) * 60);
text = String.Format("Next Picks: {0} {1} and {2} {3}", ((int)ts.TotalHours).ToString(), ts.TotalHours == 1 ? "hour" : "hours", minutes.ToString(), ts.TotalMinutes == 1 ? "minute" : "minutes");
}
else
text = String.Format("Next Picks: {0} {1}", ((int)ts.TotalMinutes).ToString(), ts.TotalMinutes == 1 ? "minute" : "minutes");
AddLabel(70, 40, labelColor, text);
}
AddHtml(105, 65, 200, 16, "<Basefont Color=#FFFFFF>Purchase Ticket</Basefont>", false, false);
if (PowerBall.Instance != null && PowerBall.Instance.CanBuyTickets)
AddButton(70, 65, 0xFBD, 0xFBF, 1, GumpButtonType.Reply, 0);
//else
// AddImage(70, 65, 0xFB4);
AddButton(70, 95, 0xFBD, 0xFBF, 0, GumpButtonType.Page, 2);
AddHtml(105, 95, 200, 16, "<Basefont Color=#FFFFFF>Archived Picks</Basefont>", false, false);
AddButton(70, 125, 0xFBD, 0xFBF, 0, GumpButtonType.Page, 3);
AddHtml(105, 125, 200, 16, "<Basefont Color=#FFFFFF>Jackpot Winners</Basefont>", false, false);
AddHtml(105, 155, 200, 16, "<Basefont Color=#FFFFFF>Current Game Info</Basefont>", false, false);
if (m_PowerBall.IsActive)
AddButton(70, 155, 0xFBD, 0xFBF, 0, GumpButtonType.Page, 4);
//else
// AddImage(70, 155, 0xFB4);
AddPage(2); //Archived Picks
AddLabel(70, 20, labelColor, "Game");
AddLabel(150, 20, labelColor, "Last 10 Picks");
AddLabel(275, 20, labelColor, "Total Payout");
int count = 0;
for (int i = PowerBallStats.PicksStats.Count - 1; i >= 0; --i)
{
PowerBallStats stats = PowerBallStats.PicksStats[i];
string payout = String.Format("{0:##,###,###}", stats.Payout);
AddHtml(70, 50 + (count * 25), 50, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", stats.GameNumber.ToString()), false, false);
AddHtml(305, 50 + (count * 25), 50, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", payout), false, false);
if (stats.Picks != null && stats.Picks.Count > 0)
{
for (int j = 0; j < stats.Picks.Count; ++j)
{
if (j + 1 < stats.Picks.Count)
AddHtml(125 + (j * 25), 50 + (count * 25), 25, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", stats.Picks[j]), false, false);
else
AddHtml(250, 50 + (count * 25), 25, 16, String.Format("<Basefont Color=#FF0000>{0}</Basefont>", stats.Picks[j]), false, false);
}
}
if (count++ >= 9)
break;
}
AddButton(350, 300, 0xFAE, 0xFB0, 0, GumpButtonType.Page, 1);
AddPage(3); //Jackpot Winners
AddLabel(70, 20, labelColor, "Player");
AddLabel(150, 20, labelColor, "Jackpot Amount");
AddLabel(300, 20, labelColor, "Time");
count = 0;
for (int i = PowerBallStats.JackpotStats.Count - 1; i >= 0; --i)
{
PowerBallStats stats = PowerBallStats.JackpotStats[i];
Mobile mob = stats.JackpotWinner;
string jackpotamount = String.Format("{0:##,###,### Gold}", stats.JackpotAmount);
AddHtml(70, 50 + (count * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", mob != null ? mob.Name : "Unanimous"), false, false);
AddHtml(150, 50 + (count * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", jackpotamount), false, false);
AddHtml(270, 50 + (count * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", stats.JackpotTime.ToString()), false, false);
if (count++ >= 9)
break;
}
AddButton(350, 300, 0xFAE, 0xFB0, 0, GumpButtonType.Page, 1);
AddPage(4); //Current Game info
List<Mobile> ticketList = new List<Mobile>();
if (PowerBall.Instance != null)
{
foreach (PowerBallTicket ticket in PowerBall.Instance.Tickets)
{
if (!ticketList.Contains(ticket.Owner) && ticket.Owner != null)
ticketList.Add(ticket.Owner);
}
}
AddLabel(70, 20, labelColor, "Current Game Information");
if (PowerBall.Instance != null || PowerBall.Instance.PowerBall != null && PowerBall.Instance.PowerBall.IsActive)
{
AddLabel(70, 80, labelColor, "Game Number:");
AddHtml(200, 80, 300, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", gameNumber), false, false);
string jackpotamount = String.Format("{0:##,###,### Gold}", PowerBall.Instance.JackPot);
AddLabel(70, 110, labelColor, "Jackpot Amount:");
AddHtml(200, 110, 300, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", PowerBall.Instance.JackPot > 0 ? jackpotamount : "0 Gold"), false, false);
AddLabel(70, 140, labelColor, "Players:");
AddHtml(200, 140, 300, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", ticketList.Count), false, false);
if (PowerBall.Instance != null)
{
int entryCount = 0;
foreach (PowerBallTicket t in PowerBall.Instance.Tickets)
foreach (TicketEntry e in t.Entries)
entryCount++;
AddLabel(70, 170, labelColor, "Tickets:");
AddHtml(200, 170, 300, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", entryCount.ToString()), false, false);
AddLabel(70, 200, labelColor, "Next Picks:");
AddHtml(200, 200, 300, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", PowerBall.Instance.PowerBall.NextGame), false, false);
}
if (ticketList != null && ticketList.Count > 0)
{
AddButton(70, 300, 0x483, 0x481, 0, GumpButtonType.Page, 5);
AddHtml(110, 300, 200, 16, "<Basefont Color=#FFFFFF>Players</Basefont>", false, false);
}
}
else
AddLabel(70, 80, labelColor, "Inactive");
AddButton(350, 300, 0xFAE, 0xFB0, 0, GumpButtonType.Page, 1);
AddPage(5);
AddLabel(70, 20, labelColor, "Players in Current Game");
for (int k = 0; k < ticketList.Count; ++k)
{
if (k < 12)
AddHtml(70, 45 + (k * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", ticketList[k] != null ? ticketList[k].Name : "Unanimous"), false, false);
else if (k < 24)
AddHtml(180, 45 + ((k - 12) * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", ticketList[k] != null ? ticketList[k].Name : "Unanimous"), false, false);
else if (k < 36)
AddHtml(290, 45 + ((k - 24) * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", ticketList[k] != null ? ticketList[k].Name : "Unanimous"), false, false);
}
AddButton(290, 20, 0xFB1, 0xFB3, 0, GumpButtonType.Page, 1);
}
public override void OnResponse(NetState state, RelayInfo info)
{
switch (info.ButtonID)
{
default:
case 0: break;
case 1:
{
Container pack = m_From.Backpack;
if (PowerBall.Instance != null && PowerBall.Game != null && PowerBall.Instance.CanBuyTickets)
{
int cost = PowerBall.Game.TicketCost;
if (pack != null && pack.GetAmount(typeof(Gold)) >= cost)
{
pack.ConsumeTotal(typeof(Gold), cost);
m_From.SendMessage("You purchase a Powerball ticket with {0} gold from your backpack.", cost);
pack.DropItem(new PowerBallTicket(m_From, m_PowerBall));
if (PowerBall.Instance != null)
PowerBall.Instance.Profit += cost;
}
else if (Banker.Withdraw(m_From, cost, true))
{
var ticket = new PowerBallTicket(m_From, m_PowerBall);
if (!pack.TryDropItem(m_From, ticket, false))
{
m_From.SendMessage("There is no room in your pack, so the ticket was placed in your bank box!");
m_From.BankBox.DropItem(ticket);
}
if (PowerBall.Instance != null)
PowerBall.Instance.Profit += cost;
}
else
m_From.SendLocalizedMessage(500191); //Begging thy pardon, but thy bank account lacks these funds.
}
m_From.SendGump(new PowerBallStatsGump(m_PowerBall, m_From));
break;
}
case 2: //Reset all stats
{
if (m_From.AccessLevel == AccessLevel.Player)
break;
for (int i = 0; i < PowerBallStats.PicksStats.Count; ++i)
{
PowerBallStats.PicksStats.Clear();
}
for (int i = 0; i < PowerBallStats.JackpotStats.Count; ++i)
{
PowerBallStats.JackpotStats.Clear();
}
if (PowerBall.Instance != null)
{
PowerBall.Game.InvalidateProperties();
PowerBall.Game.UpdateSatellites();
}
m_From.SendMessage("Stats erased!");
m_From.SendGump(new PowerBallStatsGump(m_PowerBall, m_From));
break;
}
case 3:
{
if (m_From.AccessLevel == AccessLevel.Player)
break;
if (!m_PowerBall.DoJackpot)
{
m_PowerBall.DoJackpot = true;
m_From.SendGump(new PowerBallStatsGump(m_PowerBall, m_From));
m_From.SendMessage("Next picks will result in a jackpot!");
}
break;
}
case 4:
{
if (m_From.AccessLevel == AccessLevel.Player)
break;
if (m_PowerBall.IsActive)
{
m_PowerBall.IsActive = false;
m_From.SendMessage("Powerball set to inactive.");
}
else
{
m_PowerBall.IsActive = true;
m_From.SendMessage("Powerball set to active.");
}
m_From.SendGump(new PowerBallStatsGump(m_PowerBall, m_From));
break;
}
}
}
private long GetOdds()
{
if (PowerBall.Game == null)
return 1;
int white = PowerBall.Game.MaxWhiteBalls;
int red = PowerBall.Game.MaxRedBalls;
long amount1 = GetFact(white);
long amount2 = GetFact(5);
long amount3 = GetFact(white - 5);
try
{
return (amount1 / (amount2 * amount3)) * red;
}
catch
{
return 1;
}
}
private long GetFact(int balls)
{
long value = balls;
for (int i = balls; i > 1; --i)
value *= (i - 1);
return value;
}
}
}

View File

@@ -0,0 +1,278 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Network;
using Server.Misc;
using Server.Engines.LotterySystem;
namespace Server.Gumps
{
public class PowerballTicketGump : Gump
{
private const int labelColor = 88;
private const int maxEntries = 10;
private PowerBallTicket m_Ticket;
private Mobile m_From;
public PowerballTicketGump(PowerBallTicket ticket, Mobile from) : this(ticket, from, true)
{
}
public PowerballTicketGump(PowerBallTicket ticket, Mobile from, bool powerBall)
: base(50, 50)
{
m_Ticket = ticket;
m_From = from;
if (ticket.Owner == null)
ticket.Owner = from;
int gameNumber = 0;
if (PowerBall.Game != null)
gameNumber = PowerBall.Game.GameNumber;
int entries = ticket.Entries.Count;
int yoffSet = 25;
string title = String.Format("<BASEFONT SIZE=8 COLOR=#FF0000><Center>Powerball</Center></BASEFONT>");
AddBackground(50, 0, 300, 200 + (yoffSet * entries), 9270);
AddHtml(65, 170 + (yoffSet * entries), 350, 20, String.Format("<Basefont Size=2>Lotto Association of {0}, All Rights Reserved</Basefont>", ServerList.ServerName), false, false);
AddHtml(50, 20, 300, 30, title, false, false);
AddLabel(65, 50, labelColor, String.Format("Picks: {0}", entries));
AddLabel(65, 70, labelColor, String.Format("Game: {0}", m_Ticket.GameNumber));
if (ticket.GameNumber == gameNumber && entries < maxEntries)
{
AddHtml(180, 50, 80, 16, "<BASEFONT COLOR=#FFFFFF>Powerball</BASEFONT>", false, false);
AddRadio(260, 50, 0x25F8, 0x25FB, powerBall, 0);
AddHtml(180, 80, 80, 16, "<BASEFONT COLOR=#FFFFFF>No Powerball</BASEFONT>", false, false);
AddRadio(260, 80, 0x25F8, 0x25FB, !powerBall, 1);
AddLabel(245, 120, labelColor, "Quick Picks");
AddButton(321, 123, 0x837, 0x838, 2, GumpButtonType.Reply, 0); //Quick Pick
}
if (entries > 0)
{
AddLabel(65, 120, labelColor, "Pick");
for (int i = 0; i < ticket.Entries.Count; ++i)
{
TicketEntry entry = ticket.Entries[i];
int index = i + 1;
List<int> entryList = new List<int>();
entryList.Add(entry.One);
entryList.Add(entry.Two);
entryList.Add(entry.Three);
entryList.Add(entry.Four);
entryList.Add(entry.Five);
AddLabel(75, 150 + (i * yoffSet), labelColor, String.Format("{0}", index.ToString()));
AddHtml(270, 150 + (i * yoffSet), 50, 16, String.Format("<BASEFONT COLOR=#FF0000>{0}</BASEFONT>", entry.PowerBall > 0 ? entry.PowerBall.ToString() : "<B>-</B>"), false, false);
AddHtml(310, 150 + (i * yoffSet), 50, 16, entry.Winner ? "<BASEFONT COLOR=#FFFFFF><b>*</b></BASEFONT>" : "", false, false);
for (int j = entryList.Count - 1; j >= 0; --j)
{
AddHtml(105 + (j * 30), 150 + (i * yoffSet), 50, 16, String.Format("<BASEFONT COLOR=#FFFFFF>{0}</BASEFONT>", entryList[j]), false, false);
}
ColUtility.Free(entryList);
}
}
if (entries < maxEntries && ticket.GameNumber == gameNumber)
{
int yStart = 130 + (yoffSet * (entries));
AddButton(75, yStart + (yoffSet + 2), 0x837, 0x838, 1, GumpButtonType.Reply, 0);
AddTextEntry(100, yStart + yoffSet, 20, 16, labelColor, 1, "*");
AddTextEntry(130, yStart + yoffSet, 20, 16, labelColor, 2, "*");
AddTextEntry(160, yStart + yoffSet, 20, 16, labelColor, 3, "*");
AddTextEntry(190, yStart + yoffSet, 20, 16, labelColor, 4, "*");
AddTextEntry(220, yStart + yoffSet, 20, 16, labelColor, 5, "*");
AddTextEntry(250, yStart + yoffSet, 20, 16, labelColor, 6, "*");
}
}
public override void OnResponse(NetState state, RelayInfo info)
{
bool powerball = info.IsSwitched(0);
if (PowerBall.Game == null || m_Ticket.GameNumber != PowerBall.Game.GameNumber)
return;
int white = PowerBall.Game.MaxWhiteBalls;
int red = PowerBall.Game.MaxRedBalls;
switch (info.ButtonID)
{
default:
case 0: m_From.CloseGump(typeof(PowerballTicketGump)); break;
case 1:
{
int pick1 = 0; int pick2 = 0; int pick3 = 0;
int pick4 = 0; int pick5 = 0; int pick6 = 0;
TextRelay s1 = info.GetTextEntry(1);
TextRelay s2 = info.GetTextEntry(2);
TextRelay s3 = info.GetTextEntry(3);
TextRelay s4 = info.GetTextEntry(4);
TextRelay s5 = info.GetTextEntry(5);
TextRelay s6 = info.GetTextEntry(6);
try
{
pick1 = Convert.ToInt32(s1.Text);
pick2 = Convert.ToInt32(s2.Text);
pick3 = Convert.ToInt32(s3.Text);
pick4 = Convert.ToInt32(s4.Text);
pick5 = Convert.ToInt32(s5.Text);
pick6 = Convert.ToInt32(s6.Text);
}
catch
{
}
if (PowerBall.Instance != null && PowerBall.Game != null)
{
if (pick1 < 1 || pick2 < 1 || pick3 < 1 || pick4 < 1 || pick5 < 1)
m_From.SendMessage(String.Format("You must choose a number from 1 to {0} on a non-powerball pick.", white.ToString()));
else if (pick1 == pick2 || pick1 == pick3 || pick1 == pick4 || pick1 == pick5 || pick2 == pick3 || pick2 == pick4 || pick2 == pick5 || pick3 == pick4 || pick3 == pick5 || pick4 == pick5)
m_From.SendMessage("You should think twice before picking the same number twice.");
else if (pick1 > white || pick2 > white || pick3 > white || pick4 > white || pick5 > white)
m_From.SendMessage(String.Format("White numbers cannot be any higher than {0}.", white.ToString()));
else if (pick6 > red)
m_From.SendMessage(String.Format("Red numbers cannot be any higher than {0}.", red.ToString()));
else if (powerball)
{
if (pick6 < 1)
m_From.SendMessage(String.Format("You must choose a number from 1 to {0} on your powerball pick.", red.ToString()));
else
{
Container pack = m_From.Backpack;
int price = PowerBall.Game.TicketEntryPrice + PowerBall.Game.PowerBallPrice;
if (pack != null && pack.GetAmount(typeof(Gold)) >= price)
{
pack.ConsumeTotal(typeof(Gold), price);
m_From.SendMessage("You purchase a powerball ticket with {0} gold from your backpack.", price);
new TicketEntry(m_Ticket, pick1, pick2, pick3, pick4, pick5, pick6, false);
PowerBall.Instance.Profit += price;
}
else if (Banker.Withdraw(m_From, price, true))
{
new TicketEntry(m_Ticket, pick1, pick2, pick3, pick4, pick5, pick6, false);
PowerBall.Instance.Profit += price;
}
else
m_From.SendLocalizedMessage(500191); //Begging thy pardon, but thy bank account lacks these funds.
}
}
else
{
Container pack = m_From.Backpack;
int price = PowerBall.Game.TicketEntryPrice;
if (pack != null && pack.GetAmount(typeof(Gold)) >= price)
{
pack.ConsumeTotal(typeof(Gold), price);
m_From.SendMessage("You purchase a powerball ticket with {0} gold from your backpack.", price);
new TicketEntry(m_Ticket, pick1, pick2, pick3, pick4, pick5, false);
PowerBall.Instance.Profit += price;
}
else if (Banker.Withdraw(m_From, price, true))
{
new TicketEntry(m_Ticket, pick1, pick2, pick3, pick4, pick5, false);
PowerBall.Instance.Profit += price;
}
else
m_From.SendLocalizedMessage(500191); //Begging thy pardon, but thy bank account lacks these funds.
}
}
m_From.SendGump(new PowerballTicketGump(m_Ticket, m_From, powerball));
break;
}
case 2: //Quickpick
{
Container pack = m_From.Backpack;
int price;
if (powerball)
price = PowerBall.Game.TicketEntryPrice + PowerBall.Game.PowerBallPrice;
else
price = PowerBall.Game.TicketEntryPrice;
if (pack != null && pack.GetAmount(typeof(Gold)) >= price)
{
m_From.SendMessage("You purchase a powerball ticket with {0} gold from your backpack.", price);
pack.ConsumeTotal(typeof(Gold), price);
}
else if (!Banker.Withdraw(m_From, price, true))
{
m_From.SendLocalizedMessage(1060398, price.ToString()); //~1_AMOUNT~ gold has been withdrawn from your bank box.
m_From.SendLocalizedMessage(500191); //Begging thy pardon, but thy bank account lacks these funds.
m_From.SendGump(new PowerballTicketGump(m_Ticket, m_From, powerball));
break;
}
int pick1 = 0; int pick2 = 0; int pick3 = 0;
int pick4 = 0; int pick5 = 0; int pick6 = 0;
List<int> whiteList = new List<int>();
for (int i = 1; i < white + 1; ++i)
whiteList.Add(i);
int count = 0;
while (++count < 6)
{
int ran = Utility.Random(whiteList.Count);
if (count == 1)
pick1 = whiteList[ran];
else if (count == 2)
pick2 = whiteList[ran];
else if (count == 3)
pick3 = whiteList[ran];
else if (count == 4)
pick4 = whiteList[ran];
else
pick5 = whiteList[ran];
whiteList.Remove(whiteList[ran]);
pick6 = Utility.RandomMinMax(1, red);
}
if (powerball)
{
new TicketEntry(m_Ticket, pick1, pick2, pick3, pick4, pick5, pick6, false);
PowerBall.Instance.Profit += price;
}
else
{
new TicketEntry(m_Ticket, pick1, pick2, pick3, pick4, pick5, false);
PowerBall.Instance.Profit += price;
}
m_From.SendGump(new PowerballTicketGump(m_Ticket, m_From, powerball));
}
break;
}
}
}
}

View File

@@ -0,0 +1,458 @@
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<PowerBallSatellite> m_SatList = new List<PowerBallSatellite>();
public static List<PowerBallSatellite> 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<int> 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);
}
}
}
}

View File

@@ -0,0 +1,469 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Network;
using System.Collections.Generic;
/* To give a reward for a jackpot, you can add it to GiveReward(Mobile m) method.
* RewardChance is the chance that reward is given, on Jackpot. This reward, which
* is NOT given by default, would be in addition to the normal jackpot.*/
namespace Server.Engines.LotterySystem
{
public class PowerBallGame
{
public static double RewardChance = 0.5;
private int m_Profit; //Total ticket/entry costs per string of games - resets to zero once a jackpot is won
private int m_NoWins; //Increases each game there is not jackpot
private int m_Payout; //Total payout on any winning tickets
private bool m_Jackpot; //Did this game yeild a jackpot?
private PowerBall m_PowerBall; //Instanced Powerball Item
private List<PowerBallTicket> m_Tickets = new List<PowerBallTicket>(); //Tickets for current game
private List<int> m_Picks; //Picked at the end of the game
private int m_JackpotWinners; //Used for jackpot message
public int Profit { get { return m_Profit; } set { m_Profit = value; } }
public int Payout { get { return m_Payout; } }
public int JackPot { get { return m_Profit / 2; } }
public int NoWins { get { return m_NoWins; } set { m_NoWins = value; } }
public bool HasJackpot { get { return m_Jackpot; } }
public PowerBall PowerBall { get { return m_PowerBall; } }
public List<PowerBallTicket> Tickets { get { return m_Tickets; } }
public List<int> Picks { get { return m_Picks; } }
public bool CanBuyTickets { get { return m_PowerBall.NextGame - m_PowerBall.DeadLine > DateTime.Now && m_PowerBall.IsActive; } }
public int JackpotWinners { get { return m_JackpotWinners; } }
public PowerBallGame(PowerBall item, int noWins, int profit)
{
m_PowerBall = item;
m_NoWins = noWins;
m_Profit = profit;
}
public PowerBallGame(PowerBall item)
{
m_PowerBall = item;
m_NoWins = 0;
m_Profit = 0;
}
public void ProcessGame()
{
m_Payout = 0;
m_JackpotWinners = 0;
if (m_PowerBall == null)
return;;
if (m_PowerBall.DoJackpot)
m_Picks = ChooseJackpotPicks();
if (m_Picks == null)
{
m_Picks = new List<int>();
List<int> whiteList = new List<int>();
int whiteCount = m_PowerBall.MaxWhiteBalls;
for (int i = 1; i < whiteCount + 1; ++i)
whiteList.Add(i);
int count = 0;
int pick = 0;
int powerBall;
while (++count < 6)
{
pick = whiteList[Utility.Random(whiteList.Count)];
m_Picks.Add(pick);
whiteList.Remove(pick);
}
powerBall = Utility.RandomMinMax(1, m_PowerBall.MaxRedBalls);
m_Picks.Add(powerBall);
}
if (m_PowerBall.GuaranteedJackpot && m_NoWins > 5 && Utility.Random(20) < m_NoWins)
{
List<int> list = ChooseJackpotPicks();
if (list != null)
{
m_Picks.Clear();
m_Picks = list;
}
}
new InternalTimer(this);
}
public void CheckForWinners()
{
if (m_Picks == null || m_Tickets == null || m_Tickets.Count == 0)
return;
List<TicketEntry> jackpotList = new List<TicketEntry>();
Dictionary<TicketEntry, int> prizeTable = new Dictionary<TicketEntry, int>();
for(int i = 0; i < m_Tickets.Count; ++i)
{
PowerBallTicket ticket = m_Tickets[i];
ticket.Checked = true;
foreach (TicketEntry entry in ticket.Entries)
{
int matches = 0;
bool powerball = false;
for (int j = 0; j < m_Picks.Count; ++j)
{
if (j == m_Picks.Count - 1)
{
if (entry.PowerBall == m_Picks[j])
powerball = true;
}
else if (entry.One == m_Picks[j] || entry.Two == m_Picks[j] || entry.Three == m_Picks[j] || entry.Four == m_Picks[j] || entry.Five == m_Picks[j])
matches++;
}
if (matches == 5 && powerball)
{
jackpotList.Add(entry);
entry.Winner = true;
m_Jackpot = true;
}
if (matches >= 3 && !entry.Winner && !prizeTable.ContainsKey(entry))
{
prizeTable.Add(entry, matches);
entry.Winner = true;
}
if (powerball && !m_Jackpot)
{
entry.Ticket.Payout += 500;
m_Profit -= 500;
m_Payout += 500;
entry.Winner = true;
}
}
}
DistributeAwards(jackpotList, prizeTable);
}
private void DistributeAwards(List<TicketEntry> jackpot, Dictionary<TicketEntry, int> prize)
{
int pot = m_Profit;
if (jackpot != null && jackpot.Count > 0)
{
foreach (TicketEntry entry in jackpot)
{
if (entry.Ticket != null && entry.Ticket.Owner != null)
{
int amount = JackPot / jackpot.Count;
m_Jackpot = true;
entry.Ticket.Payout += amount;
m_Payout += amount;
m_Profit -= amount;
PowerBall.AddToArchive(entry.Ticket.Owner, amount);
m_JackpotWinners++;
m_PowerBall.InvalidateProperties();
if (RewardChance > Utility.RandomDouble())
{
GiveReward(entry.Ticket.Owner);
}
}
}
}
if (prize != null && prize.Count > 0)
{
int award = 0;
int match3 = 0;
int match4 = 0;
int match5 = 0;
foreach (KeyValuePair<TicketEntry, int> kvp in prize)
{
if (kvp.Value == 3)
match3++;
else if (kvp.Value == 4)
match4++;
else
match5++;
}
foreach (KeyValuePair<TicketEntry, int> kvp in prize)
{
TicketEntry entry = kvp.Key;
int matches = kvp.Value;
if (matches == 3)
award = (pot / 50) / match3; //2% of Pot
else if (matches == 4)
award = (pot / 20) / match4; //5% of Pot
else
award = (pot / 10) / match5; //10% of Pot
entry.Ticket.Payout += award;
m_Payout += award;
m_Profit -= award;
}
}
}
private void GiveReward(Mobile m)
{
}
private List<int> ChooseJackpotPicks()
{
if (m_Tickets == null || m_Tickets.Count == 0)
return null;
List<TicketEntry> entryList = new List<TicketEntry>();
foreach (PowerBallTicket ticket in m_Tickets)
{
if (ticket.Entries.Count > 0 && ticket.Owner != null)
{
foreach (TicketEntry entry in ticket.Entries)
{
if (entry.PowerBall > 0)
entryList.Add(entry);
}
}
}
int random = Utility.Random(entryList.Count);
for (int j = 0; j < entryList.Count; ++j)
{
if (j == random)
{
TicketEntry entry = entryList[j];
List<int> list = new List<int>();
list.Add(entry.One);
list.Add(entry.Two);
list.Add(entry.Three);
list.Add(entry.Four);
list.Add(entry.Five);
list.Add(entry.PowerBall);
return list;
}
}
return null;
}
public void AddTicket(PowerBallTicket ticket)
{
if (!m_Tickets.Contains(ticket))
m_Tickets.Add(ticket);
}
public void RemoveTicket(PowerBallTicket ticket)
{
if (m_Tickets.Contains(ticket))
m_Tickets.Remove(ticket);
}
public class InternalTimer : Timer
{
private PowerBallGame m_Game;
private int m_Ticks;
private DateTime m_Start;
public InternalTimer(PowerBallGame game) : base (TimeSpan.Zero, TimeSpan.FromSeconds(1.0))
{
m_Game = game;
m_Ticks = 0;
m_Start = DateTime.Now;
Start();
}
protected override void OnTick()
{
if (m_Game == null || m_Game.PowerBall == null || m_Game.Picks == null || m_Game.Picks.Count < 6)
{
Stop();
return;
}
if (m_Start > DateTime.Now)
return;
if (m_Ticks <= 5)
{
string text;
int num = 0;
try
{
num = m_Game.Picks[m_Ticks];
}
catch
{
this.Stop();
Console.WriteLine("Error with PowerBallGame Timer");
return;
}
if (m_Ticks == 0)
text = "The first pick is... ";
else if (m_Ticks < 5)
text = "The next pick is... ";
else
text = "And the powerball is... ";
if (m_Game != null && m_Game.PowerBall != null)
{
m_Game.PowerBall.PublicOverheadMessage(0, m_Ticks < 5 ? 2041 : 0x21, false, text);
Timer.DelayCall(TimeSpan.FromSeconds(2), new TimerStateCallback(DoDelayMessage), new object[] { m_Game.PowerBall, num, m_Ticks });
}
foreach (PowerBallSatellite sat in PowerBall.SatList)
{
sat.PublicOverheadMessage(0, m_Ticks < 5 ? 2041 : 0x21, false, text);
Timer.DelayCall(TimeSpan.FromSeconds(2), new TimerStateCallback(DoDelayMessage), new object[] { sat, num, m_Ticks });
}
m_Ticks++;
m_Start = DateTime.Now + TimeSpan.FromSeconds(8 + Utility.Random(10));
}
else //Time to tally picks and start up a new game!
{
m_Game.CheckForWinners();
PowerBall.AddToArchive(m_Game.Picks, m_Game.Payout); //Adds pickslist to Archive for stats gump
if (!m_Game.HasJackpot) //Still no jackpot eh?
{
m_Game.NoWins++;
Timer.DelayCall(TimeSpan.FromSeconds(2), new TimerStateCallback(DoMessage), m_Game);
}
else
{
if (PowerBall.Announcement)
Timer.DelayCall(TimeSpan.FromSeconds(2), new TimerStateCallback(DoJackpotMessage), m_Game.JackpotWinners);
PowerBall.GoldSink += PowerBall.Instance.Profit;
}
Timer.DelayCall(TimeSpan.FromSeconds(10), new TimerStateCallback(DoWinnersMessage), m_Game);
m_Game.PowerBall.NewGame(m_Game.HasJackpot);
Stop();
}
}
public static void DoDelayMessage(object state)
{
object[] o = (object[])state;
Item item = o[0] as Item;
int num = (int)o[1];
int tick = (int)o[2];
item.PublicOverheadMessage(0, tick < 5 ? 2041 : 0x21, false, num.ToString());
}
#region Messages
public static void DoMessage(object state)
{
if (state is PowerBallGame)
{
PowerBallGame powerball = (PowerBallGame)state;
List<Mobile> mobList = new List<Mobile>();
if (powerball == null)
return;
foreach (PowerBallTicket ticket in powerball.Tickets)
{
if (ticket.Owner != null && !mobList.Contains(ticket.Owner))
mobList.Add(ticket.Owner);
}
if (mobList.Count > 0)
{
for (int i = 0; i < mobList.Count; ++i)
{
mobList[i].SendMessage("New Powerball numbers have been chosen so check your tickets!");
}
}
}
}
public static void DoJackpotMessage(object state)
{
if (state is int && (int)state > 0)
{
int amount = (int)state;
foreach (NetState netState in NetState.Instances)
{
Mobile m = netState.Mobile;
if (m != null)
{
m.PlaySound(1460);
m.SendMessage(33, "There {0} {1} winning jackpot {2} in powerball!", amount > 1 ? "are" : "is", amount, amount > 1 ? "tickets" : "ticket");
}
}
}
}
public static void DoWinnersMessage(object state)
{
if (state is PowerBallGame)
{
PowerBallGame powerball = (PowerBallGame)state;
List<Mobile> winList = new List<Mobile>();
if (powerball == null)
return;
foreach (PowerBallTicket ticket in powerball.Tickets)
{
if (ticket.Owner != null && ticket.Owner is PlayerMobile && ticket.Owner.NetState != null)
{
foreach (TicketEntry entry in ticket.Entries)
{
if (entry.Winner && !winList.Contains(ticket.Owner))
winList.Add(ticket.Owner);
}
}
}
foreach (Mobile mob in winList)
{
int sound;
if (mob.Female)
{
sound = Utility.RandomList(0x30C, 0x30F, 0x313, 0x31A, 0x31D, 0x32B, 0x330, 0x337);
mob.PlaySound(sound);
}
else
{
sound = Utility.RandomList(0x41A, 0x41B, 0x41E, 0x422, 0x42A, 0x42D, 0x431, 0x429);
mob.PlaySound(sound);
}
mob.SendMessage("It looks like you have a winning ticket!");
}
}
}
#endregion
}
}
}

View File

@@ -0,0 +1,111 @@
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 PowerBallSatellite : Item
{
private PowerBall m_PowerBall;
[CommandProperty(AccessLevel.GameMaster)]
public PowerBall PowerBall { get { return m_PowerBall; } set { m_PowerBall = value; } }
[Constructable]
public PowerBallSatellite() : base(0xED4)
{
Hue = 592;
Name = "Let's Play Powerball!";
Movable = false;
if (PowerBall.PowerBallInstance != null)
{
m_PowerBall = PowerBall.PowerBallInstance;
m_PowerBall.AddToSatList(this);
}
else Delete();
}
public override void OnDoubleClick(Mobile from)
{
if (m_PowerBall == null)
base.OnDoubleClick(from);
else if (!m_PowerBall.IsActive && 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(m_PowerBall, from));
}
else if (from.AccessLevel > AccessLevel.Player)
from.SendGump(new PropertiesGump(from, m_PowerBall));
else
from.SendLocalizedMessage(500446); // That is too far away.
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (m_PowerBall != null && !m_PowerBall.Deleted)
{
if (!m_PowerBall.IsActive)
list.Add(1060658, "Status\tOffline");
else
list.Add(1060658, "Status\tActive");
if (PowerBallStats.JackpotStats.Count > 0)
{
int index = PowerBallStats.JackpotStats.Count - 1;
list.Add(1060659, "Last Jackpot\t{0}", PowerBallStats.JackpotStats[index].JackpotWinner.Name);
list.Add(1060660, "Date\t{0}", PowerBallStats.JackpotStats[index].JackpotTime);
list.Add(1060661, "Amount\t{0}", PowerBallStats.JackpotStats[index].JackpotAmount);
}
}
else
list.Add("Disabled");
}
public override void OnAfterDelete()
{
if (m_PowerBall != null)
m_PowerBall.RemoveFromSatList(this);
base.OnAfterDelete();
}
public PowerBallSatellite(Serial serial) : base (serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); //Version
writer.Write(m_PowerBall);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_PowerBall = reader.ReadItem() as PowerBall;
if (m_PowerBall != null)
m_PowerBall.AddToSatList(this);
}
}
}

View File

@@ -0,0 +1,134 @@
using System;
using Server;
using Server.Mobiles;
using System.Collections.Generic;
namespace Server.Engines.LotterySystem
{
public class PowerBallStats
{
public static readonly int MaxStats = 10; //How many in the list to retain
private Mobile m_JackpotWinner;
private int m_Payout;
private int m_JackpotAmount;
private int m_GameNumber;
private DateTime m_JackpotTime;
private List<int> m_Picks = new List<int>();
private bool m_JackpotEntry;
public Mobile JackpotWinner { get { return m_JackpotWinner; } }
public int Payout { get { return m_Payout; } }
public int JackpotAmount { get { return m_JackpotAmount; } }
public int GameNumber { get { return m_GameNumber; } }
public DateTime JackpotTime { get { return m_JackpotTime; } }
public List<int> Picks { get { return m_Picks; } }
public bool IsJackpotEntry { get { return m_JackpotEntry; } }
private static List<PowerBallStats> m_PicksStats = new List<PowerBallStats>();
public static List<PowerBallStats> PicksStats { get { return m_PicksStats; } }
private static List<PowerBallStats> m_JackpotStats = new List<PowerBallStats>();
public static List<PowerBallStats> JackpotStats { get { return m_JackpotStats; } }
public PowerBallStats(Mobile winner, int amount, int gameNumber)
{
m_JackpotWinner = winner;
m_JackpotAmount = amount;
m_GameNumber = gameNumber;
m_JackpotTime = DateTime.Now;
m_JackpotEntry = true;
m_JackpotStats.Add(this);
TrimList(m_JackpotStats); //Keeps the list at a minimum of 10
if (PowerBall.Game != null)
PowerBall.Game.UpdateSatellites();
}
public PowerBallStats(List<int> list, int gameNumber, int payOut)
{
m_Picks = list;
m_GameNumber = gameNumber;
m_JackpotEntry = false;
m_Payout = payOut;
m_PicksStats.Add(this);
TrimList(m_PicksStats); //Keeps the list at a minimum of 10
}
public void TrimList(List<PowerBallStats> list)
{
if (list == null || list.Count <= MaxStats || PowerBall.Game == null)
return;
for (int i = 0; i < list.Count; ++i)
{
PowerBallStats stat = list[i];
if (stat.IsJackpotEntry && i < list.Count - MaxStats && m_JackpotStats.Contains(stat))
m_JackpotStats.Remove(stat);
else if (stat.GameNumber < PowerBall.Game.GameNumber - MaxStats && m_PicksStats.Contains(stat))
m_PicksStats.Remove(stat);
}
}
public void Serialize(GenericWriter writer)
{
writer.Write((int)0); //version
writer.Write(m_JackpotEntry);
writer.Write(m_GameNumber);
if (m_JackpotEntry)
{
writer.Write(m_JackpotWinner);
writer.Write(m_JackpotAmount);
writer.Write(m_JackpotTime);
}
else
{
writer.Write(m_Payout);
writer.Write(m_Picks.Count);
for (int i = 0; i < m_Picks.Count; ++i)
{
writer.Write(m_Picks[i]);
}
}
}
public PowerBallStats(GenericReader reader)
{
int version = reader.ReadInt();
m_JackpotEntry = reader.ReadBool();
m_GameNumber = reader.ReadInt();
if (m_JackpotEntry)
{
m_JackpotWinner = reader.ReadMobile();
m_JackpotAmount = reader.ReadInt();
m_JackpotTime = reader.ReadDateTime();
m_JackpotStats.Add(this);
}
else
{
m_Payout = reader.ReadInt();
int count = reader.ReadInt();
for (int i = 0; i < count; ++i)
{
int pick = reader.ReadInt();
m_Picks.Add(pick);
}
m_PicksStats.Add(this);
}
}
}
}

View File

@@ -0,0 +1,199 @@
using Server;
using System;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Engines.LotterySystem;
using Server.Gumps;
using Server.Items;
namespace Server.Items
{
public class PowerBallTicket : BaseLottoTicket
{
private PowerBall m_PowerBall;
private int m_Game;
private List<TicketEntry> m_Entries = new List<TicketEntry>();
[CommandProperty(AccessLevel.GameMaster)]
public int GameNumber { get { return m_Game; } }
public List<TicketEntry> Entries { get { return m_Entries; } }
[Constructable]
public PowerBallTicket() : base(null, TicketType.Powerball, false)
{
Name = "a powerball ticket";
LootType = LootType.Blessed;
Hue = 2106;
if (PowerBall.Instance != null && PowerBall.Game != null)
{
m_PowerBall = PowerBall.Game;
PowerBall.Instance.AddTicket(this);
m_Game = m_PowerBall.GameNumber;
}
else
m_Game = 0;
}
[Constructable]
public PowerBallTicket(Mobile owner, PowerBall powerball) : base (owner, TicketType.Powerball, false)
{
Name = "a powerball ticket";
LootType = LootType.Blessed;
Hue = 2106;
m_PowerBall = powerball;
if (m_PowerBall != null)
m_Game = m_PowerBall.GameNumber;
else
m_Game = 0;
if (PowerBall.Instance != null)
PowerBall.Instance.AddTicket(this);
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (Payout > 0 || m_PowerBall == null || m_Game != m_PowerBall.GameNumber )
list.Add(1150487); //[Expired]
else
list.Add(3005117); //[Active]
}
/*public override void OnDoubleClick(Mobile from)
{
if (Owner == null)
Owner = from;
if (!IsChildOf(from.Backpack))
from.SendLocalizedMessage(1042001);
else if (from != Owner)
from.SendMessage("Only the owner can view this ticket.");
else
{
if (from.HasGump(typeof(TicketGump)))
from.CloseGump(typeof(TicketGump));
from.SendGump(new TicketGump(this, from));
}
base.OnDoubleClick(from);
}*/
public void AddEntry(TicketEntry entry)
{
if (!m_Entries.Contains(entry))
m_Entries.Add(entry);
}
public override void OnAfterDelete()
{
if (PowerBall.Instance != null)
PowerBall.Instance.RemoveTicket(this);
if (m_Entries.Count > 0)
m_Entries.Clear();
}
public PowerBallTicket(Serial serial) : base( serial )
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int) 0); //Version
writer.Write(m_Game);
writer.Write(m_Entries.Count);
for (int i = 0; i < m_Entries.Count; ++i)
{
TicketEntry entry = m_Entries[i];
writer.Write(entry.One);
writer.Write(entry.Two);
writer.Write(entry.Three);
writer.Write(entry.Four);
writer.Write(entry.Five);
writer.Write(entry.PowerBall);
writer.Write(entry.Winner);
}
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Game = reader.ReadInt();
int count = reader.ReadInt();
for (int i = 0; i < count; ++i)
{
int one = reader.ReadInt();
int two = reader.ReadInt();
int three = reader.ReadInt();
int four = reader.ReadInt();
int five = reader.ReadInt();
int six = reader.ReadInt();
bool winner = reader.ReadBool();
new TicketEntry(this, one, two, three, four, five, six, winner);
}
m_PowerBall = PowerBall.Game;
if (PowerBall.Instance != null && m_PowerBall != null && m_Game == m_PowerBall.GameNumber)
PowerBall.Instance.AddTicket(this);
}
}
public class TicketEntry
{
private PowerBallTicket m_Ticket;
private int m_One;
private int m_Two;
private int m_Three;
private int m_Four;
private int m_Five;
private int m_PowerBall;
private bool m_Winner;
public PowerBallTicket Ticket { get { return m_Ticket; } }
public int One { get { return m_One; } }
public int Two { get { return m_Two; } }
public int Three { get { return m_Three; } }
public int Four { get { return m_Four; } }
public int Five{ get { return m_Five; } }
public int PowerBall { get { return m_PowerBall; } }
public bool Winner { get { return m_Winner; } set { m_Winner = value; } }
public TicketEntry (PowerBallTicket ticket, int one, int two, int three, int four, int five, bool winner) : this (ticket, one, two, three, four, five, 0, winner)
{
}
public TicketEntry(PowerBallTicket ticket, int one, int two, int three, int four, int five, int six, bool winner)
{
m_Ticket = ticket;
m_One = one;
m_Two = two;
m_Three = three;
m_Four = four;
m_Five = five;
m_PowerBall = six;
m_Winner = winner;
m_Ticket.AddEntry(this);
}
}
}

Binary file not shown.

View File

@@ -0,0 +1,206 @@
using Server;
using System;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Engines.LotterySystem;
using Server.Gumps;
using Server.Items;
namespace Server.Items
{
public class CrazedCrafting : BaseLottoTicket
{
private int[] m_WinAmounts = new int[] { 1000, 2500, 7500, 25000, 150000, 2 };
private int[] m_WildCards = new int[] { 0x15AF, 0x15B3, 0x15B7, 0x15CB, 0x15CD };
public int[] WildCards { get { return m_WildCards; } }
public static readonly int TicketCost = 1000;
[Constructable]
public CrazedCrafting() : this(null, false)
{
}
[Constructable]
public CrazedCrafting(Mobile owner, bool quickScratch) : base (owner, TicketType.CrazedCrafting, quickScratch)
{
Name = "a crazed crafting ticket";
LootType = LootType.Blessed;
Hue = 0x972;
}
public override bool DoScratch(int scratch, Mobile from)
{
if (scratch > 3 || scratch < 0 || from == null)
return false;
int pick;
int pickAmount;
try
{
if (.08 > Utility.RandomDouble())
pickAmount = m_WildCards[Utility.Random(m_WildCards.Length)];
else
{
int[] odds = ReturnOdds(from);
pick = odds[Utility.Random(odds.Length)];
pickAmount = m_WinAmounts[pick];
}
}
catch
{
return false;
}
switch (scratch)
{
case 1: Scratch1 = pickAmount; break;
case 2: Scratch2 = pickAmount; break;
case 3: Scratch3 = pickAmount; break;
default: return false;
}
CheckScratches();
return true;
}
private int[] ReturnOdds(Mobile from)
{
if (CraftingSkill(from) > 120 || (CraftingSkill(from) > 100 && Utility.RandomBool()))
return new int[] { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5 };
return new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5 };
}
public override void CheckScratches()
{
/*Multipler = 3 same wildcards = 10x
2 same wildcards = 2x*/
if (Scratch1 > 0 && Scratch2 > 0 && Scratch3 > 0)
{
Checked = true;
bool wild1 = false;
bool wild2 = false;
bool wild3 = false;
foreach(int num in m_WildCards)
{
if (Scratch1 == num)
wild1 = true;
if (Scratch2 == num)
wild2 = true;
if (Scratch3 == num)
wild3 = true;
}
if (Scratch1 == 2 || Scratch2 == 2 || Scratch3 == 2)
FreeTicket = true;
else if ((Scratch1 == Scratch2 && Scratch2 == Scratch3) || (wild1 && Scratch2 == Scratch3) || (wild2 && Scratch1 == Scratch3)
|| (wild3 && Scratch1 == Scratch2) || (wild1 && wild2) || (wild2 && wild3) || (wild1 && wild3))
{
int payOut = 0;
if (!wild1)
{
payOut = Scratch1;
if (wild2 && wild3 && Scratch2 == Scratch3)
payOut *= 2;
}
else if (!wild2)
{
payOut = Scratch2;
if (wild1 && wild3 && Scratch1 == Scratch3)
payOut *= 2;
}
else if (!wild3)
{
payOut = Scratch3;
if (wild1 && wild2 && Scratch1 == Scratch2)
payOut *= 2;
}
else
{
payOut = 150000;
if (Scratch1 == Scratch2 && Scratch2 == Scratch3)
payOut *= 10;
else if (Scratch1 == Scratch2 || Scratch2 == Scratch3 || Scratch1 == Scratch3)
payOut *= 2;
}
Payout = payOut;
DoWin(Payout);
if (ScratcherLotto.Stone != null)
ScratcherLotto.Stone.GoldSink -= Payout;
}
}
InvalidateProperties();
}
private void DoWin(int amount)
{
if (Owner != null)
Owner.PlaySound(Owner.Female ? 0x337 : 0x449);
if (amount >= 100000) //Jackpot
{
new ScratcherStats(Owner, amount, this.Type);
if (ScratcherLotto.Stone != null)
{
ScratcherLotto.Stone.InvalidateProperties();
ScratcherLotto.Stone.UpdateSatellites();
}
}
if (Owner != null)
Owner.SendMessage(42, "It looks like you have a winning ticket!");
}
private double CraftingSkill(Mobile from)
{
double topSkill = from.Skills[SkillName.Alchemy].Value;
if (from.Skills[SkillName.Fletching].Value > topSkill)
topSkill = from.Skills[SkillName.Fletching].Value;
if (from.Skills[SkillName.Blacksmith].Value > topSkill)
topSkill = from.Skills[SkillName.Blacksmith].Value;
if (from.Skills[SkillName.Tailoring].Value > topSkill)
topSkill = from.Skills[SkillName.Tailoring].Value;
if (from.Skills[SkillName.Inscribe].Value > topSkill)
topSkill = from.Skills[SkillName.Inscribe].Value;
if (from.Skills[SkillName.Carpentry].Value > topSkill)
topSkill = from.Skills[SkillName.Carpentry].Value;
if (from.Skills[SkillName.Tinkering].Value > topSkill)
topSkill = from.Skills[SkillName.Tinkering].Value;
return topSkill;
}
public CrazedCrafting(Serial serial)
: base(serial)
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); //Version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,131 @@
using Server;
using System;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Engines.LotterySystem;
using Server.Gumps;
using Server.Items;
namespace Server.Items
{
public class GoldenTicket : BaseLottoTicket
{
private int[] m_WinAmounts = new int[] { 1000, 5000, 25000, 100000, 250000, 1000000, 2 };
public static readonly int TicketCost = 1000;
[Constructable]
public GoldenTicket() :this(null, false)
{
}
[Constructable]
public GoldenTicket(Mobile owner, bool quickScratch) : base (owner, TicketType.GoldenTicket, quickScratch)
{
Name = "a golden ticket";
LootType = LootType.Blessed;
Hue = 0x8A5;
}
public override void CheckScratches()
{
if (Scratch1 > 0 && Scratch2 > 0 && Scratch3 > 0 && !Checked)
{
Checked = true;
if (Scratch1 == 2 || Scratch2 == 2 || Scratch3 == 2)
FreeTicket = true;
else if (Scratch1 == Scratch2 && Scratch1 == Scratch3)
{
if (Scratch1 == 2)
Payout = 250000;
else
Payout = Scratch1;
DoWin();
if (ScratcherLotto.Stone != null)
ScratcherLotto.Stone.GoldSink -= Payout;
}
}
InvalidateProperties();
}
public override bool DoScratch(int scratch, Mobile from)
{
if (scratch > 3 || scratch < 0 || from == null)
return false;
int pick;
int pickAmount;
try
{
int[] odds = ReturnOdds(from);
pick = odds[Utility.Random(odds.Length)];
pickAmount = m_WinAmounts[pick];
}
catch
{
return false;
}
switch (scratch)
{
case 1: Scratch1 = pickAmount; break;
case 2: Scratch2 = pickAmount; break;
case 3: Scratch3 = pickAmount; break;
default: return false;
}
CheckScratches();
return true;
}
private int[] ReturnOdds(Mobile from)
{
if (from != null && from.Luck >= 1800 || (from.Luck > 1200 && Utility.RandomBool()))
return new int[] { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6 };
return new int[] { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6 };
}
private void DoWin()
{
if (Owner != null)
Owner.PlaySound(Owner.Female ? 0x337 : 0x449);
if (Payout >= 100000)
{
new ScratcherStats(Owner, Payout, this.Type);
if (ScratcherLotto.Stone != null)
{
ScratcherLotto.Stone.InvalidateProperties();
ScratcherLotto.Stone.UpdateSatellites();
}
}
if (Owner != null)
Owner.SendMessage(42, "It looks like you have a winning ticket!");
}
public GoldenTicket(Serial serial) : base( serial )
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); //Version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}

View File

@@ -0,0 +1,258 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Network;
using Server.Misc;
using Server.Engines.LotterySystem;
namespace Server.Gumps
{
public class ScratcherGump : Gump
{
private const int labelColor = 88;
private BaseLottoTicket m_Ticket;
private Mobile m_From;
public ScratcherGump(BaseLottoTicket ticket, Mobile from)
: base(50, 50)
{
m_Ticket = ticket;
m_From = from;
int bg = GetBackGround();
AddBackground(50, 0, 400, 200, bg);
AddImage(125, 12, 0xFC4);
AddImage(325, 12, 0xFC4);
AddHtml(50, 20, 400, 30, String.Format("<Center><BASEFONT SIZE=9>{0}</Center>", ScratcherLotto.GetGameType(m_Ticket.Type)), false, false);
if (m_Ticket.Checked && m_Ticket.Payout > 0)
AddHtml(75, 150, 200, 20, String.Format("<Basefont Color=#FFFF00>Winnings: {0}</Basefont>", m_Ticket.Payout), false, false);
switch (m_Ticket.Type)
{
case TicketType.GoldenTicket: GoldTicket(); break;
case TicketType.CrazedCrafting: CrazedCrafting(); break;
case TicketType.SkiesTheLimit: SkiesTheLimit(); break;
}
AddHtml(75, 170, 350, 20, String.Format("<Basefont Size=2>Lotto Association of {0}, All Rights Reserved</Basefont>", ServerList.ServerName), false, false);
}
private void GoldTicket()
{
int yStart = 90;
if (m_Ticket.Scratch1 == 0)
AddButton(80, yStart, 0x98B, 0x98B, 1, GumpButtonType.Reply, 0);
else if (m_Ticket.Scratch1 == 2)
AddHtml(60, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#FFFF00><Center>Free</Center></Basefont>"), false, false);
else
{
string num = String.Format("{0:##,###,###}", m_Ticket.Scratch1);
AddHtml(60, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#FFFF00><Center>{0}</Center></Basefont>", num), false, false);
}
if (m_Ticket.Scratch2 == 0)
AddButton(220, yStart, 0x98B, 0x98B, 2, GumpButtonType.Reply, 0);
else if (m_Ticket.Scratch2 == 2)
AddHtml(200, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#FFFF00><Center>Free</Center></Basefont>"), false, false);
else
{
string num = String.Format("{0:##,###,###}", m_Ticket.Scratch2);
AddHtml(200, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#FFFF00><Center>{0}</Center></Basefont>", num), false, false);
}
if (m_Ticket.Scratch3 == 0)
AddButton(360, yStart, 0x98B, 0x98B, 3, GumpButtonType.Reply, 0);
else if (m_Ticket.Scratch3 == 2)
AddHtml(340, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#FFFF00><Center>Free</Center></Basefont>"), false, false);
else
{
string num = String.Format("{0:##,###,###}", m_Ticket.Scratch3);
AddHtml(340, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#FFFF00><Center>{0}</Center></Basefont>", num), false, false);
}
}
private void CrazedCrafting()
{
int yStart = 75;
AddImage(70, yStart - 10, 0x589);
AddImage(210, yStart - 10, 0x589);
AddImage(350, yStart - 10, 0x589);
CrazedCrafting ticket = null;
if (m_Ticket is CrazedCrafting)
ticket = (CrazedCrafting)m_Ticket;
if (ticket != null)
{
if (m_Ticket.Scratch1 == 0)
AddButton(79, yStart, 0x15C3, 0x15C4, 1, GumpButtonType.Reply, 0);
else if (m_Ticket.Scratch1 == 2)
AddHtml(71, yStart + 20, 80, 20, String.Format("<Basefont Size=6 Color=#FFFF00><Center>Free</Center></Basefont>"), false, false);
else
{
bool wildCard = false;
foreach (int num in ticket.WildCards)
{
if (m_Ticket.Scratch1 == num)
{
AddImage(80, yStart, num, 2);
wildCard = true;
}
}
if (!wildCard)
{
string value = String.Format("{0:##,###,###}", ticket.Scratch1);
AddHtml(71, yStart + 20, 80, 20, String.Format("<Basefont Size=6 Color=#FFFF00><Center>{0}</Center></Basefont>", value), false, false);
AddImage(80, yStart, 0x15AA, 1);
}
}
if (m_Ticket.Scratch2 == 0)
AddButton(219, yStart, 0x15C3, 0x15C4, 2, GumpButtonType.Reply, 0);
else if (m_Ticket.Scratch2 == 2)
AddHtml(211, yStart + 20, 80, 20, String.Format("<Basefont Size=6 Color=#FFFF00><Center>Free</Center></Basefont>"), false, false);
else
{
bool wildCard = false;
foreach (int num in ticket.WildCards)
{
if (m_Ticket.Scratch2 == num)
{
AddImage(220, yStart, num, 2);
wildCard = true;
}
}
if (!wildCard)
{
string value = String.Format("{0:##,###,###}", ticket.Scratch2);
AddHtml(211, yStart + 20, 80, 20, String.Format("<Basefont Size=6 Color=#FFFF00><Center>{0}</Center></Basefont>", value), false, false);
AddImage(220, yStart, 0x15AA, 1);
}
}
if (m_Ticket.Scratch3 == 0)
AddButton(359, yStart, 0x15C3, 0x15C4, 3, GumpButtonType.Reply, 0);
else if (m_Ticket.Scratch3 == 2)
AddHtml(351, yStart + 20, 80, 20, String.Format("<Basefont Size=6 Color=#FFFF00><Center>Free</Center></Basefont>"), false, false);
else
{
bool wildCard = false;
foreach (int num in ticket.WildCards)
{
if (m_Ticket.Scratch3 == num)
{
AddImage(360, yStart, num, 2);
wildCard = true;
}
}
if (!wildCard)
{
string value = String.Format("{0:##,###,###}", ticket.Scratch3);
AddHtml(351, yStart + 20, 80, 20, String.Format("<Basefont Size=6 Color=#FFFF00><Center>{0}</Center></Basefont>", value), false, false);
AddImage(360, yStart, 0x15AA, 1);
}
}
}
else
{
AddHtml(110, yStart, 80, 20, "<Basefont Size=6 Color=#FFFF00><Center>Void</Center></Basefont>", false, false);
AddHtml(250, yStart, 80, 20, "<Basefont Size=6 Color=#FFFF00><Center>Void</Center></Basefont>", false, false);
AddHtml(250, yStart, 80, 20, "<Basefont Size=6 Color=#FFFF00><Center>Void</Center></Basefont>", false, false);
}
}
private void SkiesTheLimit()
{
int yStart = 90;
if (m_Ticket.Scratch1 == 0)
AddButton(80, yStart, 0x98B, 0x98B, 1, GumpButtonType.Reply, 0);
else if (m_Ticket.Scratch1 == 2)
AddHtml(60, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#0000FF><Center>Free</Center></Basefont>"), false, false);
else if (m_Ticket.Scratch1 == 1)
{
AddImage(100, yStart - 5, 0x265A);
AddItem(98, yStart, 0xEEF);
AddItem(108, yStart, 0xEEF);
}
else
{
string value = String.Format("{0:##,###,###}", m_Ticket.Scratch1);
AddHtml(60, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#0000FF><Center>{0}</Center></Basefont>", value), false, false);
}
if (m_Ticket.Scratch2 == 0)
AddButton(220, yStart, 0x98B, 0x98B, 2, GumpButtonType.Reply, 0);
else if (m_Ticket.Scratch2 == 2)
AddHtml(200, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#0000FF><Center>Free</Center></Basefont>"), false, false);
else if (m_Ticket.Scratch2 == 1)
{
AddImage(240, yStart - 5, 0x265A);
AddItem(238, yStart, 0xEEF);
AddItem(248, yStart, 0xEEF);
}
else
{
string value = String.Format("{0:##,###,###}", m_Ticket.Scratch2);
AddHtml(200, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#0000FF><Center>{0}</Center></Basefont>", value), false, false);
}
if (m_Ticket.Scratch3 == 0)
AddButton(360, yStart, 0x98B, 0x98B, 3, GumpButtonType.Reply, 0);
else if (m_Ticket.Scratch3 == 2)
AddHtml(340, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#0000FF><Center>Free</Center></Basefont>"), false, false);
else if (m_Ticket.Scratch3 == 1)
{
AddImage(380, yStart - 5, 0x265A);
AddItem(378, yStart, 0xEEF);
AddItem(388, yStart, 0xEEF);
}
else
{
string value = String.Format("{0:##,###,###}", m_Ticket.Scratch3);
AddHtml(340, yStart, 100, 60, String.Format("<Basefont Size=8 COLOR=#0000FF><Center>{0}</Center></Basefont>", value), false, false);
}
}
public override void OnResponse(NetState state, RelayInfo info)
{
int res = info.ButtonID;
if (res < 4 && res > 0)
{
if (!m_Ticket.DoScratch(res, m_From))
m_From.SendMessage("Put some elbow greese in it next time!");
m_From.PlaySound(0x249);
m_From.SendGump(new ScratcherGump(m_Ticket, m_From));
}
}
private int GetBackGround()
{
if (m_Ticket != null)
{
switch (m_Ticket.Type)
{
case TicketType.CrazedCrafting: return 0x2454;
case TicketType.SkiesTheLimit: return 0x2486;
case TicketType.GoldenTicket: return 0xDAC;
}
}
return 9270;
}
}
}

View File

@@ -0,0 +1,416 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Misc;
using Server.Network;
using Server.Engines.LotterySystem;
namespace Server.Gumps
{
public class ScratcherStoneGump : Gump
{
private const int labelColor = 2106;
private const int GMColor = 33;
private ScratcherLotto m_Stone;
private Mobile m_From;
public ScratcherStoneGump(ScratcherLotto stone, Mobile from) : this( stone, from, true)
{
}
public ScratcherStoneGump(ScratcherLotto stone, Mobile from, bool quickScratch)
: base(50, 50)
{
m_Stone = stone;
m_From = from;
AddPage(0);
AddBackground(50, 0, 350, 350, 9250);
AddPage(1);
if (m_From.AccessLevel > AccessLevel.Player)
{
AddLabel(70, 265, GMColor, String.Format("Gold Sink: {0}", m_Stone.GoldSink));
if (ScratcherLotto.Stone != null)
{
AddLabel(230, 265, GMColor, "Next Stats Reset:");
AddLabel(230, 295, GMColor, String.Format("{0}", ScratcherLotto.Stone.StatStart + ScratcherLotto.Stone.WipeStats));
}
AddLabel(105, 295, GMColor, m_Stone.IsActive ? "Set Game Inactive" : "Set Active");
AddButton(70, 295, 0xFBD, 0xFBF, 6, GumpButtonType.Reply, 0);
}
AddHtml(70, 20, 300, 16, String.Format("<Center>{0} Lottery Scratchers</Center>", ServerList.ServerName), false, false);
#region Quick/Normal Scratch Radio
AddLabel(110, 40, labelColor, "Quick Scratch");
AddLabel(110, 73, labelColor, "Normal Scratch");
AddRadio(70, 40, 0x25F8, 0x25FB, quickScratch, 0);
AddRadio(70, 70, 0x25F8, 0x25FB, !quickScratch, 1);
#endregion
#region Ticket Info
AddLabel(60, 117, labelColor, "Buy Ticket");
AddLabel(230, 117, labelColor, "Cost");
AddLabel(350, 117, labelColor, "Stats");
AddLabel(110, 140, 0, "Golden Ticket");
if (ScratcherLotto.Stone != null && ScratcherLotto.Stone.IsActive)
{
AddButton(70, 140, 0xFBD, 0xFBF, (int)TicketType.GoldenTicket, GumpButtonType.Reply, 0);
AddLabel(230, 140, 0, GoldenTicket.TicketCost.ToString());
AddButton(350, 140, 0xFA5, 0xFA7, 0, GumpButtonType.Page, (int)TicketType.GoldenTicket + 1);
}
else
AddLabel(230, 140, GMColor, "Offline");
AddLabel(110, 170, 0, "Crazed Crafting");
if (ScratcherLotto.Stone != null && ScratcherLotto.Stone.IsActive)
{
AddButton(70, 170, 0xFBD, 0xFBF, (int)TicketType.CrazedCrafting, GumpButtonType.Reply, 0);
AddLabel(230, 170, 0, CrazedCrafting.TicketCost.ToString());
AddButton(350, 170, 0xFA5, 0xFA7, 0, GumpButtonType.Page, (int)TicketType.CrazedCrafting + 1);
}
else
AddLabel(230, 170, GMColor, "Offline");
AddLabel(110, 200, 0, "Skies the Limit");
if (ScratcherLotto.Stone != null && ScratcherLotto.Stone.IsActive)
{
AddButton(70, 200, 0xFBD, 0xFBF, (int)TicketType.SkiesTheLimit, GumpButtonType.Reply, 0);
AddLabel(230, 200, 0, SkiesTheLimit.TicketCost.ToString());
AddButton(350, 200, 0xFA5, 0xFA7, 0, GumpButtonType.Page, (int)TicketType.SkiesTheLimit + 1);
}
else
AddLabel(230, 200, GMColor, "Offline");
AddLabel(110, 230, 0, "Powerball");
if (PowerBall.Instance != null && PowerBall.Game != null && !PowerBall.Game.Deleted && PowerBall.Instance.CanBuyTickets)
{
AddLabel(230, 230, 0, PowerBall.Game != null ? PowerBall.Game.TicketCost.ToString() : "");
AddButton(70, 230, 0xFBD, 0xFBF, (int)TicketType.Powerball, GumpButtonType.Reply, 0);
}
else
AddLabel(230, 230, GMColor, "Offline");
#endregion
AddPage(2); //Golden Ticket Stats
AddLabel(70, 20, labelColor, "Golden Ticket Top 10 Winners");
int index = 0;
for(int i = ScratcherStats.Stats.Count - 1; i >= 0; --i)
{
if (ScratcherStats.Stats[i].Type == TicketType.GoldenTicket)
{
string num = String.Format("{0:##,###,###}", ScratcherStats.Stats[i].Payout);
string name = "unknown player";
if (ScratcherStats.Stats[i].Winner != null)
name = ScratcherStats.Stats[i].Winner.Name;
AddHtml(70, 50 + (index * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", name), false, false);
AddHtml(150, 50 + (index * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", num), false, false);
AddHtml(270, 50 + (index * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", ScratcherStats.Stats[i].WinTime), false, false);
index++;
}
if (index >= 9)
break;
}
AddButton(350, 300, 0xFAE, 0xFB0, 0, GumpButtonType.Page, 1);
AddPage(3); //Crazed Crafting Stats
AddLabel(70, 20, labelColor, "Crazed Crafting Highest Winners");
index = 0;
for (int i = ScratcherStats.Stats.Count - 1; i >= 0; --i)
{
if (ScratcherStats.Stats[i].Type == TicketType.CrazedCrafting)
{
string num = String.Format("{0:##,###,###}", ScratcherStats.Stats[i].Payout);
string name = "unknown player";
if (ScratcherStats.Stats[i].Winner != null)
name = ScratcherStats.Stats[i].Winner.Name;
AddHtml(70, 50 + (index * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", name), false, false);
AddHtml(150, 50 + (index * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", num), false, false);
AddHtml(270, 50 + (index * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", ScratcherStats.Stats[i].WinTime), false, false);
index++;
}
if (index >= 9)
break;
}
AddButton(350, 300, 0xFAE, 0xFB0, 0, GumpButtonType.Page, 1);
AddPage(4); //Skies the Limit Stats
AddLabel(70, 20, labelColor, "Skies the Limit");
AddLabel(70, 300, labelColor, String.Format("Progressive Jackpot: {0}", m_Stone.SkiesProgressive));
index = 0;
for (int i = ScratcherStats.Stats.Count - 1; i >= 0; --i)
{
if (ScratcherStats.Stats[i].Type == TicketType.SkiesTheLimit)
{
string num = String.Format("{0:##,###,###}", ScratcherStats.Stats[i].Payout);
string name = "unknown player";
if (ScratcherStats.Stats[i].Winner != null)
name = ScratcherStats.Stats[i].Winner.Name;
AddHtml(70, 50 + (index * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", name), false, false);
AddHtml(150, 50 + (index * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", num), false, false);
AddHtml(270, 50 + (index * 25), 100, 16, String.Format("<Basefont Color=#FFFFFF>{0}</Basefont>", ScratcherStats.Stats[i].WinTime), false, false);
index++;
}
if (index >= 9)
break;
}
AddButton(350, 300, 0xFAE, 0xFB0, 0, GumpButtonType.Page, 1);
}
private BaseLottoTicket FindFreeTicket(Container pack, Type type)
{
if (pack == null)
return null;
Item[] items = pack.FindItemsByType(typeof(BaseLottoTicket));
foreach (Item item in items)
{
if (item is BaseLottoTicket && item.GetType() == type && ((BaseLottoTicket)item).FreeTicket)
return (BaseLottoTicket)item;
}
return null;
}
public override void OnResponse(NetState state, RelayInfo info)
{
if (m_From == null)
return;
Container pack = m_From.Backpack;
bool quickScratch = info.IsSwitched(0);
switch (info.ButtonID)
{
default:
case 0: break;
case 1: //Golden Ticket
{
int cost = GoldenTicket.TicketCost;
if (ScratcherLotto.Stone != null && ScratcherLotto.Stone.IsActive)
{
BaseLottoTicket free = FindFreeTicket(pack, typeof(GoldenTicket));
if (free != null && free is GoldenTicket)
{
free.Delete();
m_From.SendMessage("You purchase a lottery ticket with your free ticket.", cost);
DropItem(new GoldenTicket(m_From, quickScratch));
}
else if (pack != null && pack.GetAmount(typeof(Gold)) >= cost)
{
pack.ConsumeTotal(typeof(Gold), cost);
m_From.SendMessage("You purchase a lottery ticket with {0} gold from your backpack.", cost);
DropItem(new GoldenTicket(m_From, quickScratch));
if (m_Stone != null)
m_Stone.GoldSink += cost;
}
else if (Banker.Withdraw(m_From, cost, true))
{
m_From.SendMessage("You purchase a lottery ticket with {0} gold from your bankbox.", cost);
DropItem(new GoldenTicket(m_From, quickScratch));
if (m_Stone != null)
m_Stone.GoldSink += cost;
}
else
m_From.SendLocalizedMessage(500191); //Begging thy pardon, but thy bank account lacks these funds.
}
m_From.SendGump(new ScratcherStoneGump(m_Stone, m_From, quickScratch));
break;
}
case 2: //Crazed Crafting
{
int cost = CrazedCrafting.TicketCost;
if (ScratcherLotto.Stone != null && ScratcherLotto.Stone.IsActive)
{
BaseLottoTicket free = FindFreeTicket(pack, typeof(CrazedCrafting));
if (free != null && free is CrazedCrafting)
{
free.Delete();
m_From.SendMessage("You purchase a lottery ticket with your free ticket.", cost);
DropItem(new CrazedCrafting(m_From, quickScratch));
}
else if (pack != null && pack.GetAmount(typeof(Gold)) >= cost)
{
pack.ConsumeTotal(typeof(Gold), cost);
m_From.SendMessage("You purchase a lottery ticket with {0} gold from your backpack.", cost);
DropItem(new CrazedCrafting(m_From, quickScratch));
if (m_Stone != null)
m_Stone.GoldSink += cost;
}
else if (Banker.Withdraw(m_From, cost, true))
{
m_From.SendMessage("You purchase a lottery ticket with {0} gold from your bankbox.", cost);
DropItem(new CrazedCrafting(m_From, quickScratch));
if (m_Stone != null)
m_Stone.GoldSink += cost;
}
else
m_From.SendLocalizedMessage(500191); //Begging thy pardon, but thy bank account lacks these funds.
}
m_From.SendGump(new ScratcherStoneGump(m_Stone, m_From, quickScratch));
break;
}
case 3: //Skies the Limit
{
int cost = SkiesTheLimit.TicketCost;
if (ScratcherLotto.Stone != null && ScratcherLotto.Stone.IsActive)
{
BaseLottoTicket free = FindFreeTicket(pack, typeof(SkiesTheLimit));
if (free != null && free is SkiesTheLimit)
{
free.Delete();
m_From.SendMessage("You purchase a lottery ticket with your free ticket.", cost);
DropItem(new SkiesTheLimit(m_From, quickScratch));
}
else if (pack != null && pack.GetAmount(typeof(Gold)) >= cost)
{
pack.ConsumeTotal(typeof(Gold), cost);
m_From.SendMessage("You purchase a lottery ticket with {0} gold from your backpack.", cost);
DropItem(new SkiesTheLimit(m_From, quickScratch));
if (m_Stone != null)
m_Stone.GoldSink += cost;
m_Stone.SkiesProgressive += cost / 10;
}
else if (Banker.Withdraw(m_From, cost, true))
{
m_From.SendMessage("You purchase a lottery ticket with {0} gold from your bankbox.", cost);
DropItem(new SkiesTheLimit(m_From, quickScratch));
if (m_Stone != null)
m_Stone.GoldSink += cost;
m_Stone.SkiesProgressive += cost / 10;
}
else
m_From.SendLocalizedMessage(500191); //Begging thy pardon, but thy bank account lacks these funds.
}
m_From.SendGump(new ScratcherStoneGump(m_Stone, m_From, quickScratch));
break;
}
case 4: //PowerBall Ticket
{
if (PowerBall.Instance != null && PowerBall.Game != null && !PowerBall.Game.Deleted && PowerBall.Instance.CanBuyTickets)
{
int cost = PowerBall.Game.TicketCost;
if (pack != null && pack.GetAmount(typeof(Gold)) >= cost)
{
pack.ConsumeTotal(typeof(Gold), cost);
m_From.SendMessage("You purchase a Powerball ticket with {0} gold from your backpack.", cost);
DropItem(new PowerBallTicket(m_From, PowerBall.Game));
if (PowerBall.Instance != null)
PowerBall.Instance.Profit += cost;
}
else if (Banker.Withdraw(m_From, cost, true))
{
m_From.SendMessage("You purchase a Powerball ticket with {0} gold from your bankbox.", cost);
DropItem(new PowerBallTicket(m_From, PowerBall.Game));
if (PowerBall.Instance != null)
PowerBall.Instance.Profit += cost;
}
else
m_From.SendLocalizedMessage(500191); //Begging thy pardon, but thy bank account lacks these funds.
}
m_From.SendGump(new ScratcherStoneGump(m_Stone, m_From, quickScratch));
break;
}
case 5:
{
if (PowerBall.Game != null)
m_From.SendGump(new PowerBallStatsGump(PowerBall.Game, m_From));
break;
}
case 6:
{
if (m_From.AccessLevel == AccessLevel.Player)
break;
if (m_Stone != null)
{
if (m_Stone.IsActive)
{
m_From.SendMessage("set to inactive.");
m_Stone.IsActive = false;
}
else
{
m_From.SendMessage("set to active.");
m_Stone.IsActive = true;
}
}
m_From.SendGump(new ScratcherStoneGump(m_Stone, m_From, quickScratch));
break;
}
}
}
private void DropItem(Item item)
{
Container pack = m_From.Backpack;
if (pack == null || !pack.TryDropItem(m_From, item, false))
{
m_From.SendMessage("Your pack is full, so the ticket has been placed in your bank box!");
m_From.BankBox.DropItem(item);
}
}
}
}

View File

@@ -0,0 +1,36 @@
Lotto Scratchers
All scratchers derive from BaseLottoTicket class. You can adjust the odds in the ReturnOdds(...)
function of each ticket type. Player luck effects Golden Ticket and Skies the Limit. Player
Crafting skill (highest skill) effects Crazed Crafting. Luck/craft skill bumps do not increase
the chace of a win, but increased the odds of a higher prize per scratch.
First, place LottoScratcher, this is the item that controls the stats, progressive jackpots, etc.
You can then place LottoScratcherSatellite that acts as the LottoScratcher item, like the PowerBallSatellite.
ScratcherLotto.cs -
DeleteTicketOnLoss defaulted to true. When true, and you purchase a ticket as a quick scratch,
the ticket will auto delete if it's not a winner.
Golden Ticket
- Traditional lotto scratch ticket
- Prizes range from 1000 to 1,000,000
- 1200+ luck and a 50% chance odds will go in favor of higher prize
- 1800+ odds will go in favor of a higher price
Crazed Crafting
- This has a lower standard payout, however, wild cards can increase the chances for a win
- 2 of the same wild cards give a 2x reward multiplier
- 3 of the same wild cards, which always will result in a jackpot, give a 10x multiplier
- prizes range from 2,500 to 250,000, or 2,500,000 with a wildcard multiplier
- 8% flat chance to get a wildcard
Skies the Limit
- Progressive lotto scrather
- Progressive gold amount is saved in the ScratherLotto item
- Resets to 500,000 with a win
- 3 Treasure chests win the progressive
- Normal payout is from 1,000 to 500,000
Stats reset every 90 days

View File

@@ -0,0 +1,261 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
using Server.Gumps;
using Server.Network;
using System.Collections.Generic;
namespace Server.Engines.LotterySystem
{
public class ScratcherLotto : Item
{
private bool m_DeleteTicket; //Deletes ticket on quick scratch if it is a losing ticket
private bool m_Active;
private int m_GoldSink; //Eye candy for GM's!!!
private int m_SkiesProgressive; //Progressive for Skies the Limit
private DateTime m_StatStart;
private TimeSpan m_WipeStats;
[CommandProperty(AccessLevel.GameMaster)]
public bool DeleteTicketOnLoss { get { return m_DeleteTicket; } set { m_DeleteTicket = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public bool IsActive { get { return m_Active; } set { m_Active = value; InvalidateProperties(); UpdateSatellites(); } }
[CommandProperty(AccessLevel.GameMaster)]
public int GoldSink { get { return m_GoldSink; } set { m_GoldSink = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public int SkiesProgressive { get { return m_SkiesProgressive; } set { m_SkiesProgressive = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public DateTime StatStart { get { return m_StatStart; } set { m_StatStart = value; } }
[CommandProperty(AccessLevel.GameMaster)]
public TimeSpan WipeStats { get { return m_WipeStats; } set { m_WipeStats = value; } }
public bool CanWipe { get { return m_StatStart + m_WipeStats < DateTime.Now; } }
private static ScratcherLotto m_Stone; //Instanced Stone for easy access
public static ScratcherLotto Stone{ get { return m_Stone; } set { m_Stone = value; } }
private static List<ScratcherLottoSatellite> m_SatList = new List<ScratcherLottoSatellite>();
public static List<ScratcherLottoSatellite> SatList { get { return m_SatList; } }
[Constructable]
public ScratcherLotto()
: base(0xED4)
{
if (CheckForScratcherStone())
{
Console.WriteLine("You can only have one Lotto Scratcher Stone Item.");
Delete();
return;
}
Name = "Lottery Scratch Tickets";
Hue = Utility.RandomSlimeHue();
Movable = false;
m_Active = true;
m_Stone = this;
m_SkiesProgressive = 500000;
m_DeleteTicket = true;
m_WipeStats = TimeSpan.FromDays(90);
m_StatStart = DateTime.Now;
}
public override void OnDoubleClick(Mobile from)
{
if (!m_Active && from.AccessLevel == AccessLevel.Player)
from.SendMessage("Scratch tickets are currenlty inactive at this time.");
else if (from.InRange(Location, 3))
{
if (from.HasGump(typeof(ScratcherStoneGump)))
from.CloseGump(typeof(ScratcherStoneGump));
from.SendGump(new ScratcherStoneGump(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 (ScratcherStats.Stats.Count > 0)
{
try
{
int index = ScratcherStats.Stats.Count - 1;
string jackpotAmount = String.Format("{0:##,###,###}", ScratcherStats.Stats[index].Payout);
list.Add(1060659, "Last Big Win\t{0}", ScratcherStats.Stats[index].Winner.Name);
list.Add(1060660, "Date\t{0}", ScratcherStats.Stats[index].WinTime);
list.Add(1060661, "Amount\t{0}", jackpotAmount);
list.Add(1060662, "Game\t{0}", GetGameType(ScratcherStats.Stats[index].Type));
}
catch
{
}
}
}
public static string GetGameType(TicketType type)
{
switch (type)
{
default: return "";
case TicketType.GoldenTicket: return "Golden Ticket";
case TicketType.CrazedCrafting: return "Crazed Crafting";
case TicketType.SkiesTheLimit: return "Skies the Limit";
case TicketType.Powerball: return "Powerball";
}
}
public static void DoProgressiveMessage(Mobile winner, int amount)
{
string name = "Somebody";
if (winner != null)
name = winner.Name;
foreach (NetState netState in NetState.Instances)
{
Mobile m = netState.Mobile;
if (m != null)
{
m.PlaySound(1460);
m.SendMessage(33, "{0} has won {1} gold in the Skies the Limit Progressive Scratcher!", name, amount.ToString());
}
}
}
private void DoWipe()
{
if (ScratcherStats.Stats != null)
ScratcherStats.Stats.Clear();
UpdateSatellites();
InvalidateProperties();
m_StatStart = DateTime.Now;
}
public void UpdateSatellites()
{
foreach (ScratcherLottoSatellite sat in m_SatList)
{
if (sat != null && !sat.Deleted)
sat.InvalidateProperties();
}
}
public ScratcherLotto(Serial serial) : base( serial )
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)2); //Version
writer.Write(m_WipeStats);
writer.Write(m_StatStart);
writer.Write(m_DeleteTicket);
writer.Write(m_Active);
writer.Write(m_GoldSink);
writer.Write(m_SkiesProgressive);
writer.Write(ScratcherStats.Stats.Count);
for (int i = 0; i < ScratcherStats.Stats.Count; ++i)
{
ScratcherStats.Stats[i].Serialize(writer);
}
if (CanWipe)
Timer.DelayCall(TimeSpan.FromSeconds(5), new TimerCallback(DoWipe));
InvalidateProperties();
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
switch (version)
{
case 2:
{
m_WipeStats = reader.ReadTimeSpan();
m_StatStart = reader.ReadDateTime();
goto case 1;
}
case 1:
{
m_DeleteTicket = reader.ReadBool();
goto case 0;
}
case 0:
{
m_Active = reader.ReadBool();
m_GoldSink = reader.ReadInt();
m_SkiesProgressive = reader.ReadInt();
int statsCount = reader.ReadInt();
for (int i = 0; i < statsCount; i++)
{
new ScratcherStats(reader);
}
break;
}
}
m_Stone = this;
}
public override void OnAfterDelete()
{
for (int i = 0; i < m_SatList.Count; ++i)
{
if (m_SatList[i] != null && !m_SatList[i].Deleted)
m_SatList[i].Delete();
}
}
private bool CheckForScratcherStone()
{
foreach (Item item in World.Items.Values)
{
if (item is ScratcherLotto && !item.Deleted && item != this)
return true;
}
return false;
}
public void AddToSatList(ScratcherLottoSatellite satellite)
{
if (m_SatList != null && !m_SatList.Contains(satellite))
m_SatList.Add(satellite);
}
public void RemoveFromSatList(ScratcherLottoSatellite satellite)
{
if (m_SatList != null && m_SatList.Contains(satellite))
m_SatList.Remove(satellite);
}
}
}

View File

@@ -0,0 +1,111 @@
using System;
using Server;
using Server.Items;
using Server.Mobiles;
using Server.Targeting;
using Server.Gumps;
using Server.Network;
using System.Collections.Generic;
namespace Server.Engines.LotterySystem
{
public class ScratcherLottoSatellite : Item
{
private ScratcherLotto m_Stone;
[CommandProperty(AccessLevel.GameMaster)]
public ScratcherLotto LottoStone { get { return m_Stone; } set { m_Stone = value; } }
[Constructable]
public ScratcherLottoSatellite()
: base(0xED4)
{
Name = "Lottery Scratch Tickets";
Hue = Utility.RandomSlimeHue();
Movable = false;
if (ScratcherLotto.Stone != null)
{
m_Stone = ScratcherLotto.Stone;
m_Stone.AddToSatList(this);
}
else Delete();
}
public override void OnDoubleClick(Mobile from)
{
if (m_Stone == null || (!m_Stone.IsActive && from.AccessLevel == AccessLevel.Player))
from.SendMessage("Scratch tickets are currenlty inactive at this time.");
else if (from.InRange(Location, 3))
{
if (from.HasGump(typeof(ScratcherStoneGump)))
from.CloseGump(typeof(ScratcherStoneGump));
from.SendGump(new ScratcherStoneGump(m_Stone, from));
}
else if (from.AccessLevel > AccessLevel.Player)
from.SendGump( new PropertiesGump( from, m_Stone ) );
else
from.SendLocalizedMessage(500446); // That is too far away.
}
public override void GetProperties(ObjectPropertyList list)
{
base.GetProperties(list);
if (m_Stone == null || !m_Stone.IsActive)
list.Add(1060658, "Status\tOffline");
else
list.Add(1060658, "Status\tActive");
if (ScratcherStats.Stats.Count > 0)
{
try
{
int index = ScratcherStats.Stats.Count - 1;
string jackpotAmount = String.Format("{0:##,###,###}", ScratcherStats.Stats[index].Payout);
list.Add(1060659, "Last Big Win\t{0}", ScratcherStats.Stats[index].Winner.Name);
list.Add(1060660, "Date\t{0}", ScratcherStats.Stats[index].WinTime);
list.Add(1060661, "Amount\t{0}", jackpotAmount);
list.Add(1060662, "Game\t{0}", ScratcherLotto.GetGameType(ScratcherStats.Stats[index].Type));
}
catch
{
}
}
}
public override void OnAfterDelete()
{
if (m_Stone != null)
m_Stone.RemoveFromSatList(this);
base.OnAfterDelete();
}
public ScratcherLottoSatellite(Serial serial) : base( serial )
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int)0); //Version
writer.Write(m_Stone);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
m_Stone = (ScratcherLotto)reader.ReadItem();
if (m_Stone != null)
m_Stone.AddToSatList(this);
}
}
}

View File

@@ -0,0 +1,59 @@
using System;
using Server;
using Server.Mobiles;
using System.Collections.Generic;
namespace Server.Engines.LotterySystem
{
public class ScratcherStats
{
private Mobile m_Winner;
private TicketType m_Type;
private int m_Payout;
private DateTime m_WinTime;
public Mobile Winner { get { return m_Winner; } }
public TicketType Type { get { return m_Type; } }
public int Payout { get { return m_Payout; } }
public DateTime WinTime { get { return m_WinTime; } }
private static List<ScratcherStats> m_Stats = new List<ScratcherStats>();
public static List<ScratcherStats> Stats { get { return m_Stats; } }
public ScratcherStats(Mobile winner, int amount, TicketType type) : this(winner, amount, type, DateTime.Now)
{
}
public ScratcherStats(Mobile winner, int amount, TicketType type, DateTime time)
{
m_Winner = winner;
m_Type = type;
m_Payout = amount;
m_WinTime = time;
m_Stats.Add(this);
}
public void Serialize(GenericWriter writer)
{
writer.Write((int)0); //version
writer.Write(m_Winner);
writer.Write((int)m_Type);
writer.Write(m_Payout);
writer.Write(m_WinTime);
}
public ScratcherStats(GenericReader reader)
{
int version = reader.ReadInt();
m_Winner = reader.ReadMobile();
m_Type = (TicketType)reader.ReadInt();
m_Payout = reader.ReadInt();
m_WinTime = reader.ReadDateTime();
m_Stats.Add(this);
}
}
}

View File

@@ -0,0 +1,143 @@
using Server;
using System;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Engines.LotterySystem;
using Server.Gumps;
using Server.Items;
namespace Server.Items
{
public class SkiesTheLimit : BaseLottoTicket
{
private int[] m_WinAmounts = new int[] { 1000, 10000, 50000, 100000, 500000, 1, 2};
public static readonly int TicketCost = 1000;
[Constructable]
public SkiesTheLimit() : this(null, false)
{
}
[Constructable]
public SkiesTheLimit(Mobile owner, bool quickScratch) : base (owner, TicketType.SkiesTheLimit, quickScratch)
{
Name = "skies the limit";
LootType = LootType.Blessed;
Hue = 0x8AB;
this.Type = TicketType.SkiesTheLimit;
}
public override void CheckScratches()
{
if (Scratch1 > 0 && Scratch2 > 0 && Scratch3 > 0)
{
Checked = true;
if (Scratch1 == 2 || Scratch2 == 2 || Scratch3 == 2)
FreeTicket = true;
else if (Scratch1 == Scratch2 && Scratch1 == Scratch3)
{
int payOut = 0;
if (Scratch1 == 2)
payOut = 250000;
else
payOut = Scratch1;
if (ScratcherLotto.Stone != null && Scratch1 == 1)
{
payOut = ScratcherLotto.Stone.SkiesProgressive;
ScratcherLotto.Stone.SkiesProgressive = 500000;
ScratcherLotto.DoProgressiveMessage(Owner, payOut);
}
Payout = payOut;
DoWin(payOut);
if (ScratcherLotto.Stone != null)
ScratcherLotto.Stone.GoldSink -= Payout;
}
}
InvalidateProperties();
}
public override bool DoScratch(int scratch, Mobile from)
{
if (scratch > 3 || scratch < 0 || from == null)
return false;
int pick;
int pickAmount;
try
{
int[] odds = ReturnOdds(from);
pick = odds[Utility.Random(odds.Length)];
pickAmount = m_WinAmounts[pick];
}
catch
{
return false;
}
switch (scratch)
{
case 1: Scratch1 = pickAmount; break;
case 2: Scratch2 = pickAmount; break;
case 3: Scratch3 = pickAmount; break;
default: return false;
}
CheckScratches();
return true;
}
private int[] ReturnOdds(Mobile from)
{
if (from != null && from.Luck >= 1800 || (from.Luck > 1200 && Utility.RandomBool()))
return new int[] { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6 };
return new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6 };
}
private void DoWin(int amount)
{
if (Owner != null)
Owner.PlaySound(Owner.Female ? 0x337 : 0x449);
if (amount >= 100000)
{
new ScratcherStats(Owner, Payout, this.Type);
if (ScratcherLotto.Stone != null)
{
ScratcherLotto.Stone.InvalidateProperties();
ScratcherLotto.Stone.UpdateSatellites();
}
}
if (Owner != null)
Owner.SendMessage(42, "It looks like you have a winning ticket!");
}
public SkiesTheLimit(Serial serial) : base( serial )
{
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.Write((int) 0); //Version
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadInt();
}
}
}