Merge remote-tracking branch 'pret/master'
This commit is contained in:
601
src/battle_4.c
Normal file
601
src/battle_4.c
Normal file
@@ -0,0 +1,601 @@
|
||||
#include "global.h"
|
||||
#include "battle.h"
|
||||
#include "battle_move_effects.h"
|
||||
#include "moves.h"
|
||||
#include "abilities.h"
|
||||
#include "item.h"
|
||||
#include "items.h"
|
||||
#include "hold_effects.h"
|
||||
|
||||
void atk00_attackcanceler(void);
|
||||
void atk01_accuracycheck(void);
|
||||
void atk02_attackstring(void);
|
||||
void atk03_ppreduce(void);
|
||||
void atk04_critcalc(void);
|
||||
void atk05_damagecalc1(void);
|
||||
void atk06_typecalc(void);
|
||||
void atk07_dmg_adjustment(void);
|
||||
void atk08_dmg_adjustment2(void);
|
||||
void atk09_attackanimation(void);
|
||||
void atk0A_waitanimation(void);
|
||||
void atk0B_healthbarupdate(void);
|
||||
void atk0C_datahpupdate(void);
|
||||
void atk0D_critmessage(void);
|
||||
void atk0E_effectiveness_sound(void);
|
||||
void atk0F_resultmessage(void);
|
||||
void atk10_printstring(void);
|
||||
void atk11_printstring_playeronly(void);
|
||||
void atk12_waitmessage(void);
|
||||
void atk13_printfromtable(void);
|
||||
void atk14_printfromtable_playeronly(void);
|
||||
void atk15_seteffectwithchancetarget(void);
|
||||
void atk16_seteffectprimary(void);
|
||||
void atk17_seteffectsecondary(void);
|
||||
void atk18_status_effect_clear(void);
|
||||
void atk19_faint_pokemon(void);
|
||||
void atk1A_faint_animation(void);
|
||||
void atk1B_faint_effects_clear(void);
|
||||
void atk1C_jumpifstatus(void);
|
||||
void atk1D_jumpifstatus2(void);
|
||||
void atk1E_jumpifability(void);
|
||||
void atk1F_jumpifsideaffecting(void);
|
||||
void atk20_jumpifstat(void);
|
||||
void atk21_jumpifstatus3(void);
|
||||
void atk22_jumpiftype(void);
|
||||
void atk23_getexp(void);
|
||||
void atk24(void);
|
||||
void atk25_move_values_cleanup(void);
|
||||
void atk26_set_multihit(void);
|
||||
void atk27_decrement_multihit(void);
|
||||
void atk28_goto(void);
|
||||
void atk29_jumpifbyte(void);
|
||||
void atk2A_jumpifhalfword(void);
|
||||
void atk2B_jumpifword(void);
|
||||
void atk2C_jumpifarrayequal(void);
|
||||
void atk2D_jumpifarraynotequal(void);
|
||||
void atk2E_setbyte(void);
|
||||
void atk2F_addbyte(void);
|
||||
void atk30_subbyte(void);
|
||||
void atk31_copyarray(void);
|
||||
void atk32_copyarray_withindex(void);
|
||||
void atk33_orbyte(void);
|
||||
void atk34_orhalfword(void);
|
||||
void atk35_orword(void);
|
||||
void atk36_bicbyte(void);
|
||||
void atk37_bichalfword(void);
|
||||
void atk38_bicword(void);
|
||||
void atk39_pause(void);
|
||||
void atk3A_waitstate(void);
|
||||
void atk3B_healthbar_update(void);
|
||||
void atk3C_return(void);
|
||||
void atk3D_end(void);
|
||||
void atk3E_end2(void);
|
||||
void atk3F_end3(void);
|
||||
void atk40_jump_if_move_affected_by_protect(void);
|
||||
void atk41_call(void);
|
||||
void atk42_jumpiftype2(void);
|
||||
void atk43_jumpifabilitypresent(void);
|
||||
void atk44(void);
|
||||
void atk45_playanimation(void);
|
||||
void atk46_playanimation2(void);
|
||||
void atk47_setgraphicalstatchangevalues(void);
|
||||
void atk48_playstatchangeanimation(void);
|
||||
void atk49_moveendturn(void);
|
||||
void atk4A_typecalc2(void);
|
||||
void atk4B_return_atk_to_ball(void);
|
||||
void atk4C_copy_poke_data(void);
|
||||
void atk4D_switch_data_update(void);
|
||||
void atk4E_switchin_anim(void);
|
||||
void atk4F_jump_if_cannot_switch(void);
|
||||
void atk50_openpartyscreen(void);
|
||||
void atk51_switch_handle_order(void);
|
||||
void atk52_switch_in_effects(void);
|
||||
void atk53_trainer_slide(void);
|
||||
void atk54_effectiveness_sound(void);
|
||||
void atk55_play_sound(void);
|
||||
void atk56_fainting_cry(void);
|
||||
void atk57(void);
|
||||
void atk58_return_to_ball(void);
|
||||
void atk59_learnmove_inbattle(void);
|
||||
void atk5A(void);
|
||||
void atk5B_80256E0(void);
|
||||
void atk5C_hitanimation(void);
|
||||
void atk5D_getmoneyreward(void);
|
||||
void atk5E_8025A70(void);
|
||||
void atk5F_8025B24(void);
|
||||
void atk60_increment_gamestat(void);
|
||||
void atk61_8025BA4(void);
|
||||
void atk62_08025C6C(void);
|
||||
void atk63_jumptorandomattack(void);
|
||||
void atk64_statusanimation(void);
|
||||
void atk65_status2animation(void);
|
||||
void atk66_chosenstatusanimation(void);
|
||||
void atk67_8025ECC(void);
|
||||
void atk68_80246A0(void);
|
||||
void atk69_dmg_adjustment2(void);
|
||||
void atk6A_removeitem(void);
|
||||
void atk6B_atknameinbuff1(void);
|
||||
void atk6C_lvlbox_display(void);
|
||||
void atk6D_set_sentpokes_values(void);
|
||||
void atk6E_set_atk_to_player0(void);
|
||||
void atk6F_set_visible(void);
|
||||
void atk70_record_ability(void);
|
||||
void atk71_buffer_move_to_learn(void);
|
||||
void atk72_jump_if_can_run_frombattle(void);
|
||||
void atk73_hp_thresholds(void);
|
||||
void atk74_hp_thresholds2(void);
|
||||
void atk75_8026A58(void);
|
||||
void atk76_various(void);
|
||||
void atk77_setprotect(void);
|
||||
void atk78_faintifabilitynotdamp(void);
|
||||
void atk79_setatkhptozero(void);
|
||||
void atk7A_jumpwhiletargetvalid(void);
|
||||
void atk7B_healhalfHP_if_possible(void);
|
||||
void atk7C_8025508(void);
|
||||
void atk7D_set_rain(void);
|
||||
void atk7E_setreflect(void);
|
||||
void atk7F_setseeded(void);
|
||||
void atk80_manipulatedamage(void);
|
||||
void atk81_setrest(void);
|
||||
void atk82_jumpifnotfirstturn(void);
|
||||
void atk83_nop(void);
|
||||
void atk84_jump_if_cant_sleep(void);
|
||||
void atk85_stockpile(void);
|
||||
void atk86_stockpiletobasedamage(void);
|
||||
void atk87_stockpiletohpheal(void);
|
||||
void atk88_negativedamage(void);
|
||||
void atk89_statbuffchange(void);
|
||||
void atk8A_normalisebuffs(void);
|
||||
void atk8B_setbide(void);
|
||||
void atk8C_confuseifrepeatingattackends(void);
|
||||
void atk8D_setmultihit_counter(void);
|
||||
void atk8E_prepare_multihit(void);
|
||||
void atk8F_forcerandomswitch(void);
|
||||
void atk90_conversion_type_change(void);
|
||||
void atk91_givepaydaymoney(void);
|
||||
void atk92_setlightscreen(void);
|
||||
void atk93_ko_move(void);
|
||||
void atk94_gethalfcurrentenemyhp(void);
|
||||
void atk95_setsandstorm(void);
|
||||
void atk96_weatherdamage(void);
|
||||
void atk97_try_infatuation(void);
|
||||
void atk98_status_icon_update(void);
|
||||
void atk99_setmist(void);
|
||||
void atk9A_set_focusenergy(void);
|
||||
void atk9B_transformdataexecution(void);
|
||||
void atk9C_set_substitute(void);
|
||||
void atk9D_copyattack(void);
|
||||
void atk9E_metronome(void);
|
||||
void atk9F_dmgtolevel(void);
|
||||
void atkA0_psywavedamageeffect(void);
|
||||
void atkA1_counterdamagecalculator(void);
|
||||
void atkA2_mirrorcoatdamagecalculator(void);
|
||||
void atkA3_disablelastusedattack(void);
|
||||
void atkA4_setencore(void);
|
||||
void atkA5_painsplitdmgcalc(void);
|
||||
void atkA6_settypetorandomresistance(void);
|
||||
void atkA7_setalwayshitflag(void);
|
||||
void atkA8_copymovepermanently(void);
|
||||
void atkA9_sleeptalk_choose_move(void);
|
||||
void atkAA_set_destinybond(void);
|
||||
void atkAB_DestinyBondFlagUpdate(void);
|
||||
void atkAC_remaininghptopower(void);
|
||||
void atkAD_spite_ppreduce(void);
|
||||
void atkAE_heal_party_status(void);
|
||||
void atkAF_cursetarget(void);
|
||||
void atkB0_set_spikes(void);
|
||||
void atkB1_set_foresight(void);
|
||||
void atkB2_setperishsong(void);
|
||||
void atkB3_rolloutdamagecalculation(void);
|
||||
void atkB4_jumpifconfusedandstatmaxed(void);
|
||||
void atkB5_furycuttercalc(void);
|
||||
void atkB6_happinesstodamagecalculation(void);
|
||||
void atkB7_presentdamagecalculation(void);
|
||||
void atkB8_set_safeguard(void);
|
||||
void atkB9_magnitudedamagecalculation(void);
|
||||
void atkBA_jumpifnopursuitswitchdmg(void);
|
||||
void atkBB_setsunny(void);
|
||||
void atkBC_maxattackhalvehp(void);
|
||||
void atkBD_copyfoestats(void);
|
||||
void atkBE_breakfree(void);
|
||||
void atkBF_set_defense_curl(void);
|
||||
void atkC0_recoverbasedonsunlight(void);
|
||||
void atkC1_hidden_power(void);
|
||||
void atkC2_selectnexttarget(void);
|
||||
void atkC3_setfutureattack(void);
|
||||
void atkC4_beat_up(void);
|
||||
void atkC5_hidepreattack(void);
|
||||
void atkC6_unhidepostattack(void);
|
||||
void atkC7_setminimize(void);
|
||||
void atkC8_sethail(void);
|
||||
void atkC9_jumpifattackandspecialattackcannotfall(void);
|
||||
void atkCA_setforcedtarget(void);
|
||||
void atkCB_setcharge(void);
|
||||
void atkCC_callterrainattack(void);
|
||||
void atkCD_cureifburnedparalysedorpoisoned(void);
|
||||
void atkCE_settorment(void);
|
||||
void atkCF_jumpifnodamage(void);
|
||||
void atkD0_settaunt(void);
|
||||
void atkD1_set_helpinghand(void);
|
||||
void atkD2_swap_items(void);
|
||||
void atkD3_copy_ability(void);
|
||||
void atkD4_wish_effect(void);
|
||||
void atkD5_setroots(void);
|
||||
void atkD6_doubledamagedealtifdamaged(void);
|
||||
void atkD7_setyawn(void);
|
||||
void atkD8_setdamagetohealthdifference(void);
|
||||
void atkD9_scaledamagebyhealthratio(void);
|
||||
void atkDA_abilityswap(void);
|
||||
void atkDB_imprisoneffect(void);
|
||||
void atkDC_setgrudge(void);
|
||||
void atkDD_weightdamagecalculation(void);
|
||||
void atkDE_asistattackselect(void);
|
||||
void atkDF_setmagiccoat(void);
|
||||
void atkE0_setstealstatchange(void);
|
||||
void atkE1_intimidate_string_loader(void);
|
||||
void atkE2_switchout_abilities(void);
|
||||
void atkE3_jumpiffainted(void);
|
||||
void atkE4_getsecretpowereffect(void);
|
||||
void atkE5_pickup(void);
|
||||
void atkE6_castform_change_animation(void);
|
||||
void atkE7_castform_data_change(void);
|
||||
void atkE8_settypebasedhalvers(void);
|
||||
void atkE9_setweatherballtype(void);
|
||||
void atkEA_recycleitem(void);
|
||||
void atkEB_settypetoterrain(void);
|
||||
void atkEC_pursuit_sth(void);
|
||||
void atkED_802B4B4(void);
|
||||
void atkEE_removelightscreenreflect(void);
|
||||
void atkEF_pokeball_catch_calculation(void);
|
||||
void atkF0_copy_caught_poke(void);
|
||||
void atkF1_setpoke_as_caught(void);
|
||||
void atkF2_display_dex_info(void);
|
||||
void atkF3_nickname_caught_poke(void);
|
||||
void atkF4_802BEF0(void);
|
||||
void atkF5_removeattackerstatus1(void);
|
||||
void atkF6_802BF48(void);
|
||||
void atkF7_802BF54(void);
|
||||
void sub_8056EF8(void);
|
||||
|
||||
void (* const gBattleScriptingCommandsTable[])(void) =
|
||||
{
|
||||
atk00_attackcanceler,
|
||||
atk01_accuracycheck,
|
||||
atk02_attackstring,
|
||||
atk03_ppreduce,
|
||||
atk04_critcalc,
|
||||
atk05_damagecalc1,
|
||||
atk06_typecalc,
|
||||
atk07_dmg_adjustment,
|
||||
atk08_dmg_adjustment2,
|
||||
atk09_attackanimation,
|
||||
atk0A_waitanimation,
|
||||
atk0B_healthbarupdate,
|
||||
atk0C_datahpupdate,
|
||||
atk0D_critmessage,
|
||||
atk0E_effectiveness_sound,
|
||||
atk0F_resultmessage,
|
||||
atk10_printstring,
|
||||
atk11_printstring_playeronly,
|
||||
atk12_waitmessage,
|
||||
atk13_printfromtable,
|
||||
atk14_printfromtable_playeronly,
|
||||
atk15_seteffectwithchancetarget,
|
||||
atk16_seteffectprimary,
|
||||
atk17_seteffectsecondary,
|
||||
atk18_status_effect_clear,
|
||||
atk19_faint_pokemon,
|
||||
atk1A_faint_animation,
|
||||
atk1B_faint_effects_clear,
|
||||
atk1C_jumpifstatus,
|
||||
atk1D_jumpifstatus2,
|
||||
atk1E_jumpifability,
|
||||
atk1F_jumpifsideaffecting,
|
||||
atk20_jumpifstat,
|
||||
atk21_jumpifstatus3,
|
||||
atk22_jumpiftype,
|
||||
atk23_getexp,
|
||||
atk24,
|
||||
atk25_move_values_cleanup,
|
||||
atk26_set_multihit,
|
||||
atk27_decrement_multihit,
|
||||
atk28_goto,
|
||||
atk29_jumpifbyte,
|
||||
atk2A_jumpifhalfword,
|
||||
atk2B_jumpifword,
|
||||
atk2C_jumpifarrayequal,
|
||||
atk2D_jumpifarraynotequal,
|
||||
atk2E_setbyte,
|
||||
atk2F_addbyte,
|
||||
atk30_subbyte,
|
||||
atk31_copyarray,
|
||||
atk32_copyarray_withindex,
|
||||
atk33_orbyte,
|
||||
atk34_orhalfword,
|
||||
atk35_orword,
|
||||
atk36_bicbyte,
|
||||
atk37_bichalfword,
|
||||
atk38_bicword,
|
||||
atk39_pause,
|
||||
atk3A_waitstate,
|
||||
atk3B_healthbar_update,
|
||||
atk3C_return,
|
||||
atk3D_end,
|
||||
atk3E_end2,
|
||||
atk3F_end3,
|
||||
atk40_jump_if_move_affected_by_protect,
|
||||
atk41_call,
|
||||
atk42_jumpiftype2,
|
||||
atk43_jumpifabilitypresent,
|
||||
atk44,
|
||||
atk45_playanimation,
|
||||
atk46_playanimation2,
|
||||
atk47_setgraphicalstatchangevalues,
|
||||
atk48_playstatchangeanimation,
|
||||
atk49_moveendturn,
|
||||
atk4A_typecalc2,
|
||||
atk4B_return_atk_to_ball,
|
||||
atk4C_copy_poke_data,
|
||||
atk4D_switch_data_update,
|
||||
atk4E_switchin_anim,
|
||||
atk4F_jump_if_cannot_switch,
|
||||
atk50_openpartyscreen,
|
||||
atk51_switch_handle_order,
|
||||
atk52_switch_in_effects,
|
||||
atk53_trainer_slide,
|
||||
atk54_effectiveness_sound,
|
||||
atk55_play_sound,
|
||||
atk56_fainting_cry,
|
||||
atk57,
|
||||
atk58_return_to_ball,
|
||||
atk59_learnmove_inbattle,
|
||||
atk5A,
|
||||
atk5B_80256E0,
|
||||
atk5C_hitanimation,
|
||||
atk5D_getmoneyreward,
|
||||
atk5E_8025A70,
|
||||
atk5F_8025B24,
|
||||
atk60_increment_gamestat,
|
||||
atk61_8025BA4,
|
||||
atk62_08025C6C,
|
||||
atk63_jumptorandomattack,
|
||||
atk64_statusanimation,
|
||||
atk65_status2animation,
|
||||
atk66_chosenstatusanimation,
|
||||
atk67_8025ECC,
|
||||
atk68_80246A0,
|
||||
atk69_dmg_adjustment2,
|
||||
atk6A_removeitem,
|
||||
atk6B_atknameinbuff1,
|
||||
atk6C_lvlbox_display,
|
||||
atk6D_set_sentpokes_values,
|
||||
atk6E_set_atk_to_player0,
|
||||
atk6F_set_visible,
|
||||
atk70_record_ability,
|
||||
atk71_buffer_move_to_learn,
|
||||
atk72_jump_if_can_run_frombattle,
|
||||
atk73_hp_thresholds,
|
||||
atk74_hp_thresholds2,
|
||||
atk75_8026A58,
|
||||
atk76_various,
|
||||
atk77_setprotect,
|
||||
atk78_faintifabilitynotdamp,
|
||||
atk79_setatkhptozero,
|
||||
atk7A_jumpwhiletargetvalid,
|
||||
atk7B_healhalfHP_if_possible,
|
||||
atk7C_8025508,
|
||||
atk7D_set_rain,
|
||||
atk7E_setreflect,
|
||||
atk7F_setseeded,
|
||||
atk80_manipulatedamage,
|
||||
atk81_setrest,
|
||||
atk82_jumpifnotfirstturn,
|
||||
atk83_nop,
|
||||
atk84_jump_if_cant_sleep,
|
||||
atk85_stockpile,
|
||||
atk86_stockpiletobasedamage,
|
||||
atk87_stockpiletohpheal,
|
||||
atk88_negativedamage,
|
||||
atk89_statbuffchange,
|
||||
atk8A_normalisebuffs,
|
||||
atk8B_setbide,
|
||||
atk8C_confuseifrepeatingattackends,
|
||||
atk8D_setmultihit_counter,
|
||||
atk8E_prepare_multihit,
|
||||
atk8F_forcerandomswitch,
|
||||
atk90_conversion_type_change,
|
||||
atk91_givepaydaymoney,
|
||||
atk92_setlightscreen,
|
||||
atk93_ko_move,
|
||||
atk94_gethalfcurrentenemyhp,
|
||||
atk95_setsandstorm,
|
||||
atk96_weatherdamage,
|
||||
atk97_try_infatuation,
|
||||
atk98_status_icon_update,
|
||||
atk99_setmist,
|
||||
atk9A_set_focusenergy,
|
||||
atk9B_transformdataexecution,
|
||||
atk9C_set_substitute,
|
||||
atk9D_copyattack,
|
||||
atk9E_metronome,
|
||||
atk9F_dmgtolevel,
|
||||
atkA0_psywavedamageeffect,
|
||||
atkA1_counterdamagecalculator,
|
||||
atkA2_mirrorcoatdamagecalculator,
|
||||
atkA3_disablelastusedattack,
|
||||
atkA4_setencore,
|
||||
atkA5_painsplitdmgcalc,
|
||||
atkA6_settypetorandomresistance,
|
||||
atkA7_setalwayshitflag,
|
||||
atkA8_copymovepermanently,
|
||||
atkA9_sleeptalk_choose_move,
|
||||
atkAA_set_destinybond,
|
||||
atkAB_DestinyBondFlagUpdate,
|
||||
atkAC_remaininghptopower,
|
||||
atkAD_spite_ppreduce,
|
||||
atkAE_heal_party_status,
|
||||
atkAF_cursetarget,
|
||||
atkB0_set_spikes,
|
||||
atkB1_set_foresight,
|
||||
atkB2_setperishsong,
|
||||
atkB3_rolloutdamagecalculation,
|
||||
atkB4_jumpifconfusedandstatmaxed,
|
||||
atkB5_furycuttercalc,
|
||||
atkB6_happinesstodamagecalculation,
|
||||
atkB7_presentdamagecalculation,
|
||||
atkB8_set_safeguard,
|
||||
atkB9_magnitudedamagecalculation,
|
||||
atkBA_jumpifnopursuitswitchdmg,
|
||||
atkBB_setsunny,
|
||||
atkBC_maxattackhalvehp,
|
||||
atkBD_copyfoestats,
|
||||
atkBE_breakfree,
|
||||
atkBF_set_defense_curl,
|
||||
atkC0_recoverbasedonsunlight,
|
||||
atkC1_hidden_power,
|
||||
atkC2_selectnexttarget,
|
||||
atkC3_setfutureattack,
|
||||
atkC4_beat_up,
|
||||
atkC5_hidepreattack,
|
||||
atkC6_unhidepostattack,
|
||||
atkC7_setminimize,
|
||||
atkC8_sethail,
|
||||
atkC9_jumpifattackandspecialattackcannotfall,
|
||||
atkCA_setforcedtarget,
|
||||
atkCB_setcharge,
|
||||
atkCC_callterrainattack,
|
||||
atkCD_cureifburnedparalysedorpoisoned,
|
||||
atkCE_settorment,
|
||||
atkCF_jumpifnodamage,
|
||||
atkD0_settaunt,
|
||||
atkD1_set_helpinghand,
|
||||
atkD2_swap_items,
|
||||
atkD3_copy_ability,
|
||||
atkD4_wish_effect,
|
||||
atkD5_setroots,
|
||||
atkD6_doubledamagedealtifdamaged,
|
||||
atkD7_setyawn,
|
||||
atkD8_setdamagetohealthdifference,
|
||||
atkD9_scaledamagebyhealthratio,
|
||||
atkDA_abilityswap,
|
||||
atkDB_imprisoneffect,
|
||||
atkDC_setgrudge,
|
||||
atkDD_weightdamagecalculation,
|
||||
atkDE_asistattackselect,
|
||||
atkDF_setmagiccoat,
|
||||
atkE0_setstealstatchange,
|
||||
atkE1_intimidate_string_loader,
|
||||
atkE2_switchout_abilities,
|
||||
atkE3_jumpiffainted,
|
||||
atkE4_getsecretpowereffect,
|
||||
atkE5_pickup,
|
||||
atkE6_castform_change_animation,
|
||||
atkE7_castform_data_change,
|
||||
atkE8_settypebasedhalvers,
|
||||
atkE9_setweatherballtype,
|
||||
atkEA_recycleitem,
|
||||
atkEB_settypetoterrain,
|
||||
atkEC_pursuit_sth,
|
||||
atkED_802B4B4,
|
||||
atkEE_removelightscreenreflect,
|
||||
atkEF_pokeball_catch_calculation,
|
||||
atkF0_copy_caught_poke,
|
||||
atkF1_setpoke_as_caught,
|
||||
atkF2_display_dex_info,
|
||||
atkF3_nickname_caught_poke,
|
||||
atkF4_802BEF0,
|
||||
atkF5_removeattackerstatus1,
|
||||
atkF6_802BF48,
|
||||
atkF7_802BF54,
|
||||
sub_8056EF8
|
||||
};
|
||||
|
||||
struct statFractions
|
||||
{
|
||||
u8 dividend;
|
||||
u8 divisor;
|
||||
};
|
||||
|
||||
const struct statFractions gAccuracyStageRatios[] =
|
||||
{
|
||||
{ 33, 100}, // -6
|
||||
{ 36, 100}, // -5
|
||||
{ 43, 100}, // -4
|
||||
{ 50, 100}, // -3
|
||||
{ 60, 100}, // -2
|
||||
{ 75, 100}, // -1
|
||||
{ 1, 1}, // 0
|
||||
{133, 100}, // +1
|
||||
{166, 100}, // +2
|
||||
{ 2, 1}, // +3
|
||||
{233, 100}, // +4
|
||||
{133, 50}, // +5
|
||||
{ 3, 1}, // +6
|
||||
};
|
||||
|
||||
// The chance is 1/N for each stage.
|
||||
const u16 gCriticalHitChance[] = {16, 8, 4, 3, 2};
|
||||
|
||||
const u32 gStatusFlagsForMoveEffects[] =
|
||||
{
|
||||
0x00000000,
|
||||
0x00000007,
|
||||
0x00000008,
|
||||
0x00000010,
|
||||
0x00000020,
|
||||
0x00000040,
|
||||
0x00000080,
|
||||
0x00000007,
|
||||
0x00000008,
|
||||
0x00000000,
|
||||
0x00000070,
|
||||
0x00000000,
|
||||
0x00001000,
|
||||
0x0000E000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00400000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x04000000,
|
||||
0x08000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000C00,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000,
|
||||
0x00000000
|
||||
};
|
||||
1507
src/battle_ai.c
1507
src/battle_ai.c
File diff suppressed because it is too large
Load Diff
284
src/calculate_base_damage.c
Normal file
284
src/calculate_base_damage.c
Normal file
@@ -0,0 +1,284 @@
|
||||
#include "global.h"
|
||||
#include "abilities.h"
|
||||
#include "battle.h"
|
||||
#include "hold_effects.h"
|
||||
#include "event_data.h"
|
||||
#include "item.h"
|
||||
#include "items.h"
|
||||
#include "pokemon.h"
|
||||
#include "species.h"
|
||||
#include "moves.h"
|
||||
#include "battle_move_effects.h"
|
||||
|
||||
extern u32 gBattleTypeFlags;
|
||||
extern struct BattlePokemon gBattleMons[4];
|
||||
extern u16 gCurrentMove;
|
||||
extern u8 gCritMultiplier;
|
||||
extern u16 gBattleWeather;
|
||||
extern struct BattleEnigmaBerry gEnigmaBerries[];
|
||||
extern u16 gBattleMovePower;
|
||||
extern u16 gTrainerBattleOpponent_A;
|
||||
|
||||
u8 CountAliveMonsInBattle(u8);
|
||||
bool8 ShouldGetStatBadgeBoost(u16 flagId, u8 bank);
|
||||
|
||||
extern const struct BattleMove gBattleMoves[];
|
||||
extern const u8 gHoldEffectToType[][2];
|
||||
extern const u8 gStatStageRatios[][2];
|
||||
|
||||
#define APPLY_STAT_MOD(var, mon, stat, statIndex) \
|
||||
{ \
|
||||
(var) = (stat) * (gStatStageRatios)[(mon)->statStages[(statIndex)]][0]; \
|
||||
(var) /= (gStatStageRatios)[(mon)->statStages[(statIndex)]][1]; \
|
||||
}
|
||||
|
||||
s32 CalculateBaseDamage(struct BattlePokemon *attacker, struct BattlePokemon *defender, u32 move, u16 sideStatus, u16 powerOverride, u8 typeOverride, u8 bankAtk, u8 bankDef)
|
||||
{
|
||||
u32 i;
|
||||
s32 damage = 0;
|
||||
s32 damageHelper;
|
||||
u8 type;
|
||||
u16 attack, defense;
|
||||
u16 spAttack, spDefense;
|
||||
u8 defenderHoldEffect;
|
||||
u8 defenderHoldEffectParam;
|
||||
u8 attackerHoldEffect;
|
||||
u8 attackerHoldEffectParam;
|
||||
|
||||
if (!powerOverride)
|
||||
gBattleMovePower = gBattleMoves[move].power;
|
||||
else
|
||||
gBattleMovePower = powerOverride;
|
||||
|
||||
if (!typeOverride)
|
||||
type = gBattleMoves[move].type;
|
||||
else
|
||||
type = typeOverride & 0x3F;
|
||||
|
||||
attack = attacker->attack;
|
||||
defense = defender->defense;
|
||||
spAttack = attacker->spAttack;
|
||||
spDefense = defender->spDefense;
|
||||
|
||||
if (attacker->item == ITEM_ENIGMA_BERRY)
|
||||
{
|
||||
attackerHoldEffect = gEnigmaBerries[bankAtk].holdEffect;
|
||||
attackerHoldEffectParam = gEnigmaBerries[bankAtk].holdEffectParam;
|
||||
}
|
||||
else
|
||||
{
|
||||
attackerHoldEffect = ItemId_GetHoldEffect(attacker->item);
|
||||
attackerHoldEffectParam = ItemId_GetHoldEffectParam(attacker->item);
|
||||
}
|
||||
|
||||
if (defender->item == ITEM_ENIGMA_BERRY)
|
||||
{
|
||||
defenderHoldEffect = gEnigmaBerries[bankDef].holdEffect;
|
||||
defenderHoldEffectParam = gEnigmaBerries[bankDef].holdEffectParam;
|
||||
}
|
||||
else
|
||||
{
|
||||
defenderHoldEffect = ItemId_GetHoldEffect(defender->item);
|
||||
defenderHoldEffectParam = ItemId_GetHoldEffectParam(defender->item);
|
||||
}
|
||||
|
||||
if (attacker->ability == ABILITY_HUGE_POWER || attacker->ability == ABILITY_PURE_POWER)
|
||||
attack *= 2;
|
||||
|
||||
if (ShouldGetStatBadgeBoost(BADGE01_GET, bankAtk))
|
||||
attack = (110 * attack) / 100;
|
||||
if (ShouldGetStatBadgeBoost(BADGE05_GET, bankDef))
|
||||
defense = (110 * defense) / 100;
|
||||
if (ShouldGetStatBadgeBoost(BADGE07_GET, bankAtk))
|
||||
spAttack = (110 * spAttack) / 100;
|
||||
if (ShouldGetStatBadgeBoost(BADGE07_GET, bankDef))
|
||||
spDefense = (110 * spDefense) / 100;
|
||||
|
||||
for (i = 0; i < 17; i++)
|
||||
{
|
||||
if (attackerHoldEffect == gHoldEffectToType[i][0]
|
||||
&& type == gHoldEffectToType[i][1])
|
||||
{
|
||||
if (type <= 8)
|
||||
attack = (attack * (attackerHoldEffectParam + 100)) / 100;
|
||||
else
|
||||
spAttack = (spAttack * (attackerHoldEffectParam + 100)) / 100;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (attackerHoldEffect == HOLD_EFFECT_CHOICE_BAND)
|
||||
attack = (150 * attack) / 100;
|
||||
if (attackerHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) && (attacker->species == SPECIES_LATIAS || attacker->species == SPECIES_LATIOS))
|
||||
spAttack = (150 * spAttack) / 100;
|
||||
if (defenderHoldEffect == HOLD_EFFECT_SOUL_DEW && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER)) && (defender->species == SPECIES_LATIAS || defender->species == SPECIES_LATIOS))
|
||||
spDefense = (150 * spDefense) / 100;
|
||||
if (attackerHoldEffect == HOLD_EFFECT_DEEP_SEA_TOOTH && attacker->species == SPECIES_CLAMPERL)
|
||||
spAttack *= 2;
|
||||
if (defenderHoldEffect == HOLD_EFFECT_DEEP_SEA_SCALE && defender->species == SPECIES_CLAMPERL)
|
||||
spDefense *= 2;
|
||||
if (attackerHoldEffect == HOLD_EFFECT_LIGHT_BALL && attacker->species == SPECIES_PIKACHU)
|
||||
spAttack *= 2;
|
||||
if (defenderHoldEffect == HOLD_EFFECT_METAL_POWDER && defender->species == SPECIES_DITTO)
|
||||
defense *= 2;
|
||||
if (attackerHoldEffect == HOLD_EFFECT_THICK_CLUB && (attacker->species == SPECIES_CUBONE || attacker->species == SPECIES_MAROWAK))
|
||||
attack *= 2;
|
||||
if (defender->ability == ABILITY_THICK_FAT && (type == TYPE_FIRE || type == TYPE_ICE))
|
||||
spAttack /= 2;
|
||||
if (attacker->ability == ABILITY_HUSTLE)
|
||||
attack = (150 * attack) / 100;
|
||||
if (attacker->ability == ABILITY_PLUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MINUS, 0, 0))
|
||||
spAttack = (150 * spAttack) / 100;
|
||||
if (attacker->ability == ABILITY_MINUS && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_PLUS, 0, 0))
|
||||
spAttack = (150 * spAttack) / 100;
|
||||
if (attacker->ability == ABILITY_GUTS && attacker->status1)
|
||||
attack = (150 * attack) / 100;
|
||||
if (defender->ability == ABILITY_MARVEL_SCALE && defender->status1)
|
||||
defense = (150 * defense) / 100;
|
||||
if (type == TYPE_ELECTRIC && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFD, 0))
|
||||
gBattleMovePower /= 2;
|
||||
if (type == TYPE_FIRE && AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, 0, 0xFE, 0))
|
||||
gBattleMovePower /= 2;
|
||||
if (type == TYPE_GRASS && attacker->ability == ABILITY_OVERGROW && attacker->hp <= (attacker->maxHP / 3))
|
||||
gBattleMovePower = (150 * gBattleMovePower) / 100;
|
||||
if (type == TYPE_FIRE && attacker->ability == ABILITY_BLAZE && attacker->hp <= (attacker->maxHP / 3))
|
||||
gBattleMovePower = (150 * gBattleMovePower) / 100;
|
||||
if (type == TYPE_WATER && attacker->ability == ABILITY_TORRENT && attacker->hp <= (attacker->maxHP / 3))
|
||||
gBattleMovePower = (150 * gBattleMovePower) / 100;
|
||||
if (type == TYPE_BUG && attacker->ability == ABILITY_SWARM && attacker->hp <= (attacker->maxHP / 3))
|
||||
gBattleMovePower = (150 * gBattleMovePower) / 100;
|
||||
if (gBattleMoves[gCurrentMove].effect == EFFECT_EXPLOSION)
|
||||
defense /= 2;
|
||||
|
||||
if (type < TYPE_MYSTERY) // is physical
|
||||
{
|
||||
if (gCritMultiplier == 2)
|
||||
{
|
||||
if (attacker->statStages[STAT_STAGE_ATK] > 6)
|
||||
APPLY_STAT_MOD(damage, attacker, attack, STAT_STAGE_ATK)
|
||||
else
|
||||
damage = attack;
|
||||
}
|
||||
else
|
||||
APPLY_STAT_MOD(damage, attacker, attack, STAT_STAGE_ATK)
|
||||
|
||||
damage = damage * gBattleMovePower;
|
||||
damage *= (2 * attacker->level / 5 + 2);
|
||||
|
||||
if (gCritMultiplier == 2)
|
||||
{
|
||||
if (defender->statStages[STAT_STAGE_DEF] < 6)
|
||||
APPLY_STAT_MOD(damageHelper, defender, defense, STAT_STAGE_DEF)
|
||||
else
|
||||
damageHelper = defense;
|
||||
}
|
||||
else
|
||||
APPLY_STAT_MOD(damageHelper, defender, defense, STAT_STAGE_DEF)
|
||||
|
||||
damage = damage / damageHelper;
|
||||
damage /= 50;
|
||||
|
||||
if ((attacker->status1 & STATUS_BURN) && attacker->ability != ABILITY_GUTS)
|
||||
damage /= 2;
|
||||
|
||||
if ((sideStatus & SIDE_STATUS_REFLECT) && gCritMultiplier == 1)
|
||||
{
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(2) == 2)
|
||||
damage = 2 * (damage / 3);
|
||||
else
|
||||
damage /= 2;
|
||||
}
|
||||
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(2) == 2)
|
||||
damage /= 2;
|
||||
|
||||
// moves always do at least 1 damage.
|
||||
if (damage == 0)
|
||||
damage = 1;
|
||||
}
|
||||
|
||||
if (type == TYPE_MYSTERY)
|
||||
damage = 0; // is ??? type. does 0 damage.
|
||||
|
||||
if (type > TYPE_MYSTERY) // is special?
|
||||
{
|
||||
if (gCritMultiplier == 2)
|
||||
{
|
||||
if (attacker->statStages[STAT_STAGE_SPATK] > 6)
|
||||
APPLY_STAT_MOD(damage, attacker, spAttack, STAT_STAGE_SPATK)
|
||||
else
|
||||
damage = spAttack;
|
||||
}
|
||||
else
|
||||
APPLY_STAT_MOD(damage, attacker, spAttack, STAT_STAGE_SPATK)
|
||||
|
||||
damage = damage * gBattleMovePower;
|
||||
damage *= (2 * attacker->level / 5 + 2);
|
||||
|
||||
if (gCritMultiplier == 2)
|
||||
{
|
||||
if (defender->statStages[STAT_STAGE_SPDEF] < 6)
|
||||
APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_STAGE_SPDEF)
|
||||
else
|
||||
damageHelper = spDefense;
|
||||
}
|
||||
else
|
||||
APPLY_STAT_MOD(damageHelper, defender, spDefense, STAT_STAGE_SPDEF)
|
||||
|
||||
damage = (damage / damageHelper);
|
||||
damage /= 50;
|
||||
|
||||
if ((sideStatus & SIDE_STATUS_LIGHTSCREEN) && gCritMultiplier == 1)
|
||||
{
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && CountAliveMonsInBattle(2) == 2)
|
||||
damage = 2 * (damage / 3);
|
||||
else
|
||||
damage /= 2;
|
||||
}
|
||||
|
||||
if ((gBattleTypeFlags & BATTLE_TYPE_DOUBLE) && gBattleMoves[move].target == 8 && CountAliveMonsInBattle(2) == 2)
|
||||
damage /= 2;
|
||||
|
||||
// are effects of weather negated with cloud nine or air lock
|
||||
if (!AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_CLOUD_NINE, 0, 0)
|
||||
&& !AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_AIR_LOCK, 0, 0))
|
||||
{
|
||||
if (gBattleWeather & WEATHER_RAIN_TEMPORARY)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_FIRE:
|
||||
damage /= 2;
|
||||
break;
|
||||
case TYPE_WATER:
|
||||
damage = (15 * damage) / 10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// any weather except sun weakens solar beam
|
||||
if ((gBattleWeather & (WEATHER_RAIN_ANY | WEATHER_SANDSTORM_ANY | WEATHER_HAIL)) && gCurrentMove == MOVE_SOLAR_BEAM)
|
||||
damage /= 2;
|
||||
|
||||
// sunny
|
||||
if (gBattleWeather & WEATHER_SUN_ANY)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_FIRE:
|
||||
damage = (15 * damage) / 10;
|
||||
break;
|
||||
case TYPE_WATER:
|
||||
damage /= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// flash fire triggered
|
||||
if ((gBattleResources->flags->flags[bankAtk] & UNKNOWN_FLAG_FLASH_FIRE) && type == TYPE_FIRE)
|
||||
damage = (15 * damage) / 10;
|
||||
}
|
||||
|
||||
return damage + 2;
|
||||
}
|
||||
77
src/coins.c
Normal file
77
src/coins.c
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "global.h"
|
||||
#include "coins.h"
|
||||
#include "text.h"
|
||||
#include "window.h"
|
||||
#include "text_window.h"
|
||||
#include "string_util.h"
|
||||
|
||||
#define MAX_COINS 9999
|
||||
|
||||
EWRAM_DATA u8 sCoinsWindowId = 0;
|
||||
|
||||
extern s32 GetStringRightAlignXOffset(u8 fontId, u8 *str, s32 totalWidth);
|
||||
extern void SetWindowTemplateFields(struct WindowTemplate* template, u8 priority, u8 tilemapLeft, u8 tilemapTop, u8 width, u8 height, u8 palNum, u16 baseBlock);
|
||||
extern void SetWindowBorderStyle(u8 windowId, bool8 copyToVram, s16 tileStart, s8 palette);
|
||||
extern void sub_819746C(u8 windowId, bool8 copyToVram);
|
||||
|
||||
extern const u8 gOtherText_Coins2[];
|
||||
|
||||
void PrintCoinsString(u32 coinAmount)
|
||||
{
|
||||
u32 xAlign;
|
||||
|
||||
ConvertIntToDecimalStringN(gStringVar1, coinAmount, STR_CONV_MODE_RIGHT_ALIGN, 4);
|
||||
StringExpandPlaceholders(gStringVar4, gOtherText_Coins2);
|
||||
|
||||
xAlign = GetStringRightAlignXOffset(1, gStringVar4, 0x40);
|
||||
PrintTextOnWindow(sCoinsWindowId, 1, gStringVar4, xAlign, 1, 0, NULL);
|
||||
}
|
||||
|
||||
void ShowCoinsWindow(u32 coinAmount, u8 x, u8 y)
|
||||
{
|
||||
struct WindowTemplate template;
|
||||
SetWindowTemplateFields(&template, 0, x, y, 8, 2, 0xF, 0x141);
|
||||
sCoinsWindowId = AddWindow(&template);
|
||||
FillWindowPixelBuffer(sCoinsWindowId, 0);
|
||||
PutWindowTilemap(sCoinsWindowId);
|
||||
SetWindowBorderStyle(sCoinsWindowId, FALSE, 0x214, 0xE);
|
||||
PrintCoinsString(coinAmount);
|
||||
}
|
||||
|
||||
void HideCoinsWindow(void)
|
||||
{
|
||||
sub_819746C(sCoinsWindowId, TRUE);
|
||||
RemoveWindow(sCoinsWindowId);
|
||||
}
|
||||
|
||||
u16 GetCoins(void)
|
||||
{
|
||||
return gSaveBlock1Ptr->coins ^ gSaveBlock2Ptr->encryptionKey;
|
||||
}
|
||||
|
||||
void SetCoins(u16 coinAmount)
|
||||
{
|
||||
gSaveBlock1Ptr->coins = coinAmount ^ gSaveBlock2Ptr->encryptionKey;
|
||||
}
|
||||
|
||||
/* Can't match it lol
|
||||
bool8 AddCoins(u16 toAdd)
|
||||
{
|
||||
u16 newAmount;
|
||||
u16 ownedCoins = GetCoins();
|
||||
if (ownedCoins >= MAX_COINS)
|
||||
return FALSE;
|
||||
// check overflow, can't have less coins than previously
|
||||
if (ownedCoins > ownedCoins + toAdd)
|
||||
{
|
||||
newAmount = MAX_COINS;
|
||||
}
|
||||
else
|
||||
{
|
||||
newAmount = ownedCoins + toAdd;
|
||||
if (newAmount > MAX_COINS)
|
||||
newAmount = MAX_COINS;
|
||||
}
|
||||
SetCoins(newAmount);
|
||||
return TRUE;
|
||||
}*/
|
||||
114
src/load_save.c
Normal file
114
src/load_save.c
Normal file
@@ -0,0 +1,114 @@
|
||||
#include "global.h"
|
||||
#include "gba/flash_internal.h"
|
||||
#include "load_save.h"
|
||||
#include "main.h"
|
||||
#include "pokemon.h"
|
||||
#include "rng.h"
|
||||
#include "malloc.h"
|
||||
|
||||
extern u8 gPlayerPartyCount;
|
||||
extern struct PokemonStorage* gPokemonStoragePtr;
|
||||
extern void* gUnknown_0203CF5C;
|
||||
extern u8 gHeap[0x1C000];
|
||||
|
||||
extern bool16 IdentifyFlash(void);
|
||||
extern void SetBagItemsPointers(void);
|
||||
extern void SetDecorationInventoriesPointers(void);
|
||||
extern void InitHeap(void *heapStart, u32 heapSize);
|
||||
|
||||
void ApplyNewEncyprtionKeyToAllEncryptedData(u32 encryptionKey);
|
||||
|
||||
#define SAVEBLOCK_MOVE_RANGE 128
|
||||
|
||||
EWRAM_DATA struct SaveBlock2 gSaveblock2 = {0};
|
||||
EWRAM_DATA u8 gSaveblock2_DMA[SAVEBLOCK_MOVE_RANGE] = {0};
|
||||
|
||||
EWRAM_DATA struct SaveBlock1 gSaveblock1 = {0};
|
||||
EWRAM_DATA u8 gSaveblock1_DMA[SAVEBLOCK_MOVE_RANGE] = {0};
|
||||
|
||||
EWRAM_DATA struct PokemonStorage gPokemonStorage = {0};
|
||||
EWRAM_DATA u8 gSaveblock3_DMA[SAVEBLOCK_MOVE_RANGE] = {0};
|
||||
|
||||
void CheckForFlashMemory(void)
|
||||
{
|
||||
if (!IdentifyFlash())
|
||||
{
|
||||
gFlashMemoryPresent = TRUE;
|
||||
InitFlashTimer();
|
||||
}
|
||||
else
|
||||
gFlashMemoryPresent = FALSE;
|
||||
}
|
||||
|
||||
void ClearSav2(void)
|
||||
{
|
||||
CpuFill16(0, &gSaveblock2, sizeof(struct SaveBlock2) + sizeof(gSaveblock2_DMA));
|
||||
}
|
||||
|
||||
void ClearSav1(void)
|
||||
{
|
||||
CpuFill16(0, &gSaveblock1, sizeof(struct SaveBlock1) + sizeof(gSaveblock1_DMA));
|
||||
}
|
||||
|
||||
void SetSaveBlocksPointers(u16 offset)
|
||||
{
|
||||
struct SaveBlock1** sav1_LocalVar = &gSaveBlock1Ptr;
|
||||
|
||||
offset = (offset + Random()) & (SAVEBLOCK_MOVE_RANGE - 4);
|
||||
|
||||
gSaveBlock2Ptr = (void*)(&gSaveblock2) + offset;
|
||||
*sav1_LocalVar = (void*)(&gSaveblock1) + offset;
|
||||
gPokemonStoragePtr = (void*)(&gPokemonStorage) + offset;
|
||||
|
||||
SetBagItemsPointers();
|
||||
SetDecorationInventoriesPointers();
|
||||
}
|
||||
|
||||
struct SaveBlocksInOne
|
||||
{
|
||||
struct SaveBlock2 sav2;
|
||||
struct SaveBlock1 sav1;
|
||||
struct PokemonStorage sav3;
|
||||
};
|
||||
/*
|
||||
void MoveSaveBlocks_ResetHeap(void)
|
||||
{
|
||||
void *vblankCB, *hblankCB;
|
||||
u32 encryptionKey;
|
||||
struct SaveBlocksInOne* copiedSavs;
|
||||
|
||||
// save interrupt functions and turn them off
|
||||
vblankCB = gMain.vblankCallback;
|
||||
hblankCB = gMain.hblankCallback;
|
||||
gMain.vblankCallback = NULL;
|
||||
gMain.hblankCallback = NULL;
|
||||
gUnknown_0203CF5C = NULL;
|
||||
|
||||
copiedSavs = (void*)(gHeap);
|
||||
|
||||
// copy saveblocks' content
|
||||
copiedSavs->sav2 = *gSaveBlock2Ptr;
|
||||
copiedSavs->sav1 = *gSaveBlock1Ptr;
|
||||
copiedSavs->sav3 = *gPokemonStoragePtr;
|
||||
|
||||
// change saveblocks' pointers
|
||||
// argument is a sum of the individual trainerId bytes
|
||||
SetSaveBlocksPointers(copiedSavs->sav2.playerTrainerId[0] + copiedSavs->sav2.playerTrainerId[1] + copiedSavs->sav2.playerTrainerId[2] + copiedSavs->sav2.playerTrainerId[3]);
|
||||
|
||||
// restore saveblock data since the pointers changed
|
||||
*gSaveBlock2Ptr = copiedSavs->sav2;
|
||||
*gSaveBlock1Ptr = copiedSavs->sav1;
|
||||
*gPokemonStoragePtr = copiedSavs->sav3;
|
||||
|
||||
// heap was destroyed in the copying process, so reset it
|
||||
InitHeap(gHeap, sizeof(gHeap));
|
||||
|
||||
// restore interrupt functions
|
||||
gMain.hblankCallback = hblankCB;
|
||||
gMain.vblankCallback = vblankCB;
|
||||
|
||||
// create a new encryption key
|
||||
encryptionKey = (Random() << 0x10) + (Random());
|
||||
ApplyNewEncyprtionKeyToAllEncryptedData(encryptionKey);
|
||||
gSaveBlock2Ptr->encryptionKey = encryptionKey;
|
||||
}*/
|
||||
167
src/lottery_corner.c
Normal file
167
src/lottery_corner.c
Normal file
@@ -0,0 +1,167 @@
|
||||
#include "global.h"
|
||||
#include "lottery_corner.h"
|
||||
#include "event_data.h"
|
||||
#include "pokemon.h"
|
||||
#include "items.h"
|
||||
#include "rng.h"
|
||||
#include "species.h"
|
||||
#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();
|
||||
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++)
|
||||
{
|
||||
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);
|
||||
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(&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);
|
||||
}
|
||||
14
src/main.c
14
src/main.c
@@ -5,6 +5,7 @@
|
||||
#include "rng.h"
|
||||
#include "dma3.h"
|
||||
#include "gba/flash_internal.h"
|
||||
#include "battle.h"
|
||||
|
||||
extern u16 GetGpuReg(u8);
|
||||
extern void SetGpuReg(u8, u16);
|
||||
@@ -34,9 +35,8 @@ extern struct SoundInfo gSoundInfo;
|
||||
extern u32 gFlashMemoryPresent;
|
||||
extern u32 IntrMain[];
|
||||
extern u8 gHeap[];
|
||||
extern struct SaveBlock2 gUnknown_02024A54;
|
||||
extern char *gUnknown_03005D94;
|
||||
extern char gUnknown_02029808[];
|
||||
extern struct SaveBlock2 gSaveblock2;
|
||||
extern struct PokemonStorage gPokemonStorage;
|
||||
extern u32 gBattleTypeFlags;
|
||||
extern u8 gUnknown_03002748;
|
||||
extern u32 *gUnknown_0203CF5C;
|
||||
@@ -185,8 +185,8 @@ static void InitMainCallbacks(void)
|
||||
gMain.vblankCounter2 = 0;
|
||||
gMain.callback1 = NULL;
|
||||
SetMainCallback2(c2_copyright_1);
|
||||
gSaveBlock2Ptr = &gUnknown_02024A54;
|
||||
gUnknown_03005D94 = gUnknown_02029808;
|
||||
gSaveBlock2Ptr = &gSaveblock2;
|
||||
gPokemonStoragePtr = &gPokemonStorage;
|
||||
}
|
||||
|
||||
static void CallCallbacks(void)
|
||||
@@ -359,7 +359,7 @@ static void VBlankIntr(void)
|
||||
m4aSoundMain();
|
||||
sub_8033648();
|
||||
|
||||
if (!gMain.inBattle || (gBattleTypeFlags & 0x013F0102) == 0)
|
||||
if (!gMain.inBattle || !(gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_FRONTIER | BATTLE_TYPE_RECORDED)))
|
||||
Random();
|
||||
|
||||
sub_800E174();
|
||||
@@ -368,7 +368,7 @@ static void VBlankIntr(void)
|
||||
gMain.intrCheck |= INTR_FLAG_VBLANK;
|
||||
}
|
||||
|
||||
void StartFlashMemoryTimer(void)
|
||||
void InitFlashTimer(void)
|
||||
{
|
||||
SetFlashTimerIntr(2, gIntrTable + 0x7);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include "global.h"
|
||||
|
||||
EWRAM_DATA u8 gHeap[0x1C000] = {0};
|
||||
|
||||
static void *sHeapStart;
|
||||
static u32 sHeapSize;
|
||||
|
||||
|
||||
55
src/money.c
Normal file
55
src/money.c
Normal file
@@ -0,0 +1,55 @@
|
||||
#include "global.h"
|
||||
#include "money.h"
|
||||
|
||||
#define MAX_MONEY 999999
|
||||
|
||||
u32 GetMoney(u32* moneyPtr)
|
||||
{
|
||||
return *moneyPtr ^ gSaveBlock2Ptr->encryptionKey;
|
||||
}
|
||||
|
||||
void SetMoney(u32* moneyPtr, u32 newValue)
|
||||
{
|
||||
*moneyPtr = gSaveBlock2Ptr->encryptionKey ^ newValue;
|
||||
}
|
||||
|
||||
bool8 IsEnoughMoney(u32* moneyPtr, u32 cost)
|
||||
{
|
||||
if (GetMoney(moneyPtr) >= cost)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void AddMoney(u32* moneyPtr, u32 toAdd)
|
||||
{
|
||||
u32 toSet = GetMoney(moneyPtr);
|
||||
|
||||
// can't have more money than MAX
|
||||
if (toSet + toAdd > MAX_MONEY)
|
||||
{
|
||||
toSet = MAX_MONEY;
|
||||
}
|
||||
else
|
||||
{
|
||||
toSet += toAdd;
|
||||
// check overflow, can't have less money after you receive more
|
||||
if (toSet < GetMoney(moneyPtr))
|
||||
toSet = MAX_MONEY;
|
||||
}
|
||||
|
||||
SetMoney(moneyPtr, toSet);
|
||||
}
|
||||
|
||||
void SubtractMoney(u32* moneyPtr, u32 toSub)
|
||||
{
|
||||
u32 toSet = GetMoney(moneyPtr);
|
||||
|
||||
// can't subtract more than you already have
|
||||
if (toSet < toSub)
|
||||
toSet = 0;
|
||||
else
|
||||
toSet -= toSub;
|
||||
|
||||
SetMoney(moneyPtr, toSet);
|
||||
}
|
||||
117
src/new_game.c
117
src/new_game.c
@@ -1,22 +1,64 @@
|
||||
#include "global.h"
|
||||
#include "new_game.h"
|
||||
#include "rng.h"
|
||||
#include "pokemon.h"
|
||||
#include "roamer.h"
|
||||
#include "pokemon_size_record.h"
|
||||
#include "script.h"
|
||||
#include "lottery_corner.h"
|
||||
#include "play_time.h"
|
||||
#include "mauville_old_man.h"
|
||||
#include "lilycove_lady.h"
|
||||
#include "load_save.h"
|
||||
#include "pokeblock.h"
|
||||
#include "dewford_trend.h"
|
||||
#include "berry.h"
|
||||
#include "rtc.h"
|
||||
#include "easy_chat.h"
|
||||
#include "event_data.h"
|
||||
#include "money.h"
|
||||
#include "coins.h"
|
||||
|
||||
extern u8 gPlayerPartyCount;
|
||||
extern u8 gDifferentSaveFile;
|
||||
extern u16 gSaveFileStatus;
|
||||
extern u8 gUnknown_030060B0;
|
||||
|
||||
// TODO: replace those declarations with file headers
|
||||
extern u16 GetGeneratedTrainerIdLower(void);
|
||||
extern void ClearContestWinnerPicsInContestHall(void);
|
||||
extern void warp1_set(s8 mapBank, s8 mapNo, s8 warpNo, s8 xPos, s8 yPos);
|
||||
extern void warp_in(void);
|
||||
extern void sub_80BB358(void);
|
||||
extern void ZeroPlayerPartyMons(void);
|
||||
extern void ZeroEnemyPartyMons(void);
|
||||
extern void ResetBagScrollPositions(void);
|
||||
extern void sub_813624C(void); // clears something pokeblock related
|
||||
extern void ClearSav2(void); // clears something pokeblock related
|
||||
extern void ResetPokedex(void);
|
||||
extern void sub_8084400(void);
|
||||
extern void ClearMailData(void);
|
||||
extern void ClearTVShowData(void);
|
||||
extern void ResetGabbyAndTy(void);
|
||||
extern void ResetSecretBases(void);
|
||||
extern void ResetLinkContestBoolean(void);
|
||||
extern void ResetGameStats(void);
|
||||
extern void sub_8052DA8(void);
|
||||
extern void InitLinkBattleRecords(void);
|
||||
extern void ResetPokemonStorageSystem(void);
|
||||
extern void ClearBag(void);
|
||||
extern void NewGameInitPCItems(void);
|
||||
extern void ClearDecorationInventories(void);
|
||||
extern void ResetFanClub(void);
|
||||
extern void copy_strings_to_sav1(void);
|
||||
extern void sub_819FAA0(void);
|
||||
extern void sub_81A4B14(void);
|
||||
extern void sub_8195E10(void);
|
||||
extern void sub_801AFD8(void);
|
||||
extern void sub_800E5AC(void);
|
||||
extern void sub_81D54BC(void);
|
||||
extern void ResetContestLinkResults(void);
|
||||
extern void ResetPokeJumpResults(void);
|
||||
extern void SetBerryPowder(u32* powder, u32 newValue);
|
||||
|
||||
extern u8 gUnknown_082715DE[];
|
||||
|
||||
void WriteUnalignedWord(u32 var, u8 *dataPtr)
|
||||
{
|
||||
@@ -104,8 +146,71 @@ void sub_808447C(void)
|
||||
ResetBagScrollPositions();
|
||||
sub_813624C();
|
||||
}
|
||||
/*
|
||||
|
||||
void NewGameInitData(void)
|
||||
{
|
||||
Finish when more header files are available
|
||||
}*/
|
||||
if (gSaveFileStatus == 0 || gSaveFileStatus == 2)
|
||||
RtcReset();
|
||||
|
||||
gDifferentSaveFile = 1;
|
||||
gSaveBlock2Ptr->encryptionKey = 0;
|
||||
ZeroPlayerPartyMons();
|
||||
ZeroEnemyPartyMons();
|
||||
ResetPokedex();
|
||||
sub_8084400();
|
||||
ClearSav1();
|
||||
ClearMailData();
|
||||
gSaveBlock2Ptr->specialSaveWarp = 0;
|
||||
gSaveBlock2Ptr->field_A8 = 0;
|
||||
InitPlayerTrainerId();
|
||||
PlayTimeCounter_Reset();
|
||||
ClearPokedexFlags();
|
||||
InitEventData();
|
||||
ClearTVShowData();
|
||||
ResetGabbyAndTy();
|
||||
ResetSecretBases();
|
||||
ClearBerryTrees();
|
||||
SetMoney(&gSaveBlock1Ptr->money, 3000);
|
||||
SetCoins(0);
|
||||
ResetLinkContestBoolean();
|
||||
ResetGameStats();
|
||||
ClearAllContestWinnerPics();
|
||||
InitLinkBattleRecords();
|
||||
InitSeedotSizeRecord();
|
||||
InitLotadSizeRecord();
|
||||
gPlayerPartyCount = 0;
|
||||
ZeroPlayerPartyMons();
|
||||
ResetPokemonStorageSystem();
|
||||
ClearRoamerData();
|
||||
ClearRoamerLocationData();
|
||||
gSaveBlock1Ptr->registeredItem = 0;
|
||||
ClearBag();
|
||||
NewGameInitPCItems();
|
||||
ClearPokeblocks();
|
||||
ClearDecorationInventories();
|
||||
InitEasyChatPhrases();
|
||||
SetMauvilleOldMan();
|
||||
InitDewfordTrend();
|
||||
ResetFanClub();
|
||||
ResetLotteryCorner();
|
||||
WarpToTruck();
|
||||
ScriptContext2_RunNewScript(gUnknown_082715DE);
|
||||
ResetMiniGamesResults();
|
||||
copy_strings_to_sav1();
|
||||
SetLilycoveLady();
|
||||
sub_819FAA0();
|
||||
sub_81A4B14();
|
||||
sub_8195E10();
|
||||
sub_801AFD8();
|
||||
sub_800E5AC();
|
||||
sub_81D54BC();
|
||||
ResetContestLinkResults();
|
||||
}
|
||||
|
||||
void ResetMiniGamesResults(void)
|
||||
{
|
||||
CpuFill16(0, &gSaveBlock2Ptr->berryCrush, sizeof(struct BerryCrush));
|
||||
SetBerryPowder(&gSaveBlock2Ptr->berryCrush.berryPowderAmount, 0);
|
||||
ResetPokeJumpResults();
|
||||
CpuFill16(0, &gSaveBlock2Ptr->berryPick, sizeof(struct BerryPickingResults));
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ EWRAM_DATA struct PaletteStruct sPaletteStructs[0x10] = {0};
|
||||
EWRAM_DATA struct PaletteFadeControl gPaletteFade = {0};
|
||||
EWRAM_DATA u32 gFiller_2037FE0 = 0;
|
||||
EWRAM_DATA u32 sPlttBufferTransferPending = 0;
|
||||
EWRAM_DATA u8 sPaletteDecompressionBuffer[0x400] = {0};
|
||||
EWRAM_DATA u8 gPaletteDecompressionBuffer[0x400] = {0};
|
||||
|
||||
extern struct PaletteStructTemplate gDummyPaletteStructTemplate;
|
||||
extern void *gUnknown_0852487C;
|
||||
@@ -102,9 +102,9 @@ void sub_80A1884(u16 a1)
|
||||
|
||||
void LoadCompressedPalette(const void *src, u16 offset, u16 size)
|
||||
{
|
||||
LZDecompressWram(src, sPaletteDecompressionBuffer);
|
||||
CpuCopy16(sPaletteDecompressionBuffer, gPlttBufferUnfaded + offset, size);
|
||||
CpuCopy16(sPaletteDecompressionBuffer, gPlttBufferFaded + offset, size);
|
||||
LZDecompressWram(src, gPaletteDecompressionBuffer);
|
||||
CpuCopy16(gPaletteDecompressionBuffer, gPlttBufferUnfaded + offset, size);
|
||||
CpuCopy16(gPaletteDecompressionBuffer, gPlttBufferFaded + offset, size);
|
||||
}
|
||||
|
||||
void LoadPalette(const void *src, u16 offset, u16 size)
|
||||
|
||||
@@ -10,7 +10,7 @@ enum
|
||||
|
||||
static u8 sPlayTimeCounterState;
|
||||
|
||||
void PlayTimeCounter_Reset()
|
||||
void PlayTimeCounter_Reset(void)
|
||||
{
|
||||
sPlayTimeCounterState = STOPPED;
|
||||
|
||||
@@ -20,7 +20,7 @@ void PlayTimeCounter_Reset()
|
||||
gSaveBlock2Ptr->playTimeVBlanks = 0;
|
||||
}
|
||||
|
||||
void PlayTimeCounter_Start()
|
||||
void PlayTimeCounter_Start(void)
|
||||
{
|
||||
sPlayTimeCounterState = RUNNING;
|
||||
|
||||
@@ -28,12 +28,12 @@ void PlayTimeCounter_Start()
|
||||
PlayTimeCounter_SetToMax();
|
||||
}
|
||||
|
||||
void PlayTimeCounter_Stop()
|
||||
void PlayTimeCounter_Stop(void)
|
||||
{
|
||||
sPlayTimeCounterState = STOPPED;
|
||||
}
|
||||
|
||||
void PlayTimeCounter_Update()
|
||||
void PlayTimeCounter_Update(void)
|
||||
{
|
||||
if (sPlayTimeCounterState == RUNNING)
|
||||
{
|
||||
@@ -62,7 +62,7 @@ void PlayTimeCounter_Update()
|
||||
}
|
||||
}
|
||||
|
||||
void PlayTimeCounter_SetToMax()
|
||||
void PlayTimeCounter_SetToMax(void)
|
||||
{
|
||||
sPlayTimeCounterState = MAXED_OUT;
|
||||
|
||||
|
||||
325
src/pokemon_1.c
Normal file
325
src/pokemon_1.c
Normal file
@@ -0,0 +1,325 @@
|
||||
#include "global.h"
|
||||
#include "pokemon.h"
|
||||
#include "rng.h"
|
||||
#include "main.h"
|
||||
#include "items.h"
|
||||
#include "string_util.h"
|
||||
#include "text.h"
|
||||
|
||||
//Extracts the upper 16 bits of a 32-bit number
|
||||
#define HIHALF(n) (((n) & 0xFFFF0000) >> 16)
|
||||
|
||||
//Extracts the lower 16 bits of a 32-bit number
|
||||
#define LOHALF(n) ((n) & 0xFFFF)
|
||||
|
||||
extern u8 sav1_map_get_name(void);
|
||||
|
||||
void ZeroBoxMonData(struct BoxPokemon *boxMon)
|
||||
{
|
||||
u8 *raw = (u8 *)boxMon;
|
||||
u32 i;
|
||||
for (i = 0; i < sizeof(struct BoxPokemon); i++)
|
||||
raw[i] = 0;
|
||||
}
|
||||
|
||||
void ZeroMonData(struct Pokemon *mon)
|
||||
{
|
||||
u32 arg;
|
||||
ZeroBoxMonData(&mon->box);
|
||||
arg = 0;
|
||||
SetMonData(mon, MON_DATA_STATUS, &arg);
|
||||
SetMonData(mon, MON_DATA_LEVEL, &arg);
|
||||
SetMonData(mon, MON_DATA_HP, &arg);
|
||||
SetMonData(mon, MON_DATA_MAX_HP, &arg);
|
||||
SetMonData(mon, MON_DATA_ATK, &arg);
|
||||
SetMonData(mon, MON_DATA_DEF, &arg);
|
||||
SetMonData(mon, MON_DATA_SPD, &arg);
|
||||
SetMonData(mon, MON_DATA_SPATK, &arg);
|
||||
SetMonData(mon, MON_DATA_SPDEF, &arg);
|
||||
arg = 255;
|
||||
SetMonData(mon, MON_DATA_MAIL, &arg);
|
||||
}
|
||||
|
||||
void ZeroPlayerPartyMons(void)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < 6; i++)
|
||||
ZeroMonData(&gPlayerParty[i]);
|
||||
}
|
||||
|
||||
void ZeroEnemyPartyMons(void)
|
||||
{
|
||||
s32 i;
|
||||
for (i = 0; i < 6; i++)
|
||||
ZeroMonData(&gEnemyParty[i]);
|
||||
}
|
||||
|
||||
void CreateMon(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
|
||||
{
|
||||
u32 arg;
|
||||
ZeroMonData(mon);
|
||||
CreateBoxMon(&mon->box, species, level, fixedIV, hasFixedPersonality, fixedPersonality, otIdType, fixedOtId);
|
||||
SetMonData(mon, MON_DATA_LEVEL, &level);
|
||||
arg = 255;
|
||||
SetMonData(mon, MON_DATA_MAIL, &arg);
|
||||
CalculateMonStats(mon);
|
||||
}
|
||||
|
||||
void CreateBoxMon(struct BoxPokemon *boxMon, u16 species, u8 level, u8 fixedIV, u8 hasFixedPersonality, u32 fixedPersonality, u8 otIdType, u32 fixedOtId)
|
||||
{
|
||||
u8 speciesName[POKEMON_NAME_LENGTH + 1];
|
||||
u32 personality;
|
||||
u32 value;
|
||||
u16 checksum;
|
||||
|
||||
ZeroBoxMonData(boxMon);
|
||||
|
||||
if (hasFixedPersonality)
|
||||
personality = fixedPersonality;
|
||||
else
|
||||
personality = Random32();
|
||||
|
||||
SetBoxMonData(boxMon, MON_DATA_PERSONALITY, &personality);
|
||||
|
||||
//Determine original trainer ID
|
||||
if (otIdType == OT_ID_RANDOM_NO_SHINY) //Pokemon cannot be shiny
|
||||
{
|
||||
u32 shinyValue;
|
||||
do
|
||||
{
|
||||
value = Random32();
|
||||
shinyValue = HIHALF(value) ^ LOHALF(value) ^ HIHALF(personality) ^ LOHALF(personality);
|
||||
} while (shinyValue < 8);
|
||||
}
|
||||
else if (otIdType == OT_ID_PRESET) //Pokemon has a preset OT ID
|
||||
{
|
||||
value = fixedOtId;
|
||||
}
|
||||
else //Player is the OT
|
||||
{
|
||||
value = gSaveBlock2Ptr->playerTrainerId[0]
|
||||
| (gSaveBlock2Ptr->playerTrainerId[1] << 8)
|
||||
| (gSaveBlock2Ptr->playerTrainerId[2] << 16)
|
||||
| (gSaveBlock2Ptr->playerTrainerId[3] << 24);
|
||||
}
|
||||
|
||||
SetBoxMonData(boxMon, MON_DATA_OT_ID, &value);
|
||||
|
||||
checksum = CalculateBoxMonChecksum(boxMon);
|
||||
SetBoxMonData(boxMon, MON_DATA_CHECKSUM, &checksum);
|
||||
EncryptBoxMon(boxMon);
|
||||
GetSpeciesName(speciesName, species);
|
||||
SetBoxMonData(boxMon, MON_DATA_NICKNAME, speciesName);
|
||||
SetBoxMonData(boxMon, MON_DATA_LANGUAGE, &gGameLanguage);
|
||||
SetBoxMonData(boxMon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName);
|
||||
SetBoxMonData(boxMon, MON_DATA_SPECIES, &species);
|
||||
SetBoxMonData(boxMon, MON_DATA_EXP, &gExperienceTables[gBaseStats[species].growthRate][level]);
|
||||
SetBoxMonData(boxMon, MON_DATA_FRIENDSHIP, &gBaseStats[species].friendship);
|
||||
value = sav1_map_get_name();
|
||||
SetBoxMonData(boxMon, MON_DATA_MET_LOCATION, &value);
|
||||
SetBoxMonData(boxMon, MON_DATA_MET_LEVEL, &level);
|
||||
SetBoxMonData(boxMon, MON_DATA_MET_GAME, &gGameVersion);
|
||||
value = ITEM_POKE_BALL;
|
||||
SetBoxMonData(boxMon, MON_DATA_POKEBALL, &value);
|
||||
SetBoxMonData(boxMon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender);
|
||||
|
||||
if (fixedIV < 32)
|
||||
{
|
||||
SetBoxMonData(boxMon, MON_DATA_HP_IV, &fixedIV);
|
||||
SetBoxMonData(boxMon, MON_DATA_ATK_IV, &fixedIV);
|
||||
SetBoxMonData(boxMon, MON_DATA_DEF_IV, &fixedIV);
|
||||
SetBoxMonData(boxMon, MON_DATA_SPD_IV, &fixedIV);
|
||||
SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &fixedIV);
|
||||
SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &fixedIV);
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 iv;
|
||||
value = Random();
|
||||
|
||||
iv = value & 0x1F;
|
||||
SetBoxMonData(boxMon, MON_DATA_HP_IV, &iv);
|
||||
iv = (value & 0x3E0) >> 5;
|
||||
SetBoxMonData(boxMon, MON_DATA_ATK_IV, &iv);
|
||||
iv = (value & 0x7C00) >> 10;
|
||||
SetBoxMonData(boxMon, MON_DATA_DEF_IV, &iv);
|
||||
|
||||
value = Random();
|
||||
|
||||
iv = value & 0x1F;
|
||||
SetBoxMonData(boxMon, MON_DATA_SPD_IV, &iv);
|
||||
iv = (value & 0x3E0) >> 5;
|
||||
SetBoxMonData(boxMon, MON_DATA_SPATK_IV, &iv);
|
||||
iv = (value & 0x7C00) >> 10;
|
||||
SetBoxMonData(boxMon, MON_DATA_SPDEF_IV, &iv);
|
||||
}
|
||||
|
||||
if (gBaseStats[species].ability2)
|
||||
{
|
||||
value = personality & 1;
|
||||
SetBoxMonData(boxMon, MON_DATA_ALT_ABILITY, &value);
|
||||
}
|
||||
|
||||
GiveBoxMonInitialMoveset(boxMon);
|
||||
}
|
||||
|
||||
void CreateMonWithNature(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 nature)
|
||||
{
|
||||
u32 personality;
|
||||
|
||||
do
|
||||
{
|
||||
personality = Random32();
|
||||
}
|
||||
while (nature != GetNatureFromPersonality(personality));
|
||||
|
||||
CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0);
|
||||
}
|
||||
|
||||
void CreateMonWithGenderNatureLetter(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 gender, u8 nature, u8 unownLetter)
|
||||
{
|
||||
u32 personality;
|
||||
|
||||
if ((u8)(unownLetter - 1) < 28)
|
||||
{
|
||||
u16 actualLetter;
|
||||
|
||||
do
|
||||
{
|
||||
personality = Random32();
|
||||
actualLetter = ((((personality & 0x3000000) >> 18) | ((personality & 0x30000) >> 12) | ((personality & 0x300) >> 6) | (personality & 0x3)) % 28);
|
||||
}
|
||||
while (nature != GetNatureFromPersonality(personality)
|
||||
|| gender != GetGenderFromSpeciesAndPersonality(species, personality)
|
||||
|| actualLetter != unownLetter - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
personality = Random32();
|
||||
}
|
||||
while (nature != GetNatureFromPersonality(personality)
|
||||
|| gender != GetGenderFromSpeciesAndPersonality(species, personality));
|
||||
}
|
||||
|
||||
CreateMon(mon, species, level, fixedIV, 1, personality, OT_ID_PLAYER_ID, 0);
|
||||
}
|
||||
|
||||
// This is only used to create Wally's Ralts.
|
||||
void CreateMaleMon(struct Pokemon *mon, u16 species, u8 level)
|
||||
{
|
||||
u32 personality;
|
||||
u32 otId;
|
||||
|
||||
do
|
||||
{
|
||||
otId = Random32();
|
||||
personality = Random32();
|
||||
}
|
||||
while (GetGenderFromSpeciesAndPersonality(species, personality) != MON_MALE);
|
||||
CreateMon(mon, species, level, 32, 1, personality, OT_ID_PRESET, otId);
|
||||
}
|
||||
|
||||
void CreateMonWithIVsPersonality(struct Pokemon *mon, u16 species, u8 level, u32 ivs, u32 personality)
|
||||
{
|
||||
CreateMon(mon, species, level, 0, 1, personality, OT_ID_PLAYER_ID, 0);
|
||||
SetMonData(mon, MON_DATA_IVS, &ivs);
|
||||
CalculateMonStats(mon);
|
||||
}
|
||||
|
||||
void CreateMonWithIVsOTID(struct Pokemon *mon, u16 species, u8 level, u8 *ivs, u32 otId)
|
||||
{
|
||||
CreateMon(mon, species, level, 0, 0, 0, OT_ID_PRESET, otId);
|
||||
SetMonData(mon, MON_DATA_HP_IV, &ivs[0]);
|
||||
SetMonData(mon, MON_DATA_ATK_IV, &ivs[1]);
|
||||
SetMonData(mon, MON_DATA_DEF_IV, &ivs[2]);
|
||||
SetMonData(mon, MON_DATA_SPD_IV, &ivs[3]);
|
||||
SetMonData(mon, MON_DATA_SPATK_IV, &ivs[4]);
|
||||
SetMonData(mon, MON_DATA_SPDEF_IV, &ivs[5]);
|
||||
CalculateMonStats(mon);
|
||||
}
|
||||
|
||||
void CreateMonWithEVSpread(struct Pokemon *mon, u16 species, u8 level, u8 fixedIV, u8 evSpread)
|
||||
{
|
||||
s32 i;
|
||||
s32 statCount = 0;
|
||||
u16 evAmount;
|
||||
u8 temp;
|
||||
|
||||
CreateMon(mon, species, level, fixedIV, 0, 0, 0, 0);
|
||||
|
||||
temp = evSpread;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
if (temp & 1)
|
||||
statCount++;
|
||||
temp >>= 1;
|
||||
}
|
||||
|
||||
evAmount = 510 / statCount;
|
||||
|
||||
temp = 1;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
if (evSpread & temp)
|
||||
SetMonData(mon, MON_DATA_HP_EV + i, &evAmount);
|
||||
temp <<= 1;
|
||||
}
|
||||
|
||||
CalculateMonStats(mon);
|
||||
}
|
||||
|
||||
void sub_806819C(struct Pokemon *mon, struct UnknownPokemonStruct *src)
|
||||
{
|
||||
s32 i;
|
||||
u8 nickname[30];
|
||||
u8 language;
|
||||
u8 value;
|
||||
|
||||
CreateMon(mon, src->species, src->level, 0, 1, src->personality, 1, src->otId);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
SetMonMoveSlot(mon, src->moves[i], i);
|
||||
|
||||
SetMonData(mon, MON_DATA_PP_BONUSES, &src->ppBonuses);
|
||||
SetMonData(mon, MON_DATA_HELD_ITEM, &src->heldItem);
|
||||
SetMonData(mon, MON_DATA_FRIENDSHIP, &src->friendship);
|
||||
|
||||
StringCopy(nickname, src->nickname);
|
||||
|
||||
if (nickname[0] == EXT_CTRL_CODE_BEGIN && nickname[1] == EXT_CTRL_CODE_JPN)
|
||||
{
|
||||
language = LANGUAGE_JAPANESE;
|
||||
StripExtCtrlCodes(nickname);
|
||||
}
|
||||
else
|
||||
language = GAME_LANGUAGE;
|
||||
|
||||
SetMonData(mon, MON_DATA_LANGUAGE, &language);
|
||||
SetMonData(mon, MON_DATA_NICKNAME, nickname);
|
||||
SetMonData(mon, MON_DATA_HP_EV, &src->hpEV);
|
||||
SetMonData(mon, MON_DATA_ATK_EV, &src->attackEV);
|
||||
SetMonData(mon, MON_DATA_DEF_EV, &src->defenseEV);
|
||||
SetMonData(mon, MON_DATA_SPD_EV, &src->speedEV);
|
||||
SetMonData(mon, MON_DATA_SPATK_EV, &src->spAttackEV);
|
||||
SetMonData(mon, MON_DATA_SPDEF_EV, &src->spDefenseEV);
|
||||
value = src->altAbility;
|
||||
SetMonData(mon, MON_DATA_ALT_ABILITY, &value);
|
||||
value = src->hpIV;
|
||||
SetMonData(mon, MON_DATA_HP_IV, &value);
|
||||
value = src->attackIV;
|
||||
SetMonData(mon, MON_DATA_ATK_IV, &value);
|
||||
value = src->defenseIV;
|
||||
SetMonData(mon, MON_DATA_DEF_IV, &value);
|
||||
value = src->speedIV;
|
||||
SetMonData(mon, MON_DATA_SPD_IV, &value);
|
||||
value = src->spAttackIV;
|
||||
SetMonData(mon, MON_DATA_SPATK_IV, &value);
|
||||
value = src->spDefenseIV;
|
||||
SetMonData(mon, MON_DATA_SPDEF_IV, &value);
|
||||
MonRestorePP(mon);
|
||||
CalculateMonStats(mon);
|
||||
}
|
||||
4
src/pokemon_2.c
Normal file
4
src/pokemon_2.c
Normal file
@@ -0,0 +1,4 @@
|
||||
#include "global.h"
|
||||
#include "pokemon.h"
|
||||
|
||||
|
||||
222
src/pokemon_size_record.c
Normal file
222
src/pokemon_size_record.c
Normal file
@@ -0,0 +1,222 @@
|
||||
#include "global.h"
|
||||
#include "pokemon_size_record.h"
|
||||
#include "event_data.h"
|
||||
#include "species.h"
|
||||
#include "string_util.h"
|
||||
#include "text.h"
|
||||
#include "pokemon.h"
|
||||
|
||||
#define DEFAULT_MAX_SIZE 0x8000 // was 0x8100 in Ruby/Sapphire
|
||||
|
||||
struct UnknownStruct
|
||||
{
|
||||
u16 unk0;
|
||||
u8 unk2;
|
||||
u16 unk4;
|
||||
};
|
||||
|
||||
extern u16 GetPokedexHeightWeight(u16 dexNo, bool8 height);
|
||||
extern u16 SpeciesToNationalPokedexNum(u16 species);
|
||||
|
||||
static const struct UnknownStruct sBigMonSizeTable[] =
|
||||
{
|
||||
{ 290, 1, 0 },
|
||||
{ 300, 1, 10 },
|
||||
{ 400, 2, 110 },
|
||||
{ 500, 4, 310 },
|
||||
{ 600, 20, 710 },
|
||||
{ 700, 50, 2710 },
|
||||
{ 800, 100, 7710 },
|
||||
{ 900, 150, 17710 },
|
||||
{ 1000, 150, 32710 },
|
||||
{ 1100, 100, -17826 },
|
||||
{ 1200, 50, -7826 },
|
||||
{ 1300, 20, -2826 },
|
||||
{ 1400, 5, -826 },
|
||||
{ 1500, 2, -326 },
|
||||
{ 1600, 1, -126 },
|
||||
{ 1700, 1, -26 },
|
||||
};
|
||||
|
||||
static const u8 sGiftRibbonsMonDataIds[] =
|
||||
{
|
||||
MON_DATA_GIFT_RIBBON_1, MON_DATA_GIFT_RIBBON_2, MON_DATA_GIFT_RIBBON_3,
|
||||
MON_DATA_GIFT_RIBBON_4, MON_DATA_GIFT_RIBBON_5, MON_DATA_GIFT_RIBBON_6,
|
||||
MON_DATA_GIFT_RIBBON_7
|
||||
};
|
||||
|
||||
extern const u8 gOtherText_DecimalPoint[];
|
||||
extern const u8 gOtherText_Marco[];
|
||||
extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1];
|
||||
|
||||
#define CM_PER_INCH 2.54
|
||||
|
||||
static u32 GetMonSizeHash(struct Pokemon *pkmn)
|
||||
{
|
||||
u16 personality = GetMonData(pkmn, MON_DATA_PERSONALITY);
|
||||
u16 hpIV = GetMonData(pkmn, MON_DATA_HP_IV) & 0xF;
|
||||
u16 attackIV = GetMonData(pkmn, MON_DATA_ATK_IV) & 0xF;
|
||||
u16 defenseIV = GetMonData(pkmn, MON_DATA_DEF_IV) & 0xF;
|
||||
u16 speedIV = GetMonData(pkmn, MON_DATA_SPD_IV) & 0xF;
|
||||
u16 spAtkIV = GetMonData(pkmn, MON_DATA_SPATK_IV) & 0xF;
|
||||
u16 spDefIV = GetMonData(pkmn, MON_DATA_SPDEF_IV) & 0xF;
|
||||
u32 hibyte = ((attackIV ^ defenseIV) * hpIV) ^ (personality & 0xFF);
|
||||
u32 lobyte = ((spAtkIV ^ spDefIV) * speedIV) ^ (personality >> 8);
|
||||
|
||||
return (hibyte << 8) + lobyte;
|
||||
}
|
||||
|
||||
static u8 TranslateBigMonSizeTableIndex(u16 a)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
for (i = 1; i < 15; i++)
|
||||
{
|
||||
if (a < sBigMonSizeTable[i].unk4)
|
||||
return i - 1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static u32 GetMonSize(u16 species, u16 b)
|
||||
{
|
||||
u64 unk2;
|
||||
u64 unk4;
|
||||
u64 unk0;
|
||||
u32 height;
|
||||
u32 var;
|
||||
|
||||
height = GetPokedexHeightWeight(SpeciesToNationalPokedexNum(species), 0);
|
||||
var = TranslateBigMonSizeTableIndex(b);
|
||||
unk0 = sBigMonSizeTable[var].unk0;
|
||||
unk2 = sBigMonSizeTable[var].unk2;
|
||||
unk4 = sBigMonSizeTable[var].unk4;
|
||||
unk0 += (b - unk4) / unk2;
|
||||
return height * unk0 / 10;
|
||||
}
|
||||
|
||||
static void FormatMonSizeRecord(u8 *string, u32 size)
|
||||
{
|
||||
#ifdef UNITS_IMPERIAL
|
||||
//Convert size from centimeters to inches
|
||||
size = (double)(size * 10) / (CM_PER_INCH * 10);
|
||||
#endif
|
||||
|
||||
string = ConvertIntToDecimalStringN(string, size / 10, 0, 8);
|
||||
string = StringAppend(string, gOtherText_DecimalPoint);
|
||||
ConvertIntToDecimalStringN(string, size % 10, 0, 1);
|
||||
}
|
||||
|
||||
static u8 CompareMonSize(u16 species, u16 *sizeRecord)
|
||||
{
|
||||
if (gScriptResult == 0xFF)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct Pokemon *pkmn = &gPlayerParty[gScriptResult];
|
||||
|
||||
if (GetMonData(pkmn, MON_DATA_IS_EGG) == TRUE || GetMonData(pkmn, MON_DATA_SPECIES) != species)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
u32 oldSize;
|
||||
u32 newSize;
|
||||
u16 sizeParams;
|
||||
|
||||
*(&sizeParams) = GetMonSizeHash(pkmn);
|
||||
newSize = GetMonSize(species, sizeParams);
|
||||
oldSize = GetMonSize(species, *sizeRecord);
|
||||
FormatMonSizeRecord(gStringVar2, newSize);
|
||||
if (newSize <= oldSize)
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
*sizeRecord = sizeParams;
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Stores species name in gStringVar1, trainer's name in gStringVar2, and size in gStringVar3
|
||||
static void GetMonSizeRecordInfo(u16 species, u16 *sizeRecord)
|
||||
{
|
||||
u32 size = GetMonSize(species, *sizeRecord);
|
||||
|
||||
FormatMonSizeRecord(gStringVar3, size);
|
||||
StringCopy(gStringVar1, gSpeciesNames[species]);
|
||||
if (*sizeRecord == DEFAULT_MAX_SIZE)
|
||||
StringCopy(gStringVar2, gOtherText_Marco);
|
||||
else
|
||||
StringCopy(gStringVar2, gSaveBlock2Ptr->playerName);
|
||||
}
|
||||
|
||||
void InitSeedotSizeRecord(void)
|
||||
{
|
||||
VarSet(VAR_SEEDOT_SIZE_RECORD, DEFAULT_MAX_SIZE);
|
||||
}
|
||||
|
||||
void GetSeedotSizeRecordInfo(void)
|
||||
{
|
||||
u16 *sizeRecord = GetVarPointer(VAR_SEEDOT_SIZE_RECORD);
|
||||
|
||||
GetMonSizeRecordInfo(SPECIES_SEEDOT, sizeRecord);
|
||||
}
|
||||
|
||||
void CompareSeedotSize(void)
|
||||
{
|
||||
u16 *sizeRecord = GetVarPointer(VAR_SEEDOT_SIZE_RECORD);
|
||||
|
||||
gScriptResult = CompareMonSize(SPECIES_SEEDOT, sizeRecord);
|
||||
}
|
||||
|
||||
void InitLotadSizeRecord(void)
|
||||
{
|
||||
VarSet(VAR_LOTAD_SIZE_RECORD, DEFAULT_MAX_SIZE);
|
||||
}
|
||||
|
||||
void GetLotadSizeRecordInfo(void)
|
||||
{
|
||||
u16 *sizeRecord = GetVarPointer(VAR_LOTAD_SIZE_RECORD);
|
||||
|
||||
GetMonSizeRecordInfo(SPECIES_LOTAD, sizeRecord);
|
||||
}
|
||||
|
||||
void CompareLotadSize(void)
|
||||
{
|
||||
u16 *sizeRecord = GetVarPointer(VAR_LOTAD_SIZE_RECORD);
|
||||
|
||||
gScriptResult = CompareMonSize(SPECIES_LOTAD, sizeRecord);
|
||||
}
|
||||
|
||||
void GiveGiftRibbonToParty(u8 index, u8 ribbonId)
|
||||
{
|
||||
s32 i;
|
||||
bool32 gotRibbon = FALSE;
|
||||
u8 data = 1;
|
||||
u8 array[8];
|
||||
memcpy(array, sGiftRibbonsMonDataIds, sizeof(sGiftRibbonsMonDataIds));
|
||||
|
||||
if (index < 11 && ribbonId < 65)
|
||||
{
|
||||
gSaveBlock1Ptr->giftRibbons[index] = ribbonId;
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
struct Pokemon *pkmn = &gPlayerParty[i];
|
||||
|
||||
if (GetMonData(pkmn, MON_DATA_SPECIES) != 0 && GetMonData(pkmn, MON_DATA_SANITY_BIT3) == 0)
|
||||
{
|
||||
SetMonData(pkmn, array[index], &data);
|
||||
gotRibbon = TRUE;
|
||||
}
|
||||
}
|
||||
if (gotRibbon)
|
||||
FlagSet(SYS_RIBBON_GET);
|
||||
}
|
||||
}
|
||||
@@ -4,13 +4,10 @@
|
||||
// The number 1103515245 comes from the example implementation of rand and srand
|
||||
// in the ISO C standard.
|
||||
|
||||
extern u32 gRngValue;
|
||||
extern u32 gRng2Value;
|
||||
|
||||
EWRAM_DATA static u8 sUnknown = 0;
|
||||
EWRAM_DATA static u32 sRandCount = 0;
|
||||
|
||||
u16 Random()
|
||||
u16 Random(void)
|
||||
{
|
||||
gRngValue = 1103515245 * gRngValue + 24691;
|
||||
sRandCount++;
|
||||
|
||||
268
src/safari_zone.c
Normal file
268
src/safari_zone.c
Normal file
@@ -0,0 +1,268 @@
|
||||
#include "global.h"
|
||||
#include "safari_zone.h"
|
||||
#include "event_data.h"
|
||||
#include "game_stat.h"
|
||||
#include "main.h"
|
||||
#include "battle.h"
|
||||
#include "string_util.h"
|
||||
|
||||
struct PokeblockFeeder
|
||||
{
|
||||
/*0x00*/ s16 x;
|
||||
/*0x02*/ s16 y;
|
||||
/*0x04*/ s8 mapNum;
|
||||
/*0x05*/ u8 stepCounter;
|
||||
/*0x08*/ struct Pokeblock pokeblock;
|
||||
};
|
||||
|
||||
#define NUM_POKEBLOCK_FEEDERS 10
|
||||
|
||||
extern u8 gBattleOutcome;
|
||||
extern void* gUnknown_03005DAC;
|
||||
|
||||
extern u8 gUnknown_082A4B8A[];
|
||||
extern u8 gUnknown_082A4B6F[];
|
||||
extern u8 gUnknown_082A4B4C[];
|
||||
extern u8 gUnknown_082A4B9B[];
|
||||
extern const u8* const gPokeblockNames[];
|
||||
|
||||
extern void sub_80EE44C(u8, u8);
|
||||
extern void IncrementGameStat(u8 index);
|
||||
extern void ScriptContext1_SetupScript(u8*);
|
||||
extern void ScriptContext2_RunNewScript(u8*);
|
||||
extern void c2_exit_to_overworld_2_switch(void);
|
||||
extern void c2_exit_to_overworld_1_continue_scripts_restart_music(void);
|
||||
extern void c2_load_new_map(void);
|
||||
extern void sub_80AF6F0(void);
|
||||
extern void script_env_2_set_ctx_paused(void);
|
||||
extern void warp_in(void);
|
||||
extern void GetXYCoordsOneStepInFrontOfPlayer(s16* x, s16* y);
|
||||
extern void PlayerGetDestCoords(s16* x, s16* y);
|
||||
|
||||
EWRAM_DATA u8 gNumSafariBalls = 0;
|
||||
EWRAM_DATA static u16 sSafariZoneStepCounter = 0;
|
||||
EWRAM_DATA static u8 sSafariZoneCaughtMons = 0;
|
||||
EWRAM_DATA static u8 sSafariZoneFleedMons = 0;
|
||||
EWRAM_DATA static struct PokeblockFeeder sPokeblockFeeders[NUM_POKEBLOCK_FEEDERS] = {0};
|
||||
|
||||
static void ClearAllPokeblockFeeders(void);
|
||||
static void DecrementFeederStepCounters(void);
|
||||
|
||||
bool32 GetSafariZoneFlag(void)
|
||||
{
|
||||
return FlagGet(SYS_SAFARI_MODE);
|
||||
}
|
||||
|
||||
void SetSafariZoneFlag(void)
|
||||
{
|
||||
FlagSet(SYS_SAFARI_MODE);
|
||||
}
|
||||
|
||||
void ResetSafariZoneFlag(void)
|
||||
{
|
||||
FlagReset(SYS_SAFARI_MODE);
|
||||
}
|
||||
|
||||
void EnterSafariMode(void)
|
||||
{
|
||||
IncrementGameStat(GAME_STAT_ENTERED_SAFARI_ZONE);
|
||||
SetSafariZoneFlag();
|
||||
ClearAllPokeblockFeeders();
|
||||
gNumSafariBalls = 30;
|
||||
sSafariZoneStepCounter = 500;
|
||||
sSafariZoneCaughtMons = 0;
|
||||
sSafariZoneFleedMons = 0;
|
||||
}
|
||||
|
||||
void ExitSafariMode(void)
|
||||
{
|
||||
sub_80EE44C(sSafariZoneCaughtMons, sSafariZoneFleedMons);
|
||||
ResetSafariZoneFlag();
|
||||
ClearAllPokeblockFeeders();
|
||||
gNumSafariBalls = 0;
|
||||
sSafariZoneStepCounter = 0;
|
||||
}
|
||||
|
||||
bool8 SafariZoneTakeStep(void)
|
||||
{
|
||||
if (GetSafariZoneFlag() == FALSE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
DecrementFeederStepCounters();
|
||||
sSafariZoneStepCounter--;
|
||||
if (sSafariZoneStepCounter == 0)
|
||||
{
|
||||
ScriptContext1_SetupScript(gUnknown_082A4B8A);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void SafariZoneRetirePrompt(void)
|
||||
{
|
||||
ScriptContext1_SetupScript(gUnknown_082A4B6F);
|
||||
}
|
||||
|
||||
void sub_80FC190(void)
|
||||
{
|
||||
sSafariZoneFleedMons += gBattleResults.field_1F;
|
||||
if (gBattleOutcome == BATTLE_CAUGHT)
|
||||
sSafariZoneCaughtMons++;
|
||||
if (gNumSafariBalls != 0)
|
||||
{
|
||||
SetMainCallback2(c2_exit_to_overworld_2_switch);
|
||||
}
|
||||
else if (gBattleOutcome == 8)
|
||||
{
|
||||
ScriptContext2_RunNewScript(gUnknown_082A4B4C);
|
||||
warp_in();
|
||||
gUnknown_03005DAC = sub_80AF6F0;
|
||||
SetMainCallback2(c2_load_new_map);
|
||||
}
|
||||
else if (gBattleOutcome == BATTLE_CAUGHT)
|
||||
{
|
||||
ScriptContext1_SetupScript(gUnknown_082A4B9B);
|
||||
script_env_2_set_ctx_paused();
|
||||
SetMainCallback2(c2_exit_to_overworld_1_continue_scripts_restart_music);
|
||||
}
|
||||
}
|
||||
|
||||
static void ClearPokeblockFeeder(u8 index)
|
||||
{
|
||||
memset(&sPokeblockFeeders[index], 0, sizeof(struct PokeblockFeeder));
|
||||
}
|
||||
|
||||
static void ClearAllPokeblockFeeders(void)
|
||||
{
|
||||
memset(sPokeblockFeeders, 0, sizeof(sPokeblockFeeders));
|
||||
}
|
||||
|
||||
static void GetPokeblockFeederInFront(void)
|
||||
{
|
||||
s16 x, y;
|
||||
u16 i;
|
||||
|
||||
GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
|
||||
|
||||
for (i = 0; i < NUM_POKEBLOCK_FEEDERS; i++)
|
||||
{
|
||||
if (gSaveBlock1Ptr->location.mapNum == sPokeblockFeeders[i].mapNum
|
||||
&& sPokeblockFeeders[i].x == x
|
||||
&& sPokeblockFeeders[i].y == y)
|
||||
{
|
||||
gScriptResult = i;
|
||||
StringCopy(gStringVar1, gPokeblockNames[sPokeblockFeeders[i].pokeblock.color]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
gScriptResult = -1;
|
||||
}
|
||||
|
||||
void GetPokeblockFeederWithinRange(void)
|
||||
{
|
||||
s16 x, y;
|
||||
u16 i;
|
||||
|
||||
PlayerGetDestCoords(&x, &y);
|
||||
|
||||
for (i = 0; i < NUM_POKEBLOCK_FEEDERS; i++)
|
||||
{
|
||||
if (gSaveBlock1Ptr->location.mapNum == sPokeblockFeeders[i].mapNum)
|
||||
{
|
||||
//Get absolute value of x and y distance from Pokeblock feeder on current map
|
||||
x -= sPokeblockFeeders[i].x;
|
||||
y -= sPokeblockFeeders[i].y;
|
||||
if (x < 0)
|
||||
x *= -1;
|
||||
if (y < 0)
|
||||
y *= -1;
|
||||
if ((x + y) <= 5)
|
||||
{
|
||||
gScriptResult = i;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gScriptResult = -1;
|
||||
}
|
||||
|
||||
// unused
|
||||
struct Pokeblock *SafariZoneGetPokeblockInFront(void)
|
||||
{
|
||||
GetPokeblockFeederInFront();
|
||||
|
||||
if (gScriptResult == 0xFFFF)
|
||||
return NULL;
|
||||
else
|
||||
return &sPokeblockFeeders[gScriptResult].pokeblock;
|
||||
}
|
||||
|
||||
struct Pokeblock *SafariZoneGetActivePokeblock(void)
|
||||
{
|
||||
GetPokeblockFeederWithinRange();
|
||||
|
||||
if (gScriptResult == 0xFFFF)
|
||||
return NULL;
|
||||
else
|
||||
return &sPokeblockFeeders[gScriptResult].pokeblock;
|
||||
}
|
||||
|
||||
void SafariZoneActivatePokeblockFeeder(u8 pkblId)
|
||||
{
|
||||
s16 x, y;
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < NUM_POKEBLOCK_FEEDERS; i++)
|
||||
{
|
||||
// Find free entry in sPokeblockFeeders
|
||||
if (sPokeblockFeeders[i].mapNum == 0
|
||||
&& sPokeblockFeeders[i].x == 0
|
||||
&& sPokeblockFeeders[i].y == 0)
|
||||
{
|
||||
// Initialize Pokeblock feeder
|
||||
GetXYCoordsOneStepInFrontOfPlayer(&x, &y);
|
||||
sPokeblockFeeders[i].mapNum = gSaveBlock1Ptr->location.mapNum;
|
||||
sPokeblockFeeders[i].pokeblock = gSaveBlock1Ptr->pokeblocks[pkblId];
|
||||
sPokeblockFeeders[i].stepCounter = 100;
|
||||
sPokeblockFeeders[i].x = x;
|
||||
sPokeblockFeeders[i].y = y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void DecrementFeederStepCounters(void)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
for (i = 0; i < NUM_POKEBLOCK_FEEDERS; i++)
|
||||
{
|
||||
if (sPokeblockFeeders[i].stepCounter != 0)
|
||||
{
|
||||
sPokeblockFeeders[i].stepCounter--;
|
||||
if (sPokeblockFeeders[i].stepCounter == 0)
|
||||
ClearPokeblockFeeder(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unused
|
||||
bool8 GetInFrontFeederPokeblockAndSteps(void)
|
||||
{
|
||||
GetPokeblockFeederInFront();
|
||||
|
||||
if (gScriptResult == 0xFFFF)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ConvertIntToDecimalStringN(gStringVar2,
|
||||
sPokeblockFeeders[gScriptResult].stepCounter,
|
||||
STR_CONV_MODE_LEADING_ZEROS, 3);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
extern struct SaveSectionOffsets gSaveSectionOffsets[0xE];
|
||||
extern struct SaveSectionLocation gRamSaveSectionLocations[0xE];
|
||||
extern void *gUnknown_03005D94;
|
||||
extern u8 gDecompressionBuffer[];
|
||||
extern u32 gFlashMemoryPresent;
|
||||
extern u16 gUnknown_03006294;
|
||||
@@ -593,7 +592,7 @@ void UpdateSaveAddresses(void)
|
||||
|
||||
for(i = 5; i < 14; i++)
|
||||
{
|
||||
gRamSaveSectionLocations[i].data = gUnknown_03005D94 + gSaveSectionOffsets[i].toAdd;
|
||||
gRamSaveSectionLocations[i].data = gPokemonStoragePtr + gSaveSectionOffsets[i].toAdd;
|
||||
gRamSaveSectionLocations[i].size = gSaveSectionOffsets[i].size;
|
||||
}
|
||||
}
|
||||
@@ -630,7 +629,7 @@ _081531AC:\n\
|
||||
bge _081531AC\n\
|
||||
movs r4, 0x5\n\
|
||||
ldr r1, =gRamSaveSectionLocations\n\
|
||||
ldr r5, =gUnknown_03005D94\n\
|
||||
ldr r5, =gPokemonStoragePtr\n\
|
||||
ldr r0, =gSaveSectionOffsets\n\
|
||||
adds r3, r1, 0\n\
|
||||
adds r3, 0x28\n\
|
||||
|
||||
231
src/start_menu.c
Normal file
231
src/start_menu.c
Normal file
@@ -0,0 +1,231 @@
|
||||
#include "global.h"
|
||||
#include "start_menu.h"
|
||||
#include "menu.h"
|
||||
#include "safari_zone.h"
|
||||
#include "event_data.h"
|
||||
#include "window.h"
|
||||
#include "string_util.h"
|
||||
#include "text.h"
|
||||
|
||||
// Menu actions
|
||||
enum
|
||||
{
|
||||
MENU_ACTION_POKEDEX,
|
||||
MENU_ACTION_POKEMON,
|
||||
MENU_ACTION_BAG,
|
||||
MENU_ACTION_POKENAV,
|
||||
MENU_ACTION_PLAYER,
|
||||
MENU_ACTION_SAVE,
|
||||
MENU_ACTION_OPTION,
|
||||
MENU_ACTION_EXIT,
|
||||
MENU_ACTION_RETIRE_SAFARI,
|
||||
MENU_ACTION_PLAYER_LINK,
|
||||
MENU_ACTION_REST_FRONTIER,
|
||||
MENU_ACTION_RETIRE_FRONTIER,
|
||||
MENU_ACTION_PYRAMID_BAG
|
||||
};
|
||||
|
||||
static void BuildStartMenuActions_LinkMode(void);
|
||||
static void BuildStartMenuActions_UnionRoom(void);
|
||||
static void BuildStartMenuActions_SafariZone(void);
|
||||
static void BuildStartMenuActions_BattlePike(void);
|
||||
static void BuildStartMenuActions_BattlePyramid(void);
|
||||
static void BuildStartMenuActions_MultiBattleRoom(void);
|
||||
static void BuildStartMenuActions_Normal(void);
|
||||
u8 StartMenu_PlayerName(void);
|
||||
|
||||
extern bool32 is_c1_link_related_active(void);
|
||||
extern bool32 InUnionRoom(void);
|
||||
extern bool8 InBattlePike(void);
|
||||
extern bool8 InBattlePyramid(void);
|
||||
extern bool8 InMultiBattleRoom(void);
|
||||
extern void sub_81973FC(u8 windowId, u8 a1);
|
||||
extern void sub_8198070(u8 windowId, u8 a1);
|
||||
|
||||
EWRAM_DATA u8 sSafariBallsWindowId = 0;
|
||||
EWRAM_DATA u8 sBattlePyramidFloorWindowId = 0;
|
||||
EWRAM_DATA u8 sStartMenuCursorPos = 0;
|
||||
EWRAM_DATA u8 sNumStartMenuActions = 0;
|
||||
EWRAM_DATA u8 sCurrentStartMenuActions[9] = {0};
|
||||
|
||||
void BuildStartMenuActions(void)
|
||||
{
|
||||
sNumStartMenuActions = 0;
|
||||
if (is_c1_link_related_active() == TRUE)
|
||||
BuildStartMenuActions_LinkMode();
|
||||
else if (InUnionRoom() == TRUE)
|
||||
BuildStartMenuActions_UnionRoom();
|
||||
else if (GetSafariZoneFlag() == TRUE)
|
||||
BuildStartMenuActions_SafariZone();
|
||||
else if (InBattlePike())
|
||||
BuildStartMenuActions_BattlePike();
|
||||
else if (InBattlePyramid())
|
||||
BuildStartMenuActions_BattlePyramid();
|
||||
else if (InMultiBattleRoom())
|
||||
BuildStartMenuActions_MultiBattleRoom();
|
||||
else
|
||||
BuildStartMenuActions_Normal();
|
||||
}
|
||||
|
||||
void AddStartMenuAction(u8 action)
|
||||
{
|
||||
AppendToList(sCurrentStartMenuActions, &sNumStartMenuActions, action);
|
||||
}
|
||||
|
||||
static void BuildStartMenuActions_Normal(void)
|
||||
{
|
||||
if (FlagGet(SYS_POKEDEX_GET) == TRUE)
|
||||
AddStartMenuAction(MENU_ACTION_POKEDEX);
|
||||
if (FlagGet(SYS_POKEMON_GET) == TRUE)
|
||||
AddStartMenuAction(MENU_ACTION_POKEMON);
|
||||
AddStartMenuAction(MENU_ACTION_BAG);
|
||||
if (FlagGet(SYS_POKENAV_GET) == TRUE)
|
||||
AddStartMenuAction(MENU_ACTION_POKENAV);
|
||||
AddStartMenuAction(MENU_ACTION_PLAYER);
|
||||
AddStartMenuAction(MENU_ACTION_SAVE);
|
||||
AddStartMenuAction(MENU_ACTION_OPTION);
|
||||
AddStartMenuAction(MENU_ACTION_EXIT);
|
||||
}
|
||||
|
||||
static void BuildStartMenuActions_SafariZone(void)
|
||||
{
|
||||
AddStartMenuAction(MENU_ACTION_RETIRE_SAFARI);
|
||||
AddStartMenuAction(MENU_ACTION_POKEDEX);
|
||||
AddStartMenuAction(MENU_ACTION_POKEMON);
|
||||
AddStartMenuAction(MENU_ACTION_BAG);
|
||||
AddStartMenuAction(MENU_ACTION_PLAYER);
|
||||
AddStartMenuAction(MENU_ACTION_OPTION);
|
||||
AddStartMenuAction(MENU_ACTION_EXIT);
|
||||
}
|
||||
|
||||
static void BuildStartMenuActions_LinkMode(void)
|
||||
{
|
||||
AddStartMenuAction(MENU_ACTION_POKEMON);
|
||||
AddStartMenuAction(MENU_ACTION_BAG);
|
||||
if (FlagGet(SYS_POKENAV_GET) == TRUE)
|
||||
AddStartMenuAction(MENU_ACTION_POKENAV);
|
||||
AddStartMenuAction(MENU_ACTION_PLAYER_LINK);
|
||||
AddStartMenuAction(MENU_ACTION_OPTION);
|
||||
AddStartMenuAction(MENU_ACTION_EXIT);
|
||||
}
|
||||
|
||||
static void BuildStartMenuActions_UnionRoom(void)
|
||||
{
|
||||
AddStartMenuAction(MENU_ACTION_POKEMON);
|
||||
AddStartMenuAction(MENU_ACTION_BAG);
|
||||
if (FlagGet(SYS_POKENAV_GET) == TRUE)
|
||||
AddStartMenuAction(MENU_ACTION_POKENAV);
|
||||
AddStartMenuAction(MENU_ACTION_PLAYER);
|
||||
AddStartMenuAction(MENU_ACTION_OPTION);
|
||||
AddStartMenuAction(MENU_ACTION_EXIT);
|
||||
}
|
||||
|
||||
static void BuildStartMenuActions_BattlePike(void)
|
||||
{
|
||||
AddStartMenuAction(MENU_ACTION_POKEDEX);
|
||||
AddStartMenuAction(MENU_ACTION_POKEMON);
|
||||
AddStartMenuAction(MENU_ACTION_PLAYER);
|
||||
AddStartMenuAction(MENU_ACTION_OPTION);
|
||||
AddStartMenuAction(MENU_ACTION_EXIT);
|
||||
}
|
||||
|
||||
static void BuildStartMenuActions_BattlePyramid(void)
|
||||
{
|
||||
AddStartMenuAction(MENU_ACTION_POKEMON);
|
||||
AddStartMenuAction(MENU_ACTION_PYRAMID_BAG);
|
||||
AddStartMenuAction(MENU_ACTION_PLAYER);
|
||||
AddStartMenuAction(MENU_ACTION_REST_FRONTIER);
|
||||
AddStartMenuAction(MENU_ACTION_RETIRE_FRONTIER);
|
||||
AddStartMenuAction(MENU_ACTION_OPTION);
|
||||
AddStartMenuAction(MENU_ACTION_EXIT);
|
||||
}
|
||||
|
||||
static void BuildStartMenuActions_MultiBattleRoom(void)
|
||||
{
|
||||
AddStartMenuAction(MENU_ACTION_POKEMON);
|
||||
AddStartMenuAction(MENU_ACTION_PLAYER);
|
||||
AddStartMenuAction(MENU_ACTION_OPTION);
|
||||
AddStartMenuAction(MENU_ACTION_EXIT);
|
||||
}
|
||||
|
||||
extern const struct WindowTemplate gSafariBallsWindowTemplate;
|
||||
extern const struct WindowTemplate gPyramidFloorWindowTemplate_1;
|
||||
extern const struct WindowTemplate gPyramidFloorWindowTemplate_2;
|
||||
extern const u8 gOtherText_SafariStock[];
|
||||
|
||||
void DisplaySafariBallsWindow(void)
|
||||
{
|
||||
sSafariBallsWindowId = AddWindow(&gSafariBallsWindowTemplate);
|
||||
PutWindowTilemap(sSafariBallsWindowId);
|
||||
sub_81973FC(sSafariBallsWindowId, 0);
|
||||
ConvertIntToDecimalStringN(gStringVar1, gNumSafariBalls, STR_CONV_MODE_RIGHT_ALIGN, 2);
|
||||
StringExpandPlaceholders(gStringVar4, gOtherText_SafariStock);
|
||||
PrintTextOnWindow(sSafariBallsWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL);
|
||||
CopyWindowToVram(sSafariBallsWindowId, 2);
|
||||
}
|
||||
|
||||
extern const u8* const gUnknown_08510510[];
|
||||
extern const u8 gOtherText_BattlePyramid_X[];
|
||||
|
||||
void DisplayPyramidFloorWindow(void)
|
||||
{
|
||||
// TODO: fix location
|
||||
if (*(u16*)(&gSaveBlock2Ptr->field_CAA[8]) == 7)
|
||||
sBattlePyramidFloorWindowId = AddWindow(&gPyramidFloorWindowTemplate_1);
|
||||
else
|
||||
sBattlePyramidFloorWindowId = AddWindow(&gPyramidFloorWindowTemplate_2);
|
||||
PutWindowTilemap(sBattlePyramidFloorWindowId);
|
||||
sub_81973FC(sBattlePyramidFloorWindowId, 0);
|
||||
StringCopy(gStringVar1, gUnknown_08510510[*(u16*)(&gSaveBlock2Ptr->field_CAA[8])]);
|
||||
StringExpandPlaceholders(gStringVar4, gOtherText_BattlePyramid_X);
|
||||
PrintTextOnWindow(sBattlePyramidFloorWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL);
|
||||
CopyWindowToVram(sBattlePyramidFloorWindowId, 2);
|
||||
}
|
||||
|
||||
void RemoveExtraStartMenuWindows(void)
|
||||
{
|
||||
if (GetSafariZoneFlag())
|
||||
{
|
||||
sub_8198070(sSafariBallsWindowId, 0);
|
||||
CopyWindowToVram(sSafariBallsWindowId, 2);
|
||||
RemoveWindow(sSafariBallsWindowId);
|
||||
}
|
||||
if (InBattlePyramid())
|
||||
{
|
||||
sub_8198070(sBattlePyramidFloorWindowId, 0);
|
||||
RemoveWindow(sBattlePyramidFloorWindowId);
|
||||
}
|
||||
}
|
||||
|
||||
extern const struct MenuAction sStartMenuItems[];
|
||||
|
||||
/*
|
||||
// Prints n menu items starting at *index
|
||||
static bool32 PrintStartMenuItemsMultistep(s16 *index, u32 n)
|
||||
{
|
||||
s8 _index = *index;
|
||||
|
||||
do
|
||||
{
|
||||
if (sStartMenuItems[sCurrentStartMenuActions[_index]].func == StartMenu_PlayerName)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} while (++_index > sNumStartMenuActions);
|
||||
|
||||
if (--n == 0)
|
||||
{
|
||||
*index = _index;
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
*index = _index;
|
||||
return TRUE;
|
||||
}
|
||||
}*/
|
||||
@@ -9,7 +9,7 @@ struct Task gTasks[NUM_TASKS];
|
||||
static void InsertTask(u8 newTaskId);
|
||||
static u8 FindFirstActiveTask();
|
||||
|
||||
void ResetTasks()
|
||||
void ResetTasks(void)
|
||||
{
|
||||
u8 i;
|
||||
|
||||
@@ -110,7 +110,7 @@ void DestroyTask(u8 taskId)
|
||||
}
|
||||
}
|
||||
|
||||
void RunTasks()
|
||||
void RunTasks(void)
|
||||
{
|
||||
u8 taskId = FindFirstActiveTask();
|
||||
|
||||
@@ -189,7 +189,7 @@ u8 FindTaskIdByFunc(TaskFunc func)
|
||||
return -1;
|
||||
}
|
||||
|
||||
u8 GetTaskCount()
|
||||
u8 GetTaskCount(void)
|
||||
{
|
||||
u8 i;
|
||||
u8 count = 0;
|
||||
|
||||
@@ -149,7 +149,7 @@ void DeactivateAllTextPrinters (void)
|
||||
gTextPrinters[printer].sub_union.sub.active = 0;
|
||||
}
|
||||
|
||||
u16 Print(u8 windowId, u8 fontId, u8 *str, u8 x, u8 y, u8 speed, void (*callback)(struct TextSubPrinter *, u16))
|
||||
u16 PrintTextOnWindow(u8 windowId, u8 fontId, u8 *str, u8 x, u8 y, u8 speed, void (*callback)(struct TextSubPrinter *, u16))
|
||||
{
|
||||
struct TextSubPrinter subPrinter;
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ bool16 InitWindows(struct WindowTemplate *templates)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u16 AddWindow(struct WindowTemplate *template)
|
||||
u16 AddWindow(const struct WindowTemplate *template)
|
||||
{
|
||||
u16 win;
|
||||
u8 bgLayer;
|
||||
|
||||
Reference in New Issue
Block a user