summaryrefslogblamecommitdiff
path: root/npc/031-4/gambler.txt
blob: d523f710becabf03331b15b5c0709cfb5d0ac59b (plain) (tree)
1
2
3
4
5
6
7
8
9
10







                                                                               

                       
                            
               
                              
                
                              
                
                              
                














                                     
                















                                                                 


         
                      



                









                                                                                                                                                                     

                                                                   
                                                                              





                                 


                                                                                                                                                                                         

                      



                                                                
                                                           











                                                                                                                                      




                


                                       

                           

                                                         
         



                                     



                                                       
 
        
                               
                               






























                                                                  
                            
     

                
 











                                                         


                                                         

                 










                                                                                                                                 
     
















                                                                   






                                                                         





























































                                                                                                                             

       
                      






                                                 
                                                   






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

}