diff options
Diffstat (limited to 'src/field/lottery_corner.c')
-rw-r--r-- | src/field/lottery_corner.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/src/field/lottery_corner.c b/src/field/lottery_corner.c new file mode 100644 index 000000000..c2c25b9ac --- /dev/null +++ b/src/field/lottery_corner.c @@ -0,0 +1,174 @@ +#include "global.h" +#include "lottery_corner.h" +#include "event_data.h" +#include "items.h" +#include "rng.h" +#include "species.h" +#include "string_util.h" +#include "text.h" + +extern u16 gScriptResult; +extern u16 gSpecialVar_0x8004; +extern struct PokemonStorage gPokemonStorage; +extern u16 gSpecialVar_0x8005; +extern u16 gSpecialVar_0x8006; +static EWRAM_DATA u16 sWinNumberDigit = 0; +static EWRAM_DATA u16 sOtIdDigit = 0; + +static const u16 sLotteryPrizes[] = +{ + ITEM_PP_UP, + ITEM_EXP_SHARE, + ITEM_MAX_REVIVE, + ITEM_MASTER_BALL, +}; + +static u8 GetMatchingDigits(u16, u16); + +void ResetLotteryCorner(void) +{ + u16 rand = Random(); + + SetLotteryNumber((Random() << 16) | rand); + VarSet(VAR_POKELOT_PRIZE, 0); +} + +void SetRandomLotteryNumber(u16 i) +{ + u32 var = Random(); + + while (--i != 0xFFFF) + var = var * 1103515245 + 12345; + + SetLotteryNumber(var); +} + +void RetrieveLotteryNumber(void) +{ + u16 lottoNumber = GetLotteryNumber(); + gScriptResult = lottoNumber; +} + +void PickLotteryCornerTicket(void) +{ + u16 i; + u16 j; + u32 box; + u32 slot; + + gSpecialVar_0x8004 = 0; + slot = 0; + box = 0; + for (i = 0; i < 6; i++) + { + struct Pokemon *pkmn = &gPlayerParty[i]; + + // UB: Too few arguments for function GetMonData + if (GetMonData(pkmn, MON_DATA_SPECIES) != SPECIES_NONE) + { + // do not calculate ticket values for eggs. + if (!GetMonData(pkmn, MON_DATA_IS_EGG)) + { + u32 otId = GetMonData(pkmn, MON_DATA_OT_ID); + u8 numMatchingDigits = GetMatchingDigits(gScriptResult, otId); + + if (numMatchingDigits > gSpecialVar_0x8004 && numMatchingDigits > 1) + { + gSpecialVar_0x8004 = numMatchingDigits - 1; + box = 14; + slot = i; + } + } + } + else // pokemon are always arranged from populated spots first to unpopulated, so the moment a NONE species is found, that's the end of the list. + break; + } + + // player has 14 boxes. + for (i = 0; i < 14; i++) + { + // player has 30 slots per box. + for (j = 0; j < 30; j++) + { + struct BoxPokemon *pkmn = &gPokemonStorage.boxes[i][j]; + + // UB: Too few arguments for function GetMonData + if (GetBoxMonData(pkmn, MON_DATA_SPECIES) != SPECIES_NONE && + !GetBoxMonData(pkmn, MON_DATA_IS_EGG)) + { + u32 otId = GetBoxMonData(pkmn, MON_DATA_OT_ID); + u8 numMatchingDigits = GetMatchingDigits(gScriptResult, otId); + + if (numMatchingDigits > gSpecialVar_0x8004 && numMatchingDigits > 1) + { + gSpecialVar_0x8004 = numMatchingDigits - 1; + box = i; + slot = j; + } + } + } + } + + if (gSpecialVar_0x8004 != 0) + { + gSpecialVar_0x8005 = sLotteryPrizes[gSpecialVar_0x8004 - 1]; + + if (box == 14) + { + gSpecialVar_0x8006 = 0; + GetMonData(&gPlayerParty[slot], MON_DATA_NICKNAME, gStringVar1); + } + else + { + gSpecialVar_0x8006 = 1; + GetBoxMonData(&gPokemonStorage.boxes[box][slot], MON_DATA_NICKNAME, gStringVar1); + } + StringGetEnd10(gStringVar1); + } +} + +static u8 GetMatchingDigits(u16 winNumber, u16 otId) +{ + u8 i; + u8 matchingDigits = 0; + + for (i = 0; i < 5; i++) + { + sWinNumberDigit = winNumber % 10; + sOtIdDigit = otId % 10; + + if (sWinNumberDigit == sOtIdDigit) + { + winNumber = winNumber / 10; + otId = otId / 10; + matchingDigits++; + } + else + break; + } + return matchingDigits; +} + +// lottery numbers go from 0 to 99999, not 65535 (0xFFFF). interestingly enough, the function that calls GetLotteryNumber shifts to u16, so it cant be anything above 65535 anyway. +void SetLotteryNumber(u32 lotteryNum) +{ + u16 lowNum = lotteryNum >> 16; + u16 highNum = lotteryNum; + + VarSet(VAR_POKELOT_RND1, highNum); + VarSet(VAR_POKELOT_RND2, lowNum); +} + +u32 GetLotteryNumber(void) +{ + u16 highNum = VarGet(VAR_POKELOT_RND1); + u16 lowNum = VarGet(VAR_POKELOT_RND2); + + return (lowNum << 16) | highNum; +} + +// interestingly, this may have been the original lottery number set function, but GF tried to change it to 32-bit later but didnt finish changing all calls as one GetLotteryNumber still shifts to u16. +void SetLotteryNumber16_Unused(u16 lotteryNum) +{ + SetLotteryNumber(lotteryNum); +} |