Files
Pokemon-Firered/src/trainer_fan_club.c
T

358 lines
9.5 KiB
C

#include "global.h"
#include "gflib.h"
#include "battle.h"
#include "event_data.h"
#include "event_scripts.h"
#include "random.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);
}