059D

From GTAMods Wiki
Jump to navigation Jump to search

Vice City San Andreas SHUFFLE_CARD_DECKS


Description
Shuffle card decks
Syntax
059D: shuffle_card_decks [int]
Parameter
[int]
Number of decks (between 0 and 6)

This opcode generates arrays of randomly ordered numbers between 1 and 52, the number of arrays determined by the value of this opcode. The arrays simulate the random order when shuffling a deck of 52 cards. Opcode 059E is used to read the elements of the arrays. A value of 0 clears the deck by filling the arrays with the number 0. The arrays do not reset when loading different game sessions so they carry over. For Vice City, this opcode only exists on the PC v1.0 and v1.1, and was never called in the original script.

Algorithm

The following is the algorithm reverse-engineered from Vice City for generating the arrays.

memset(CardStack, 0, sizeof(CardStack[0]) * 312); // init card stack to 0
short seqarr[312];                                // set up sequential array with numbers from 0 to 311 inclusive
for (short i = 0; i < 312; i++) {
    seqarr[i] = i;
}
if (ScriptParams[0].int32) {                      // check if opcode's argument is non-zero
    int index = ScriptParams[0].int32 * 52;       // start index at end of card stack
    for (short card = 1; card < 53; card++) {     // iterate through all cards
        for (int deck = 0; deck < ScriptParams[0].int32; deck++) { // iterate through all decks
            int rand = rand() % 0x7FFF;           // get random value between 0 and 0x7FFF
            int seqindex = static_cast<int>(index * static_cast<float>(rand & 0xFFFF) / 0x8000); // calculate randomized index
            int seqval = seqarr[seqindex];        // get value from sequential array at randomized index
            CardStack[seqval] = card;             // set card stack at value to card number
            while (seqindex < index) {            // remove value from sequential array by shifting array starting at randomized index
                if (seqindex + 1 < 312) {
                    seqarr[seqindex] = seqarr[seqindex + 1]; // shift elements of sequential array
                } else {
                    seqarr[seqindex] = 0;         // set to 0 if reach end of array
                }
                seqindex++;
            }
            index--;                              // go down the card stack by one
        }
    }
}

Keywords

shuffle, card, deck, decks

Reference