// TMW2 Scripts
// Author:
// Jesusalva
// Description:
// Gambler: Will next card be better or worse?
// $XAN_BETS: How many victories all players already had (for propaganda :3)
031-4,92,84,0 script Gambler#031-4 NPC_PLAYER,{
function deal;
function cardname {
switch (getarg(0)) {
case 1:
return "A"; break;
case 11:
return "J"; break;
case 12:
return "Q"; break;
case 13:
return "K"; break;
default:
return str(getarg(0));
}
}
function suitname {
switch (getarg(0)) {
case 0:
return "Clubs"; break;
case 1:
return "Hearts"; break;
case 2:
return "Spades"; break;
case 3:
return "Diamonds"; break;
default:
return sprintf("%dERROR", getarg(0));
}
}
function playname {
switch (getarg(0)) {
case 23: return l("Royal Straight Flush"); break;
case 22: return l("Royal Straight"); break;
case 21: return l("Straight Flush"); break;
case 20: return l("Four of a Kind"); break;
case 19: return l("Full House"); break;
case 18: return l("Flush"); break;
case 17: return l("Straight"); break;
case 16: return l("Three of a Kind"); break;
case 15: return l("Two Pairs"); break;
case 14: return l("One Pair"); break;
default: return l("%s High", cardname(getarg(0))); break;
}
}
.@showMenu = true;
goto L_Menu;
L_Menu:
showavatar;
if (.@showMenu) {
mesn;
mesc l("Hey, do you want to play my card game?");
mesc l("It's essentially poker: I'll deal you five cards, then determine what you got. After that, I'll deal myself five cards, then determine what I got.");
mesc l("If your hand beats mine, you win. If my hand beats your, I win. Wanna play?");
mesc l("If a tie happens, I'll give your coin back.");
next;
.@showMenu=false;
}
menu
rif(countitem(CasinoCoins) >= 1, l("Let's play!")), L_Spin,
rif(countitem(CasinoCoins) >= 2, l("Make it a quick game!")), L_Short,
l("Information"), L_Info,
l("Leave"), L_Quit;
L_Info:
mes "";
mesc l("Rules:");
mesc l("You'll be given five cards. The winning hand is the one with highest combo.");
mesc l("Combos are ranked on this priority: Royal Straight Flush > Straight Flush > Four of a Kind > Full House > Flush > Straight > Three of a Kind > Two Pairs > One Pair > Card");
mesc l("Cards are ranked on this priority: A - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - J - Q - K");
next;
mesc l("Prizes:");
//mesc("If you beat my hand, you'll win 110 GP!");
mesc l("If you beat my hand, you'll win some GP!");
mesc l("You'll also get a %s!", getitemlink(MaggotSlime));
mesc l("* Slime not included if you didn't got any combo.");
mesc l("If a tie happens, you'll get your coin back.");
mes "";
mesc l("If you get a %s, you'll also get a %s.", playname(23), getitemlink(SupremeGift)); // Royal Straight Flush, 1:100, 0.00015%
mesc l("If you get a %s, you'll also get a %s.", playname(21), getitemlink(PrismGift)); // Straight Flush, 1:50, 0.0014%
mesc l("If you get a %s, you'll also get a %s.", playname(20), getitemlink(AxeHat)); // Four of a Kind, 1:20, 0.024%
mesc l("If you get a %s, you'll also get a %s.", playname(19), getitemlink(BronzeGift)); // Full House, 1:7, 0.10%
mesc l("If you get a %s, you'll also get a %s.", playname(18), getitemlink(MintDonut)); // Flush, 1:5, 0.2%
mesc l("If you get a %s, you'll also get a %s.", playname(17), getitemlink(StrangeCoin)); // Straight, 1:4, 0.4%
// 3oK 1:3 2%, 2P 1:2 5%, Pair 1:1 42%
// No pair has 50.25% chance and has no payout (1:0)
mesc l("You need to beat the Dealer's hand to get those prizes."), 1;
mesc l("If you don't have a %s, you'll receive it instead of the %s.", getitemlink(AxeHat), getitemlink(PrismGift)), 1;
// Source: Encyclopedia Britannica
next;
goto L_Menu;
L_Spin:
clear;
img("cards/cardBack_green");
mesc l("I'll draw your hand now!");
next;
delitem CasinoCoins, 1;
.@myRank = deal();
mesc l("You scored a(n) %s!", b(playname(.@myRank)));
next;
clear;
img("cards/cardBack_red");
mesc l("I'll draw my hand now!");
next;
.@aiRank = deal();
mesc l("I scored a(n) %s!", b(playname(.@aiRank)));
next;
clear;
L_Tally:
if (.@aiRank == .@myRank) {
getitem CasinoCoins, 1;
img("cards/cardBack_blue");
mesc l("It's a tie! You get your coin back!"), 3;
} else if (.@aiRank > .@myRank) {
img("cards/cardBack_red");
mesc l("It looks like I won! Better luck next time!"), 1;
} else if (.@myRank > .@aiRank) {
img("cards/cardBack_green");
mesc l("Ahahah, I concede defeat! Here's your prize!"), 2;
.@gp = 40 + 110 * .@myRank / 18;
getexp .@gp, .@myRank;
switch (.@myRank) {
case 23: getitem SupremeGift, 1; break;
case 21:
if (countitem(AxeHat))
getitem PrismGift, 1;
else
getitem AxeHat, 1;
break;
case 20: getitem AxeHat, 1; break;
case 19: getitem BronzeGift, 1; break;
case 18: getitem MintDonut, 1; break;
case 17: getitem StrangeCoin, 1; break;
case 16:
case 15:
case 14:
getitem MaggotSlime, 1;
// FALLTHROUGH
default:
Zeny += .@gp;
break;
}
X24Event(X24_POKER);
}
dnext;
goto L_Menu;
L_Short:
delitem CasinoCoins, 1;
clear;
img("cards/cardBack_green");
.@myRank = deal();
img("cards/cardBack_red");
.@aiRank = deal();
mes "";
mesc l("You scored a(n) %s!", b(playname(.@myRank)));
mesc l("I scored a(n) %s!", b(playname(.@aiRank)));
dnext;
clear;
mesc l("You scored a(n) %s!", b(playname(.@myRank)));
mesc l("I scored a(n) %s!", b(playname(.@aiRank)));
mes "";
goto L_Tally;
// deal(show=True), returns score
function deal {
// Give you 5 cards
// We cannot "give 7 cards ask to chose 5" because "chose 5" is NOT OK
freeloop(true);
while (getarraysize(.@cards) < 5) {
.@tmp = rand2(52);
if (.@tmp >= 52 || .@tmp < 0) Exception("Poker - Division by zero: "+str(.@tmp), RB_DEBUGMES|RB_IRCBROADCAST|RB_ISFATAL);
if (array_find(.@cards, .@tmp) == -1)
array_push(.@cards, .@tmp);
freeloop(true); // array_find can unset it
}
freeloop(false);
// Get their rank (err... suit) and number (err... actual rank)
// The order doesn't matter, so everything is in an array
.@r[0] = .@cards[0] / 13;
.@n[0] = .@cards[0] % 13 + 1;
.@r[1] = .@cards[1] / 13;
.@n[1] = .@cards[1] % 13 + 1;
.@r[2] = .@cards[2] / 13;
.@n[2] = .@cards[2] % 13 + 1;
.@r[3] = .@cards[3] / 13;
.@n[3] = .@cards[3] % 13 + 1;
.@r[4] = .@cards[4] / 13;
.@n[4] = .@cards[4] % 13 + 1;
// Display the cards? Do it now, before we modify the data
if (getarg(0, true)) {
if ($@GM_OVERRIDE) {
debugmes sprintf("cards/card%s%d", suitname(.@r[0]), .@n[0]);
debugmes sprintf("cards/card%s%d", suitname(.@r[1]), .@n[1]);
debugmes sprintf("cards/card%s%d", suitname(.@r[2]), .@n[2]);
debugmes sprintf("cards/card%s%d", suitname(.@r[3]), .@n[3]);
debugmes sprintf("cards/card%s%d", suitname(.@r[4]), .@n[4]);
}
img(sprintf("cards/card%s%d", suitname(.@r[0]), .@n[0]));
img(sprintf("cards/card%s%d", suitname(.@r[1]), .@n[1]));
img(sprintf("cards/card%s%d", suitname(.@r[2]), .@n[2]));
img(sprintf("cards/card%s%d", suitname(.@r[3]), .@n[3]));
img(sprintf("cards/card%s%d", suitname(.@r[4]), .@n[4]));
}
// Essentially, we don't care if the card number and suit is changed
array_sort_asc(.@n);
// Calculations related to the card number
// FIXME: The array is sorted, do we need O(n²) complexity?
.@t = 0; // Mode Number (from the three M operations = Average, Mode, Median)
.@c = 0; // Count of it
.@p = 0; // Last pair
for (.@i=0;.@i <= 13;.@i++) {
.@tmp = array_count(.@n, .@i);
// An unique pair for Full House and Two Pairs
if (.@tmp == 2 && .@p != .@i)
.@p = .@i;
// More than what we remember
if (.@tmp > .@c) {
.@t = .@i;
.@c = .@tmp;
}
}
// Shorthandlers
.@straight = (.@n[0]+1 == .@n[1] && .@n[1]+1 == .@n[2] && .@n[2]+1 == .@n[3] && .@n[3]+1 == .@n[4]);
.@royal = (.@n[0] == 1 && .@n[1] == 10 && .@n[2] == 11 && .@n[3] == 12 && .@n[4] == 13);
.@flush = (array_count(.@r, 0) == 5 || array_count(.@r, 1) == 5 || array_count(.@r, 2) == 5 || array_count(.@r, 3) == 5);
.@paires = (.@p > 0 && .@p != .@t);
// Complex logic like this one is avoided by sorting
//if (array_find(.@n, 1) && array_find(.@n, 10) && array_find(.@n, 11) && array_find(.@n, 12) && array_find(.@n, 13))
// Determine the result of your hand
// Note that it goes up to 13 (card high), then pair is at 14
if (.@royal && .@flush)
.@result = 23; // Royal Straight Flush
//else if (.@royal) // TODO: Should this be just a straight then?
// .@result = 22; // Royal Straight
else if (.@straight && .@flush)
.@result = 21; // Straight Flush
else if (.@c == 4)
.@result = 20; // Four of a kind
else if (.@c == 3 && .@p > 0)
.@result = 19; // Full house
else if (.@flush)
.@result = 18; // Flush
else if (.@straight)
.@result = 17; // Straight
else if (.@c == 3)
.@result = 16; // Three of a kind
else if (.@c == 2 && .@paires)
.@result = 15; // Two pairs
else if (.@c == 2)
.@result = 14; // One pair
else
.@result = .@n[4]; // Nothing special
return .@result;
}
L_Quit:
closeclientdialog;
close;
OnInit:
.sex = G_MALE;
.distance = 4;
.@npcId = getnpcid(.name$);
setunitdata(.@npcId, UDT_HEADTOP, TopHat);
setunitdata(.@npcId, UDT_HEADMIDDLE, Bathrobe);
setunitdata(.@npcId, UDT_HEADBOTTOM, JeansShorts);
npcsit;
end;
}