mirror of
https://github.com/Ninjdai1/pokeemerald.git
synced 2024-12-26 19:54:21 +01:00
ada29313de
Co-authored-by: DizzyEggg <jajkodizzy@wp.pl>
262 lines
7.0 KiB
C
262 lines
7.0 KiB
C
#include "global.h"
|
|
#include "battle.h"
|
|
#include "battle_gfx_sfx_util.h"
|
|
#include "berry.h"
|
|
#include "data.h"
|
|
#include "daycare.h"
|
|
#include "decompress.h"
|
|
#include "event_data.h"
|
|
#include "international_string_util.h"
|
|
#include "link.h"
|
|
#include "link_rfu.h"
|
|
#include "main.h"
|
|
#include "menu.h"
|
|
#include "overworld.h"
|
|
#include "palette.h"
|
|
#include "party_menu.h"
|
|
#include "pokedex.h"
|
|
#include "pokemon.h"
|
|
#include "random.h"
|
|
#include "script.h"
|
|
#include "sprite.h"
|
|
#include "string_util.h"
|
|
#include "tv.h"
|
|
#include "constants/items.h"
|
|
#include "constants/battle_frontier.h"
|
|
|
|
static void CB2_ReturnFromChooseHalfParty(void);
|
|
static void CB2_ReturnFromChooseBattleFrontierParty(void);
|
|
|
|
void HealPlayerParty(void)
|
|
{
|
|
u8 i, j;
|
|
u8 ppBonuses;
|
|
u8 arg[4];
|
|
|
|
// restore HP.
|
|
for(i = 0; i < gPlayerPartyCount; i++)
|
|
{
|
|
u16 maxHP = GetMonData(&gPlayerParty[i], MON_DATA_MAX_HP);
|
|
arg[0] = maxHP;
|
|
arg[1] = maxHP >> 8;
|
|
SetMonData(&gPlayerParty[i], MON_DATA_HP, arg);
|
|
ppBonuses = GetMonData(&gPlayerParty[i], MON_DATA_PP_BONUSES);
|
|
|
|
// restore PP.
|
|
for(j = 0; j < MAX_MON_MOVES; j++)
|
|
{
|
|
arg[0] = CalculatePPWithBonus(GetMonData(&gPlayerParty[i], MON_DATA_MOVE1 + j), ppBonuses, j);
|
|
SetMonData(&gPlayerParty[i], MON_DATA_PP1 + j, arg);
|
|
}
|
|
|
|
// since status is u32, the four 0 assignments here are probably for safety to prevent undefined data from reaching SetMonData.
|
|
arg[0] = 0;
|
|
arg[1] = 0;
|
|
arg[2] = 0;
|
|
arg[3] = 0;
|
|
SetMonData(&gPlayerParty[i], MON_DATA_STATUS, arg);
|
|
}
|
|
}
|
|
|
|
u8 ScriptGiveMon(u16 species, u8 level, u16 item, u32 unused1, u32 unused2, u8 unused3)
|
|
{
|
|
u16 nationalDexNum;
|
|
int sentToPc;
|
|
u8 heldItem[2];
|
|
struct Pokemon mon;
|
|
u16 targetSpecies;
|
|
|
|
CreateMon(&mon, species, level, USE_RANDOM_IVS, FALSE, 0, OT_ID_PLAYER_ID, 0);
|
|
heldItem[0] = item;
|
|
heldItem[1] = item >> 8;
|
|
SetMonData(&mon, MON_DATA_HELD_ITEM, heldItem);
|
|
|
|
// In case a mon with a form changing item is given. Eg: SPECIES_ARCEUS with ITEM_SPLASH_PLATE will transform into SPECIES_ARCEUS_WATER upon gifted.
|
|
targetSpecies = GetFormChangeTargetSpecies(&mon, FORM_CHANGE_ITEM_HOLD, 0);
|
|
if (targetSpecies != SPECIES_NONE)
|
|
{
|
|
SetMonData(&mon, MON_DATA_SPECIES, &targetSpecies);
|
|
CalculateMonStats(&mon);
|
|
}
|
|
|
|
sentToPc = GiveMonToPlayer(&mon);
|
|
nationalDexNum = SpeciesToNationalPokedexNum(species);
|
|
|
|
// Don't set Pokédex flag for MON_CANT_GIVE
|
|
switch(sentToPc)
|
|
{
|
|
case MON_GIVEN_TO_PARTY:
|
|
case MON_GIVEN_TO_PC:
|
|
GetSetPokedexFlag(nationalDexNum, FLAG_SET_SEEN);
|
|
GetSetPokedexFlag(nationalDexNum, FLAG_SET_CAUGHT);
|
|
break;
|
|
}
|
|
return sentToPc;
|
|
}
|
|
|
|
u8 ScriptGiveEgg(u16 species)
|
|
{
|
|
struct Pokemon mon;
|
|
u8 isEgg;
|
|
|
|
CreateEgg(&mon, species, TRUE);
|
|
isEgg = TRUE;
|
|
SetMonData(&mon, MON_DATA_IS_EGG, &isEgg);
|
|
|
|
return GiveMonToPlayer(&mon);
|
|
}
|
|
|
|
void HasEnoughMonsForDoubleBattle(void)
|
|
{
|
|
switch (GetMonsStateToDoubles())
|
|
{
|
|
case PLAYER_HAS_TWO_USABLE_MONS:
|
|
gSpecialVar_Result = PLAYER_HAS_TWO_USABLE_MONS;
|
|
break;
|
|
case PLAYER_HAS_ONE_MON:
|
|
gSpecialVar_Result = PLAYER_HAS_ONE_MON;
|
|
break;
|
|
case PLAYER_HAS_ONE_USABLE_MON:
|
|
gSpecialVar_Result = PLAYER_HAS_ONE_USABLE_MON;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static bool8 CheckPartyMonHasHeldItem(u16 item)
|
|
{
|
|
int i;
|
|
|
|
for(i = 0; i < PARTY_SIZE; i++)
|
|
{
|
|
u16 species = GetMonData(&gPlayerParty[i], MON_DATA_SPECIES_OR_EGG);
|
|
if (species != SPECIES_NONE && species != SPECIES_EGG && GetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM) == item)
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
bool8 DoesPartyHaveEnigmaBerry(void)
|
|
{
|
|
bool8 hasItem = CheckPartyMonHasHeldItem(ITEM_ENIGMA_BERRY_E_READER);
|
|
if (hasItem == TRUE)
|
|
GetBerryNameByBerryType(ItemIdToBerryType(ITEM_ENIGMA_BERRY_E_READER), gStringVar1);
|
|
|
|
return hasItem;
|
|
}
|
|
|
|
void CreateScriptedWildMon(u16 species, u8 level, u16 item)
|
|
{
|
|
u8 heldItem[2];
|
|
|
|
ZeroEnemyPartyMons();
|
|
CreateMon(&gEnemyParty[0], species, level, USE_RANDOM_IVS, 0, 0, OT_ID_PLAYER_ID, 0);
|
|
if (item)
|
|
{
|
|
heldItem[0] = item;
|
|
heldItem[1] = item >> 8;
|
|
SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, heldItem);
|
|
}
|
|
}
|
|
void CreateScriptedDoubleWildMon(u16 species1, u8 level1, u16 item1, u16 species2, u8 level2, u16 item2)
|
|
{
|
|
u8 heldItem1[2];
|
|
u8 heldItem2[2];
|
|
|
|
ZeroEnemyPartyMons();
|
|
|
|
CreateMon(&gEnemyParty[0], species1, level1, 32, 0, 0, OT_ID_PLAYER_ID, 0);
|
|
if (item1)
|
|
{
|
|
heldItem1[0] = item1;
|
|
heldItem1[1] = item1 >> 8;
|
|
SetMonData(&gEnemyParty[0], MON_DATA_HELD_ITEM, heldItem1);
|
|
}
|
|
|
|
CreateMon(&gEnemyParty[1], species2, level2, 32, 0, 0, OT_ID_PLAYER_ID, 0);
|
|
if (item2)
|
|
{
|
|
heldItem2[0] = item2;
|
|
heldItem2[1] = item2 >> 8;
|
|
SetMonData(&gEnemyParty[1], MON_DATA_HELD_ITEM, heldItem2);
|
|
}
|
|
}
|
|
|
|
void ScriptSetMonMoveSlot(u8 monIndex, u16 move, u8 slot)
|
|
{
|
|
// Allows monIndex to go out of bounds of gPlayerParty. Doesn't occur in vanilla
|
|
#ifdef BUGFIX
|
|
if (monIndex >= PARTY_SIZE)
|
|
#else
|
|
if (monIndex > PARTY_SIZE)
|
|
#endif
|
|
monIndex = gPlayerPartyCount - 1;
|
|
|
|
SetMonMoveSlot(&gPlayerParty[monIndex], move, slot);
|
|
}
|
|
|
|
// Note: When control returns to the event script, gSpecialVar_Result will be
|
|
// TRUE if the party selection was successful.
|
|
void ChooseHalfPartyForBattle(void)
|
|
{
|
|
gMain.savedCallback = CB2_ReturnFromChooseHalfParty;
|
|
VarSet(VAR_FRONTIER_FACILITY, FACILITY_MULTI_OR_EREADER);
|
|
InitChooseHalfPartyForBattle(0);
|
|
}
|
|
|
|
static void CB2_ReturnFromChooseHalfParty(void)
|
|
{
|
|
switch (gSelectedOrderFromParty[0])
|
|
{
|
|
case 0:
|
|
gSpecialVar_Result = FALSE;
|
|
break;
|
|
default:
|
|
gSpecialVar_Result = TRUE;
|
|
break;
|
|
}
|
|
|
|
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
|
|
}
|
|
|
|
void ChoosePartyForBattleFrontier(void)
|
|
{
|
|
gMain.savedCallback = CB2_ReturnFromChooseBattleFrontierParty;
|
|
InitChooseHalfPartyForBattle(gSpecialVar_0x8004 + 1);
|
|
}
|
|
|
|
static void CB2_ReturnFromChooseBattleFrontierParty(void)
|
|
{
|
|
switch (gSelectedOrderFromParty[0])
|
|
{
|
|
case 0:
|
|
gSpecialVar_Result = FALSE;
|
|
break;
|
|
default:
|
|
gSpecialVar_Result = TRUE;
|
|
break;
|
|
}
|
|
|
|
SetMainCallback2(CB2_ReturnToFieldContinueScriptPlayMapMusic);
|
|
}
|
|
|
|
void ReducePlayerPartyToSelectedMons(void)
|
|
{
|
|
struct Pokemon party[MAX_FRONTIER_PARTY_SIZE];
|
|
int i;
|
|
|
|
CpuFill32(0, party, sizeof party);
|
|
|
|
// copy the selected pokemon according to the order.
|
|
for (i = 0; i < MAX_FRONTIER_PARTY_SIZE; i++)
|
|
if (gSelectedOrderFromParty[i]) // as long as the order keeps going (did the player select 1 mon? 2? 3?), do not stop
|
|
party[i] = gPlayerParty[gSelectedOrderFromParty[i] - 1]; // index is 0 based, not literal
|
|
|
|
CpuFill32(0, gPlayerParty, sizeof gPlayerParty);
|
|
|
|
// overwrite the first 4 with the order copied to.
|
|
for (i = 0; i < MAX_FRONTIER_PARTY_SIZE; i++)
|
|
gPlayerParty[i] = party[i];
|
|
|
|
CalculatePlayerPartyCount();
|
|
}
|