// 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; }