diff options
author | PikalaxALT <PikalaxALT@gmail.com> | 2020-04-06 17:58:24 -0400 |
---|---|---|
committer | PikalaxALT <PikalaxALT@gmail.com> | 2020-04-06 17:58:24 -0400 |
commit | c78101535b72b39cb58295e019c36d2de6b2c1da (patch) | |
tree | 9d2f35ffda417ae6d630b2a4b96b03ec922f7030 /src/trainer_fan_club.c | |
parent | a622448029e7849361d2aabcd2138ed0de207dd1 (diff) |
Split quest_log.c
Diffstat (limited to 'src/trainer_fan_club.c')
-rw-r--r-- | src/trainer_fan_club.c | 359 |
1 files changed, 359 insertions, 0 deletions
diff --git a/src/trainer_fan_club.c b/src/trainer_fan_club.c new file mode 100644 index 000000000..9040d3405 --- /dev/null +++ b/src/trainer_fan_club.c @@ -0,0 +1,359 @@ +#include "global.h" +#include "gflib.h" +#include "battle.h" +#include "event_data.h" +#include "event_scripts.h" +#include "random.h" +#include "constants/vars.h" +#include "constants/flags.h" + +struct TrainerFanClub +{ + u8 timer:7; + u8 gotInitialFans:1; + u8 fanFlags; +}; + +#define TRAINER_FAN_CLUB ((struct TrainerFanClub *)GetVarPointer(VAR_FANCLUB_FAN_COUNTER)) + +#define GET_TRAINER_FAN_CLUB_FLAG(flag) (fanClub->fanFlags >> (flag) & 1) +#define SET_TRAINER_FAN_CLUB_FLAG(flag) (fanClub->fanFlags |= 1 << (flag)) +#define FLIP_TRAINER_FAN_CLUB_FLAG(flag)(fanClub->fanFlags ^= 1 << (flag)) + +#define FANCLUB_MEMBER1 0 +#define FANCLUB_MEMBER2 1 +#define FANCLUB_MEMBER3 2 +#define FANCLUB_MEMBER4 3 +#define FANCLUB_MEMBER5 4 +#define FANCLUB_MEMBER6 5 +#define FANCLUB_MEMBER7 6 +#define FANCLUB_MEMBER8 7 + +#define NUM_TRAINER_FAN_CLUB_MEMBERS 8 + +static void TryLoseFansFromPlayTimeAfterLinkBattle(struct TrainerFanClub *); +static void UpdateTrainerFanClubGameClear(struct TrainerFanClub *); +static u8 PlayerGainRandomTrainerFan(struct TrainerFanClub *); +static u16 GetNumFansOfPlayerInTrainerFanClub(struct TrainerFanClub *); +static void TryLoseFansFromPlayTime(struct TrainerFanClub *); +static bool16 IsFanClubMemberFanOfPlayer(struct TrainerFanClub *); +static void SetInitialFansOfPlayer(struct TrainerFanClub *); +static void BufferFanClubTrainerName(struct LinkBattleRecords *, u8, u8); +static void UpdateTrainerFansAfterLinkBattle(struct TrainerFanClub *); +static bool8 DidPlayerGetFirstFans(struct TrainerFanClub * ); +static void SetPlayerGotFirstFans(struct TrainerFanClub *); + +void ResetTrainerFanClub(void) +{ + VarSet(VAR_FANCLUB_FAN_COUNTER, 0); + VarSet(VAR_FANCLUB_LOSE_FAN_TIMER, 0); +} + +void Script_TryLoseFansFromPlayTimeAfterLinkBattle(void) +{ + TryLoseFansFromPlayTimeAfterLinkBattle(TRAINER_FAN_CLUB); +} + +static void TryLoseFansFromPlayTimeAfterLinkBattle(struct TrainerFanClub *fanClub) +{ + if (DidPlayerGetFirstFans(fanClub)) + { + TryLoseFansFromPlayTime(fanClub); + VarSet(VAR_FANCLUB_LOSE_FAN_TIMER, gSaveBlock2Ptr->playTimeHours); + } +} + +void Script_UpdateTrainerFanClubGameClear(void) +{ + UpdateTrainerFanClubGameClear(TRAINER_FAN_CLUB); +} + +static void UpdateTrainerFanClubGameClear(struct TrainerFanClub *fanClub) +{ + if (!fanClub->gotInitialFans) + { + SetPlayerGotFirstFans(fanClub); + SetInitialFansOfPlayer(fanClub); + VarSet(VAR_FANCLUB_LOSE_FAN_TIMER, gSaveBlock2Ptr->playTimeHours); + FlagClear(FLAG_HIDE_SAFFRON_FAN_CLUB_BLACKBELT); + FlagClear(FLAG_HIDE_SAFFRON_FAN_CLUB_ROCKER); + FlagClear(FLAG_HIDE_SAFFRON_FAN_CLUB_WOMAN); + FlagClear(FLAG_HIDE_SAFFRON_FAN_CLUB_BEAUTY); + VarSet(VAR_MAP_SCENE_SAFFRON_CITY_POKEMON_TRAINER_FAN_CLUB, 1); + } +} + +ALIGNED(4) const u8 sCounterIncrements[] = {2, 1, 2, 1}; + +static u8 TryGainNewFanFromCounter(struct TrainerFanClub *fanClub, u8 a1) +{ + if (VarGet(VAR_MAP_SCENE_SAFFRON_CITY_POKEMON_TRAINER_FAN_CLUB) == 2) + { + if (fanClub->timer + sCounterIncrements[a1] >= 20) + { + if (GetNumFansOfPlayerInTrainerFanClub(fanClub) < 3) + { + PlayerGainRandomTrainerFan(fanClub); + fanClub->timer = 0; + } + else + fanClub->timer = 20; + } + else + fanClub->timer += sCounterIncrements[a1]; + } + + return fanClub->timer; +} + + +static u8 PlayerGainRandomTrainerFan(struct TrainerFanClub *fanClub) +{ + static const u8 sFanClubMemberIds[] = { + FANCLUB_MEMBER2, + FANCLUB_MEMBER4, + FANCLUB_MEMBER6, + FANCLUB_MEMBER1, + FANCLUB_MEMBER8, + FANCLUB_MEMBER7, + FANCLUB_MEMBER5, + FANCLUB_MEMBER3 + }; + + u8 i; + u8 idx = 0; + + for (i = 0; i < NUM_TRAINER_FAN_CLUB_MEMBERS; i++) + { + if (!(GET_TRAINER_FAN_CLUB_FLAG(sFanClubMemberIds[i]))) + { + idx = i; + if (Random() % 2) + { + SET_TRAINER_FAN_CLUB_FLAG(sFanClubMemberIds[i]); + return sFanClubMemberIds[i]; + } + } + } + + SET_TRAINER_FAN_CLUB_FLAG(sFanClubMemberIds[idx]); + return sFanClubMemberIds[idx]; +} + +static u8 PlayerLoseRandomTrainerFan(struct TrainerFanClub *fanClub) +{ + static const u8 sFanClubMemberIds[] = + { + FANCLUB_MEMBER6, + FANCLUB_MEMBER7, + FANCLUB_MEMBER4, + FANCLUB_MEMBER8, + FANCLUB_MEMBER5, + FANCLUB_MEMBER2, + FANCLUB_MEMBER1, + FANCLUB_MEMBER3 + }; + + u8 i; + u8 idx = 0; + + if (GetNumFansOfPlayerInTrainerFanClub(fanClub) == 1) + return 0; + + for (i = 0; i < NUM_TRAINER_FAN_CLUB_MEMBERS; i++) + { + if (GET_TRAINER_FAN_CLUB_FLAG(sFanClubMemberIds[i])) + { + idx = i; + if (Random() % 2) + { + FLIP_TRAINER_FAN_CLUB_FLAG(sFanClubMemberIds[i]); + return sFanClubMemberIds[i]; + } + } + } + + if (GET_TRAINER_FAN_CLUB_FLAG(sFanClubMemberIds[idx])) + FLIP_TRAINER_FAN_CLUB_FLAG(sFanClubMemberIds[idx]); + + return sFanClubMemberIds[idx]; +} + +u16 Script_GetNumFansOfPlayerInTrainerFanClub(void) +{ + return GetNumFansOfPlayerInTrainerFanClub(TRAINER_FAN_CLUB); +} + +static u16 GetNumFansOfPlayerInTrainerFanClub(struct TrainerFanClub *fanClub) +{ + u8 count = 0; + u8 i; + + for (i = 0; i < NUM_TRAINER_FAN_CLUB_MEMBERS; i++) + { + if (GET_TRAINER_FAN_CLUB_FLAG(i)) + count++; + } + + return count; +} + +void Script_TryLoseFansFromPlayTime(void) +{ + TryLoseFansFromPlayTime(TRAINER_FAN_CLUB); +} + +static void TryLoseFansFromPlayTime(struct TrainerFanClub *fanClub) +{ + u8 i = 0; + u16 timer; + + if (gSaveBlock2Ptr->playTimeHours < 999) + { + while (1) + { + if (GetNumFansOfPlayerInTrainerFanClub(fanClub) < 5) + { + VarSet(VAR_FANCLUB_LOSE_FAN_TIMER, gSaveBlock2Ptr->playTimeHours); + break; + } + if (i == NUM_TRAINER_FAN_CLUB_MEMBERS) + break; + + timer = VarGet(VAR_FANCLUB_LOSE_FAN_TIMER); + if (gSaveBlock2Ptr->playTimeHours - timer < 12) + break; + + PlayerLoseRandomTrainerFan(fanClub); + timer = VarGet(VAR_FANCLUB_LOSE_FAN_TIMER); + VarSet(VAR_FANCLUB_LOSE_FAN_TIMER, timer + 12); + i++; + } + } +} + +bool16 Script_IsFanClubMemberFanOfPlayer(void) +{ + return IsFanClubMemberFanOfPlayer(TRAINER_FAN_CLUB); +} + +static bool16 IsFanClubMemberFanOfPlayer(struct TrainerFanClub *fanClub) +{ + return GET_TRAINER_FAN_CLUB_FLAG(gSpecialVar_0x8004); +} + +static void SetInitialFansOfPlayer(struct TrainerFanClub *fanClub) +{ + SET_TRAINER_FAN_CLUB_FLAG(FANCLUB_MEMBER1); + SET_TRAINER_FAN_CLUB_FLAG(FANCLUB_MEMBER2); + SET_TRAINER_FAN_CLUB_FLAG(FANCLUB_MEMBER3); +} + +void Script_BufferFanClubTrainerName(void) +{ + u8 whichLinkTrainer = 0; + u8 whichNPCTrainer = 0; + + switch (gSpecialVar_0x8004) + { + case FANCLUB_MEMBER1: + whichNPCTrainer = 0; + whichLinkTrainer = 0; + break; + case FANCLUB_MEMBER2: + case FANCLUB_MEMBER3: + case FANCLUB_MEMBER4: + case FANCLUB_MEMBER8: + break; + case FANCLUB_MEMBER5: + whichNPCTrainer = 1; + whichLinkTrainer = 0; + break; + case FANCLUB_MEMBER6: + whichNPCTrainer = 0; + whichLinkTrainer = 1; + break; + case FANCLUB_MEMBER7: + whichNPCTrainer = 2; + whichLinkTrainer = 1; + break; + } + BufferFanClubTrainerName(&gSaveBlock2Ptr->linkBattleRecords, whichLinkTrainer, whichNPCTrainer); +} + +static void BufferFanClubTrainerName(struct LinkBattleRecords *linkRecords, u8 whichLinkTrainer, u8 whichNPCTrainer) +{ + u8 *str; + const u8 *linkTrainerName = linkRecords->entries[whichLinkTrainer].name; + if (linkTrainerName[0] == EOS) + { + switch (whichNPCTrainer) + { + case 0: + StringCopy(gStringVar1, gSaveBlock1Ptr->rivalName); + break; + case 1: + StringCopy(gStringVar1, gText_LtSurge); + break; + case 2: + StringCopy(gStringVar1, gText_Koga); + break; + default: + StringCopy(gStringVar1, gSaveBlock1Ptr->rivalName); + break; + } + } + else + { + str = gStringVar1; + StringCopyN(str, linkTrainerName, PLAYER_NAME_LENGTH); + str[PLAYER_NAME_LENGTH] = EOS; + if ( str[0] == EXT_CTRL_CODE_BEGIN + && str[1] == EXT_CTRL_CODE_JPN) + { + str += 2; + while (*str != EOS) + str++; + *str++ = EXT_CTRL_CODE_BEGIN; + *str++ = EXT_CTRL_CODE_ENG; + *str++ = EOS; + } + } +} + +void Special_UpdateTrainerFansAfterLinkBattle(void) +{ + UpdateTrainerFansAfterLinkBattle(TRAINER_FAN_CLUB); +} + +static void UpdateTrainerFansAfterLinkBattle(struct TrainerFanClub *fanClub) +{ + if (VarGet(VAR_MAP_SCENE_SAFFRON_CITY_POKEMON_TRAINER_FAN_CLUB) == 2) + { + TryLoseFansFromPlayTimeAfterLinkBattle(fanClub); + if (gBattleOutcome == B_OUTCOME_WON) + PlayerGainRandomTrainerFan(fanClub); + else + PlayerLoseRandomTrainerFan(fanClub); + } +} + +static bool8 DidPlayerGetFirstFans(struct TrainerFanClub *fanClub) +{ + return fanClub->gotInitialFans; +} + +void Script_SetPlayerGotFirstFans(void) +{ + SetPlayerGotFirstFans(TRAINER_FAN_CLUB); +} + +static void SetPlayerGotFirstFans(struct TrainerFanClub *fanClub) +{ + fanClub->gotInitialFans = TRUE; +} + +u8 Script_TryGainNewFanFromCounter(void) +{ + return TryGainNewFanFromCounter(TRAINER_FAN_CLUB, gSpecialVar_0x8004); +} |