2017-09-08 18:48:55 +02:00
# include "global.h"
# include "lottery_corner.h"
# include "event_data.h"
# include "pokemon.h"
2017-12-05 18:55:48 +01:00
# include "constants/items.h"
2017-12-05 19:27:33 +01:00
# include "random.h"
2017-12-11 19:27:51 +01:00
# include "constants/species.h"
2017-09-08 18:48:55 +02:00
# include "string_util.h"
# include "text.h"
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 ( ) ;
2017-11-11 01:12:18 +01:00
gSpecialVar_Result = lottoNumber ;
2017-09-08 18:48:55 +02:00
}
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 ) ;
2017-11-11 01:12:18 +01:00
u8 numMatchingDigits = GetMatchingDigits ( gSpecialVar_Result , otId ) ;
2017-09-08 18:48:55 +02:00
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 + + )
{
if ( GetBoxMonData ( & gPokemonStoragePtr - > boxes [ i ] [ j ] , MON_DATA_SPECIES ) ! = SPECIES_NONE & &
! GetBoxMonData ( & gPokemonStoragePtr - > boxes [ i ] [ j ] , MON_DATA_IS_EGG ) )
{
u32 otId = GetBoxMonData ( & gPokemonStoragePtr - > boxes [ i ] [ j ] , MON_DATA_OT_ID ) ;
2017-11-11 01:12:18 +01:00
u8 numMatchingDigits = GetMatchingDigits ( gSpecialVar_Result , otId ) ;
2017-09-08 18:48:55 +02:00
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 ( & gPokemonStoragePtr - > 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 ) ;
}