pokeemerald/src/safari_zone.c

269 lines
6.4 KiB
C
Raw Normal View History

2017-09-09 15:45:50 +02:00
#include "global.h"
#include "safari_zone.h"
#include "event_data.h"
2017-12-05 18:55:48 +01:00
#include "constants/game_stat.h"
2017-09-09 15:45:50 +02:00
#include "main.h"
#include "battle.h"
#include "string_util.h"
2017-12-11 16:52:28 +01:00
#include "pokeblock.h"
2017-09-09 15:45:50 +02:00
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* gFieldCallback;
2017-09-09 15:45:50 +02:00
2017-11-11 01:12:18 +01:00
extern u8 EventScript_2A4B8A[];
extern u8 EventScript_2A4B6F[];
extern u8 EventScript_2A4B4C[];
extern u8 EventScript_2A4B9B[];
2017-09-09 15:45:50 +02:00
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);
2017-09-10 23:05:23 +02:00
extern void ScriptContext1_Stop(void);
2017-09-09 15:45:50 +02:00
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)
{
2017-11-08 22:20:10 +01:00
return FlagGet(FLAG_SYS_SAFARI_MODE);
2017-09-09 15:45:50 +02:00
}
void SetSafariZoneFlag(void)
{
2017-11-08 22:20:10 +01:00
FlagSet(FLAG_SYS_SAFARI_MODE);
2017-09-09 15:45:50 +02:00
}
void ResetSafariZoneFlag(void)
{
2017-11-08 22:20:10 +01:00
FlagClear(FLAG_SYS_SAFARI_MODE);
2017-09-09 15:45:50 +02:00
}
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)
{
2017-11-11 01:12:18 +01:00
ScriptContext1_SetupScript(EventScript_2A4B8A);
2017-09-09 15:45:50 +02:00
return TRUE;
}
return FALSE;
}
void SafariZoneRetirePrompt(void)
{
2017-11-11 01:12:18 +01:00
ScriptContext1_SetupScript(EventScript_2A4B6F);
2017-09-09 15:45:50 +02:00
}
void sub_80FC190(void)
{
sSafariZoneFleedMons += gBattleResults.field_1F;
if (gBattleOutcome == BATTLE_CAUGHT)
sSafariZoneCaughtMons++;
if (gNumSafariBalls != 0)
{
SetMainCallback2(c2_exit_to_overworld_2_switch);
}
Decompile TV (#80) * ClearTVShowData * special_0x44 * DoTVShow (nonmatching because align) * DoTVShowBravoTrainerPokemonProfile * Update field names * DoTVShowBravoTrainerBattleTower * Renaming of struct fields * sub_80EBFF4 and UpdateTVScreensOnMap * SetTVMetatilesOnMap * Power buttons for the TV screens on the map * special_0x45 * sub_80EC18C * special_0x4a * ResetGabbyAndTy * GabbyAndTyBeforeInterview * GabbyAndTyAfterInterview * Through IsTVShowInSearchOfTrainersAiring * GabbyAndTyGetLastQuote * GabbyAndTyGetLastBattleTrivia * GabbyAndTySetScriptVarsToFieldObjectLocalIds * InterviewAfter; use TVShow as a precursor for making the individual show structs anonymous * Make TV structs anonymous within the union * Move the TV union to its own subheader * Move TV show enums to the global.tv.h subheader * Funcion renaming * Apply static attributes where able * PutPokemonTodayCaughtOnAir * sub_80EC8A4 * PutPokemonTodayFailedOnTheAir * sub_80EC9E8, sub_80ECA10 * sub_80ECA38 * sub_80ECB00 * Put3CheersForPokeblocksOnTheAir * PutFanClubSpecialOnTheAir * ContestLiveUpdates_BeforeInterview * Other before-interview Contest Live Updates functions * ContestLiveUpdates_BeforeInterview_5 * InterviewAfter_BravoTrainerPokemonProfile * BravoTrainerPokemonProfile_BeforeInterview1 * BravoTrainerPokemonProfile_BeforeInterview2 * Disassemble TV data * Decompile TV data * InterviewAfter_BravoTrainerBattleTowerProfile * SaveRecordedItemPurchasesForTVShow * PutNameRaterShowOnTheAir * StartMassOutbreak * PutLilycoveContestLadyShowOnTheAir * InterviewAfter_FanClubLetter * Rip TV strings * InterviewAfter_RecentHappenings * InterviewAfter_PkmnFanClubOpinions * sub_80ED718 * EndMassOutbreak * sub_80ED888 * sub_80ED8B4 * UpdateMassOutbreakTimeLeft * sub_80ED950 * PutFishingAdviceShowOnTheAir * through sub_80EDA80 * ewram and common syms are now fetched from the object files * BSS symbols are taken from the tv.o file * through sub_80EDC60 * sub_80EDCE8 * sub_80EDD78 * through sub_80EDE84 * nomatching sub_80EDE98 * sub_80EDFB4 * sub_80EE104 * sub_80EE104 * sub_80EE184 * sub_80EE2CC * sub_80EE35C * sub_80EE44C * sub_80EE4DC * sub_80EE5A4 * sub_80EE69C * sub_80EE72C * sub_80EE7C0 * sub_80EE818 * sub_80EE8C8 * sub_80EEA70 * sub_80EEB98 * sub_80EEBF4 * through sub_80EED60 * Functions relating to Pokemon News * sub_80EEF6C * GetPriceReduction * IsPriceDiscounted * sub_80EF120 * through sub_80EF370 * sub_80EF40C * HasMixableShowAlreadyBeenSpawnedWithPlayerID * TV_SortPurchasesByQuantity * FindActiveBroadcastByShowType_SetScriptResult * InterviewBefore * through sub_80EF88C * through sub_80EF93C * through sub_80EFA24 * through TV_BernoulliTrial * sub_80EFB58 * sub_80EFBA4 * sub_80EFBDC * through sub_80EFD98 * ChangePokemonNickname * ChangeBoxPokemonNickname * sub_80EFF9C * through player_id_to_dword * CheckForBigMovieOrEmergencyNewsOnTV * GetMomOrDadStringForTVMessage * sub_80F01E8 * sub_80F0358 * sub_80F049C * TV record mixing functions * sub_80F06D0 * sub_80F0708 nonmatching * through sub_80F0B24 * sub_80F0B64 * through sub_80F0C04 * sub_80F0C7C * sub_80F0D60 * sub_80F0E58 * sub_80F0E84 * through sub_80F0F24 * sub_80F0F64 * sub_80F1208 * sub_80F1254 * sub_80F1290 * sub_80F12A4 * sub_80F14F8 * DoTVShowTodaysSmartShopper * DoTVShowTheNameRaterShow * DoTVShowPokemonTodaySuccessfulCapture * DoTVShowPokemonTodayFailedCapture * DoTVShowPokemonFanClubLetter * DoTVShowRecentHappenings * DoTVShowPokemonFanClubOpinions * DoTVShowPokemonNewsMassOutbreak * DoTVShowPokemonContestLiveUpdates * DoTVShowPokemonBattleUpdate * DoTVShow3CheersForPokeblocks * DoTVShowInSearchOfTrainers * Label GabbyAndTyData fields; remove ddump comments from data/text/tv.inc * DoTVShowPokemonAngler * DoTVShowTheWorldOfMasters; update RAM symbols and field names * Decorate static functions * DoTVShowTodaysRivalTrainer; region map enums * TVDewfordTrendWatcherNetworkTextGroup * DoTVShowHoennTreasureInvestigators * DoTVShowFindThatGamer * DoTVShowBreakingNewsTV * DoTVShowSecretBaseVisit * DoTVShowPokemonLotterWinnerFlashReport * DoTVShowThePokemonBattleSeminar * DoTVShowTrainerFanClubSpecial, DoTVShowTrainerFanClub * DoTVShowSpotTheCuties * DoTVShowPokemonNewsBattleFrontier * DoTVShowWhatsNo1InHoennToday * Helpers for DoTVShowSecretBaseSecrets * DoTVShowSecretBaseSecrets * DoTVShowSafariFanClub * Finish decompilation of tv.s * Some renaming * Rename text group pointers * revoke statis; pokenews enums * Labels are number one * Label all TV struct fields * Make data/text/tv.inc more readable * Split data/text/tv.inc * Rename pokenews text pointers * Frontier Symbol constants; indicate static rodata objects with 's' prefix * Fix leading spaces/tabs F*** CLion sometimes * Fix inconsequential warning
2017-10-13 17:09:36 +02:00
else if (gBattleOutcome == BATTLE_SAFARI_OUT_OF_BALLS)
2017-09-09 15:45:50 +02:00
{
2017-11-11 01:12:18 +01:00
ScriptContext2_RunNewScript(EventScript_2A4B4C);
2017-09-09 15:45:50 +02:00
warp_in();
gFieldCallback = sub_80AF6F0;
2017-09-09 15:45:50 +02:00
SetMainCallback2(c2_load_new_map);
}
else if (gBattleOutcome == BATTLE_CAUGHT)
{
2017-11-11 01:12:18 +01:00
ScriptContext1_SetupScript(EventScript_2A4B9B);
2017-09-10 23:05:23 +02:00
ScriptContext1_Stop();
2017-09-09 15:45:50 +02:00
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));
}
2017-10-14 20:26:25 +02:00
void GetPokeblockFeederInFront(void)
2017-09-09 15:45:50 +02:00
{
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)
{
2017-11-11 01:12:18 +01:00
gSpecialVar_Result = i;
2017-09-09 15:45:50 +02:00
StringCopy(gStringVar1, gPokeblockNames[sPokeblockFeeders[i].pokeblock.color]);
return;
}
}
2017-11-11 01:12:18 +01:00
gSpecialVar_Result = -1;
2017-09-09 15:45:50 +02:00
}
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)
{
2017-11-11 01:12:18 +01:00
gSpecialVar_Result = i;
2017-09-09 15:45:50 +02:00
return;
}
}
}
2017-11-11 01:12:18 +01:00
gSpecialVar_Result = -1;
2017-09-09 15:45:50 +02:00
}
// unused
struct Pokeblock *SafariZoneGetPokeblockInFront(void)
{
GetPokeblockFeederInFront();
2017-11-11 01:12:18 +01:00
if (gSpecialVar_Result == 0xFFFF)
2017-09-09 15:45:50 +02:00
return NULL;
else
2017-11-11 01:12:18 +01:00
return &sPokeblockFeeders[gSpecialVar_Result].pokeblock;
2017-09-09 15:45:50 +02:00
}
struct Pokeblock *SafariZoneGetActivePokeblock(void)
{
GetPokeblockFeederWithinRange();
2017-11-11 01:12:18 +01:00
if (gSpecialVar_Result == 0xFFFF)
2017-09-09 15:45:50 +02:00
return NULL;
else
2017-11-11 01:12:18 +01:00
return &sPokeblockFeeders[gSpecialVar_Result].pokeblock;
2017-09-09 15:45:50 +02:00
}
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();
2017-11-11 01:12:18 +01:00
if (gSpecialVar_Result == 0xFFFF)
2017-09-09 15:45:50 +02:00
{
return FALSE;
}
ConvertIntToDecimalStringN(gStringVar2,
2017-11-11 01:12:18 +01:00
sPokeblockFeeders[gSpecialVar_Result].stepCounter,
2017-09-09 15:45:50 +02:00
STR_CONV_MODE_LEADING_ZEROS, 3);
return TRUE;
}