tumbledemerald-legacy/src/safari_zone.c

258 lines
6.2 KiB
C

#include "global.h"
#include "battle.h"
#include "event_data.h"
#include "field_player_avatar.h"
#include "overworld.h"
#include "main.h"
#include "pokeblock.h"
#include "safari_zone.h"
#include "script.h"
#include "string_util.h"
#include "tv.h"
#include "constants/game_stat.h"
#include "field_screen_effect.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 const u8 SafariZone_EventScript_TimesUp[];
extern const u8 SafariZone_EventScript_RetirePrompt[];
extern const u8 SafariZone_EventScript_OutOfBallsMidBattle[];
extern const u8 SafariZone_EventScript_OutOfBalls[];
EWRAM_DATA u8 gNumSafariBalls = 0;
EWRAM_DATA static u16 sSafariZoneStepCounter = 0;
EWRAM_DATA static u8 sSafariZoneCaughtMons = 0;
EWRAM_DATA static u8 sSafariZonePkblkUses = 0;
EWRAM_DATA static struct PokeblockFeeder sPokeblockFeeders[NUM_POKEBLOCK_FEEDERS] = {0};
static void ClearAllPokeblockFeeders(void);
static void DecrementFeederStepCounters(void);
bool32 GetSafariZoneFlag(void)
{
return FlagGet(FLAG_SYS_SAFARI_MODE);
}
void SetSafariZoneFlag(void)
{
FlagSet(FLAG_SYS_SAFARI_MODE);
}
void ResetSafariZoneFlag(void)
{
FlagClear(FLAG_SYS_SAFARI_MODE);
}
void EnterSafariMode(void)
{
IncrementGameStat(GAME_STAT_ENTERED_SAFARI_ZONE);
SetSafariZoneFlag();
ClearAllPokeblockFeeders();
gNumSafariBalls = 30;
sSafariZoneStepCounter = 500;
sSafariZoneCaughtMons = 0;
sSafariZonePkblkUses = 0;
}
void ExitSafariMode(void)
{
TryPutSafariFanClubOnAir(sSafariZoneCaughtMons, sSafariZonePkblkUses);
ResetSafariZoneFlag();
ClearAllPokeblockFeeders();
gNumSafariBalls = 0;
sSafariZoneStepCounter = 0;
}
bool8 SafariZoneTakeStep(void)
{
if (GetSafariZoneFlag() == FALSE)
{
return FALSE;
}
DecrementFeederStepCounters();
sSafariZoneStepCounter--;
if (sSafariZoneStepCounter == 0)
{
ScriptContext1_SetupScript(SafariZone_EventScript_TimesUp);
return TRUE;
}
return FALSE;
}
void SafariZoneRetirePrompt(void)
{
ScriptContext1_SetupScript(SafariZone_EventScript_RetirePrompt);
}
void CB2_EndSafariBattle(void)
{
sSafariZonePkblkUses += gBattleResults.pokeblockThrows;
if (gBattleOutcome == B_OUTCOME_CAUGHT)
sSafariZoneCaughtMons++;
if (gNumSafariBalls != 0)
{
SetMainCallback2(CB2_ReturnToField);
}
else if (gBattleOutcome == B_OUTCOME_NO_SAFARI_BALLS)
{
ScriptContext2_RunNewScript(SafariZone_EventScript_OutOfBallsMidBattle);
WarpIntoMap();
gFieldCallback = FieldCB_ReturnToFieldNoScriptCheckMusic;
SetMainCallback2(CB2_LoadMap);
}
else if (gBattleOutcome == B_OUTCOME_CAUGHT)
{
ScriptContext1_SetupScript(SafariZone_EventScript_OutOfBalls);
ScriptContext1_Stop();
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
}
}
static void ClearPokeblockFeeder(u8 index)
{
memset(&sPokeblockFeeders[index], 0, sizeof(struct PokeblockFeeder));
}
static void ClearAllPokeblockFeeders(void)
{
memset(sPokeblockFeeders, 0, sizeof(sPokeblockFeeders));
}
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)
{
gSpecialVar_Result = i;
StringCopy(gStringVar1, gPokeblockNames[sPokeblockFeeders[i].pokeblock.color]);
return;
}
}
gSpecialVar_Result = -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)
{
gSpecialVar_Result = i;
return;
}
}
}
gSpecialVar_Result = -1;
}
// unused
struct Pokeblock *SafariZoneGetPokeblockInFront(void)
{
GetPokeblockFeederInFront();
if (gSpecialVar_Result == 0xFFFF)
return NULL;
else
return &sPokeblockFeeders[gSpecialVar_Result].pokeblock;
}
struct Pokeblock *SafariZoneGetActivePokeblock(void)
{
GetPokeblockFeederWithinRange();
if (gSpecialVar_Result == 0xFFFF)
return NULL;
else
return &sPokeblockFeeders[gSpecialVar_Result].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 (gSpecialVar_Result == 0xFFFF)
{
return FALSE;
}
ConvertIntToDecimalStringN(gStringVar2,
sPokeblockFeeders[gSpecialVar_Result].stepCounter,
STR_CONV_MODE_LEADING_ZEROS, 3);
return TRUE;
}