fix merge conflict

This commit is contained in:
DizzyEggg
2017-10-15 23:27:27 +02:00
269 changed files with 36239 additions and 38308 deletions

View File

@@ -40,7 +40,9 @@
#include "trainer_classes.h"
#include "evolution_scene.h"
#include "roamer.h"
#include "tv.h"
#include "safari_zone.h"
#include "battle_string_ids.h"
struct UnknownStruct6
{
@@ -63,7 +65,6 @@ struct UnknownPokemonStruct2
/*0x1D*/ u8 language;
};
extern u32 gBattleTypeFlags;
extern u8 gBattleCommunication[];
extern u8 gBattleTerrain;
extern u16 gBattle_BG0_X;
@@ -87,7 +88,6 @@ extern void (*gBattleMainFunc)(void);
extern void (*gUnknown_030061E8)(void);
extern struct UnknownPokemonStruct2 gUnknown_02022FF8[3]; // what is it used for?
extern struct UnknownPokemonStruct2* gUnknown_02023058; // what is it used for?
extern u8 gBattleOutcome;
extern u8 gUnknown_02039B28[]; // possibly a struct?
extern struct UnknownStruct6 gUnknown_02038C28; // todo: identify & document
extern struct MusicPlayerInfo gMPlay_SE1;
@@ -138,7 +138,6 @@ extern u8 gActionForBanks[BATTLE_BANKS_COUNT];
extern u16 gChosenMovesByBanks[BATTLE_BANKS_COUNT];
extern u8 gCurrentActionFuncId;
extern u8 gLastUsedAbility;
extern u16 gLastUsedItem;
extern u8 gUnknown_0203CF00[];
extern const u8* gBattlescriptPtrsForSelection[BATTLE_BANKS_COUNT];
extern const u8* gBattlescriptCurrInstr;
@@ -151,7 +150,6 @@ extern u8 gCurrMovePos;
extern u8 gUnknown_020241E9;
extern u16 gLastUsedMove;
extern const u8 gSpeciesNames[][POKEMON_NAME_LENGTH + 1];
extern const struct BattleMove gBattleMoves[];
extern const u16 gUnknown_08C004E0[]; // battle textbox palette
extern const struct BgTemplate gUnknown_0831AA08[];
@@ -219,14 +217,12 @@ extern void sub_81B9150(void);
extern void sub_800AC34(void);
extern void sub_80B3AF8(u8 taskId); // cable club
extern void sub_8076918(u8 bank);
extern void sub_80729D0(u8 healthoxSpriteId);
extern void SetHealthboxSpriteVisible(u8 healthoxSpriteId);
extern void sub_81A56B4(void); // battle frontier 2
extern u8 sub_81A9E28(void); // battle frontier 2
extern void sub_81A56E8(u8 bank); // battle frontier 2
extern void sub_81B8FB0(u8, u8); // party menu
extern u8 pokemon_order_func(u8); // party menu
extern void sub_80EC728(void); // tv
extern void sub_80EE184(void); // tv
extern bool8 InBattlePyramid(void);
// this file's functions
@@ -245,7 +241,7 @@ static void sub_8038F34(void);
static void sub_80392A8(void);
static void sub_803937C(void);
static void sub_803939C(void);
static void oac_poke_opponent(struct Sprite *sprite);
void oac_poke_opponent(struct Sprite *sprite);
static void sub_803980C(struct Sprite *sprite);
static void sub_8039838(struct Sprite *sprite);
static void sub_8039894(struct Sprite *sprite);
@@ -343,7 +339,7 @@ const u8 gStatusConditionString_IceJpn[8] = _("こおり$$$$");
const u8 gStatusConditionString_ConfusionJpn[8] = _("こんらん$$$");
const u8 gStatusConditionString_LoveJpn[8] = _("メロメロ$$$");
const u8 * const gStatusConditionStringsTable[][2] =
const u8 * const gStatusConditionStringsTable[7][2] =
{
{gStatusConditionString_PoisonJpn, gText_Poison},
{gStatusConditionString_SleepJpn, gText_Sleep},
@@ -858,7 +854,7 @@ static void CB2_HandleStartBattle(void)
{
s32 i;
for (i = 0; i < 2 && (gLinkPlayers[i].version & 0xFF) == 3; i++);
for (i = 0; i < 2 && (gLinkPlayers[i].version & 0xFF) == VERSION_EMERALD; i++);
if (i == 2)
gBattleCommunication[MULTIUSE_STATE] = 16;
@@ -1650,7 +1646,7 @@ void CB2_QuitRecordedBattle(void)
}
}
static void sub_8038528(struct Sprite* sprite)
void sub_8038528(struct Sprite* sprite)
{
sprite->data0 = 0;
sprite->callback = sub_8038538;
@@ -2072,7 +2068,7 @@ static void sub_8038F34(void)
else
monsCount = 2;
for (i = 0; i < monsCount && (gLinkPlayers[i].version & 0xFF) == 3; i++);
for (i = 0; i < monsCount && (gLinkPlayers[i].version & 0xFF) == VERSION_EMERALD; i++);
if (!gSaveBlock2Ptr->field_CA9_b && i == monsCount)
{
@@ -2417,7 +2413,7 @@ u32 sub_80397C4(u32 setId, u32 tableId)
#define tBank data0
#define tSpeciesId data2
static void oac_poke_opponent(struct Sprite *sprite)
void oac_poke_opponent(struct Sprite *sprite)
{
sprite->callback = sub_803980C;
StartSpriteAnimIfDifferent(sprite, 0);
@@ -2441,7 +2437,7 @@ static void sub_8039838(struct Sprite *sprite)
if (sprite->animEnded)
{
sub_8076918(sprite->tBank);
sub_80729D0(gHealthBoxesIds[sprite->tBank]);
SetHealthboxSpriteVisible(gHealthBoxesIds[sprite->tBank]);
sprite->callback = sub_8039894;
StartSpriteAnimIfDifferent(sprite, 0);
BeginNormalPaletteFade(0x20000, 0, 10, 0, 0x2108);
@@ -3299,7 +3295,7 @@ static void BattleIntroPrintTrainerWantsToBattle(void)
if (gBattleExecBuffer == 0)
{
gActiveBank = GetBankByIdentity(IDENTITY_OPPONENT_MON1);
PrepareStringBattle(0, gActiveBank);
PrepareStringBattle(STRINGID_INTROMSG, gActiveBank);
gBattleMainFunc = BattleIntroPrintOpponentSendsOut;
}
}
@@ -3309,7 +3305,7 @@ static void BattleIntroPrintWildMonAttacked(void)
if (gBattleExecBuffer == 0)
{
gBattleMainFunc = BattleIntroPrintPlayerSendsOut;
PrepareStringBattle(0, 0);
PrepareStringBattle(STRINGID_INTROMSG, 0);
}
}
@@ -3332,7 +3328,7 @@ static void BattleIntroPrintOpponentSendsOut(void)
else
identity = IDENTITY_OPPONENT_MON1;
PrepareStringBattle(1, GetBankByIdentity(identity));
PrepareStringBattle(STRINGID_INTROSENDOUT, GetBankByIdentity(identity));
gBattleMainFunc = BattleIntroOpponent1SendsOutMonAnimation;
}
@@ -3535,7 +3531,7 @@ static void BattleIntroPrintPlayerSendsOut(void)
identity = IDENTITY_PLAYER_MON1;
if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI))
PrepareStringBattle(1, GetBankByIdentity(identity));
PrepareStringBattle(STRINGID_INTROSENDOUT, GetBankByIdentity(identity));
gBattleMainFunc = BattleIntroPlayer1SendsOutMonAnimation;
}
@@ -4006,8 +4002,8 @@ static void HandleTurnActionSelectionState(void)
for (i = 0; i < 4; i++)
{
moveInfo.moves[i] = gBattleMons[gActiveBank].moves[i];
moveInfo.ppNumbers[i] = gBattleMons[gActiveBank].pp[i];
moveInfo.ppWithBonusNumbers[i] = CalculatePPWithBonus(
moveInfo.currentPp[i] = gBattleMons[gActiveBank].pp[i];
moveInfo.maxPp[i] = CalculatePPWithBonus(
gBattleMons[gActiveBank].moves[i],
gBattleMons[gActiveBank].ppBonuses,
i);
@@ -4926,7 +4922,7 @@ static void HandleEndTurn_FinishBattle(void)
}
}
}
sub_80EC728();
PutPokemonTodayCaughtOnAir();
}
if (!(gBattleTypeFlags & (BATTLE_TYPE_LINK
@@ -5323,30 +5319,30 @@ static void HandleAction_UseItem(void)
{
gBattleScripting.bank = gBankAttacker;
switch (*(gBattleStruct->field_C4 + (gBankAttacker >> 1)))
switch (*(gBattleStruct->AI_itemType + (gBankAttacker >> 1)))
{
case 1:
case 2:
case AI_ITEM_FULL_RESTORE:
case AI_ITEM_HEAL_HP:
break;
case 3:
case AI_ITEM_CURE_CONDITION:
gBattleCommunication[MULTISTRING_CHOOSER] = 0;
if (*(gBattleStruct->field_C6 + gBankAttacker / 2) & 1)
if (*(gBattleStruct->AI_itemFlags + gBankAttacker / 2) & 1)
{
if (*(gBattleStruct->field_C6 + gBankAttacker / 2) & 0x3E)
if (*(gBattleStruct->AI_itemFlags + gBankAttacker / 2) & 0x3E)
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
}
else
{
while (!(*(gBattleStruct->field_C6 + gBankAttacker / 2) & 1))
while (!(*(gBattleStruct->AI_itemFlags + gBankAttacker / 2) & 1))
{
*(gBattleStruct->field_C6 + gBankAttacker / 2) >>= 1;
*(gBattleStruct->AI_itemFlags + gBankAttacker / 2) >>= 1;
gBattleCommunication[MULTISTRING_CHOOSER]++;
}
}
break;
case 4:
case AI_ITEM_X_STAT:
gBattleCommunication[MULTISTRING_CHOOSER] = 4;
if (*(gBattleStruct->field_C6 + (gBankAttacker >> 1)) & 0x80)
if (*(gBattleStruct->AI_itemFlags + (gBankAttacker >> 1)) & 0x80)
{
gBattleCommunication[MULTISTRING_CHOOSER] = 5;
}
@@ -5355,9 +5351,9 @@ static void HandleAction_UseItem(void)
PREPARE_STAT_BUFFER(gBattleTextBuff1, STAT_ATK)
PREPARE_STRING_BUFFER(gBattleTextBuff2, 0xD2)
while (!((*(gBattleStruct->field_C6 + (gBankAttacker >> 1))) & 1))
while (!((*(gBattleStruct->AI_itemFlags + (gBankAttacker >> 1))) & 1))
{
*(gBattleStruct->field_C6 + gBankAttacker / 2) >>= 1;
*(gBattleStruct->AI_itemFlags + gBankAttacker / 2) >>= 1;
gBattleTextBuff1[2]++;
}
@@ -5365,7 +5361,7 @@ static void HandleAction_UseItem(void)
gBattleScripting.animArg2 = 0;
}
break;
case 5:
case AI_ITEM_GUARD_SPECS:
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
gBattleCommunication[MULTISTRING_CHOOSER] = 2;
else
@@ -5373,7 +5369,7 @@ static void HandleAction_UseItem(void)
break;
}
gBattlescriptCurrInstr = gUnknown_082DBD3C[*(gBattleStruct->field_C4 + gBankAttacker / 2)];
gBattlescriptCurrInstr = gUnknown_082DBD3C[*(gBattleStruct->AI_itemType + gBankAttacker / 2)];
}
gCurrentActionFuncId = ACTION_RUN_BATTLESCRIPT;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,951 @@
#include "global.h"
#include "battle.h"
#include "battle_controllers.h"
#include "abilities.h"
#include "moves.h"
#include "pokemon.h"
#include "species.h"
#include "rng.h"
#include "util.h"
#include "items.h"
#include "pokemon_item_effects.h"
extern u8 gActiveBank;
extern u8 gAbsentBankFlags;
extern u32 gBattleTypeFlags;
extern u32 gStatuses3[BATTLE_BANKS_COUNT];
extern struct BattlePokemon gBattleMons[BATTLE_BANKS_COUNT];
extern u16 gBattlePartyID[BATTLE_BANKS_COUNT];
extern u16 gUnknown_02024250[BATTLE_BANKS_COUNT];
extern u8 gUnknown_02024270[BATTLE_BANKS_COUNT];
extern u16 gDynamicBasePower;
extern u8 gBattleMoveFlags;
extern u8 gCritMultiplier;
extern s32 gBattleMoveDamage;
extern const struct BattleMove gBattleMoves[];
extern const struct BaseStats gBaseStats[];
extern const u8 gTypeEffectiveness[];
extern const u8 * const gItemEffectTable[]; // todo: fix once struct is declared
// this file's functions
static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng);
static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent);
static bool8 ShouldUseItem(void);
static bool8 ShouldSwitchIfPerishSong(void)
{
if (gStatuses3[gActiveBank] & STATUS3_PERISH_SONG
&& gDisableStructs[gActiveBank].perishSong1 == 0)
{
*(gBattleStruct->field_294 + gActiveBank) = 6;
EmitCmd_x21(1, 2, 0);
return TRUE;
}
return FALSE;
}
static bool8 ShouldSwitchIfWonderGuard(void)
{
u8 opposingIdentity;
u8 opposingBank;
u8 moveFlags;
s32 i, j;
s32 firstId;
s32 lastId; // + 1
struct Pokemon *party = NULL;
u16 move;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
return FALSE;
opposingIdentity = GetBankIdentity(gActiveBank) ^ BIT_SIDE;
if (gBattleMons[GetBankByIdentity(opposingIdentity)].ability != ABILITY_WONDER_GUARD)
return FALSE;
// check if pokemon has a super effective move
for (opposingBank = GetBankByIdentity(opposingIdentity), i = 0; i < 4; i++)
{
move = gBattleMons[gActiveBank].moves[i];
if (move == MOVE_NONE)
continue;
moveFlags = AI_TypeCalc(move, gBattleMons[opposingBank].species, gBattleMons[opposingBank].ability);
if (moveFlags & MOVESTATUS_SUPEREFFECTIVE)
return FALSE;
}
// get party information
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBank & BIT_MON) == 0)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
if (GetBankSide(gActiveBank) == SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
// find a pokemon in the party that has a super effective move
for (i = firstId; i < lastId; i++)
{
if (GetMonData(&party[i], MON_DATA_HP) == 0)
continue;
if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_NONE)
continue;
if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG)
continue;
if (i == gBattlePartyID[gActiveBank])
continue;
GetMonData(&party[i], MON_DATA_SPECIES); // unused return value
GetMonData(&party[i], MON_DATA_ALT_ABILITY); // unused return value
for (opposingBank = GetBankByIdentity(opposingIdentity), j = 0; j < 4; j++)
{
move = GetMonData(&party[i], MON_DATA_MOVE1 + j);
if (move == MOVE_NONE)
continue;
moveFlags = AI_TypeCalc(move, gBattleMons[opposingBank].species, gBattleMons[opposingBank].ability);
if (moveFlags & MOVESTATUS_SUPEREFFECTIVE && Random() % 3 < 2)
{
// we found a mon
*(gBattleStruct->field_294 + gActiveBank) = i;
EmitCmd_x21(1, 2, 0);
return TRUE;
}
}
}
return FALSE; // at this point there is not a single pokemon in the party that has a super effective move against a pokemon with wonder guard
}
static bool8 FindMonThatAbsorbsOpponentsMove(void)
{
u8 bankIn1, bankIn2;
u8 absorbingTypeAbility;
s32 firstId;
s32 lastId; // + 1
struct Pokemon *party;
s32 i;
if (HasSuperEffectiveMoveAgainstOpponents(TRUE) && Random() % 3 != 0)
return FALSE;
if (gUnknown_02024250[gActiveBank] == 0)
return FALSE;
if (gUnknown_02024250[gActiveBank] == 0xFFFF)
return FALSE;
if (gBattleMoves[gUnknown_02024250[gActiveBank]].power == 0)
return FALSE;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
bankIn1 = gActiveBank;
if (gAbsentBankFlags & gBitTable[GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON)])
bankIn2 = gActiveBank;
else
bankIn2 = GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON);
}
else
{
bankIn1 = gActiveBank;
bankIn2 = gActiveBank;
}
if (gBattleMoves[gUnknown_02024250[gActiveBank]].type == TYPE_FIRE)
absorbingTypeAbility = ABILITY_FLASH_FIRE;
else if (gBattleMoves[gUnknown_02024250[gActiveBank]].type == TYPE_WATER)
absorbingTypeAbility = ABILITY_WATER_ABSORB;
else if (gBattleMoves[gUnknown_02024250[gActiveBank]].type == TYPE_ELECTRIC)
absorbingTypeAbility = ABILITY_VOLT_ABSORB;
else
return FALSE;
if (gBattleMons[gActiveBank].ability == absorbingTypeAbility)
return FALSE;
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBank & BIT_MON) == 0)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
if (GetBankSide(gActiveBank) == SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
for (i = firstId; i < lastId; i++)
{
u16 species;
u8 monAbility;
if (GetMonData(&party[i], MON_DATA_HP) == 0)
continue;
if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_NONE)
continue;
if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG)
continue;
if (i == gBattlePartyID[bankIn1])
continue;
if (i == gBattlePartyID[bankIn2])
continue;
if (i == *(gBattleStruct->field_5C + bankIn1))
continue;
if (i == *(gBattleStruct->field_5C + bankIn2))
continue;
species = GetMonData(&party[i], MON_DATA_SPECIES);
if (GetMonData(&party[i], MON_DATA_ALT_ABILITY) != 0)
monAbility = gBaseStats[species].ability2;
else
monAbility = gBaseStats[species].ability1;
if (absorbingTypeAbility == monAbility && Random() & 1)
{
// we found a mon
*(gBattleStruct->field_294 + gActiveBank) = i;
EmitCmd_x21(1, 2, 0);
return TRUE;
}
}
return FALSE;
}
static bool8 ShouldSwitchIfNaturalCure(void)
{
if (!(gBattleMons[gActiveBank].status1 & STATUS_SLEEP))
return FALSE;
if (gBattleMons[gActiveBank].ability != ABILITY_NATURAL_CURE)
return FALSE;
if (gBattleMons[gActiveBank].hp < gBattleMons[gActiveBank].maxHP / 2)
return FALSE;
if ((gUnknown_02024250[gActiveBank] == 0 || gUnknown_02024250[gActiveBank] == 0xFFFF) && Random() & 1)
{
*(gBattleStruct->field_294 + gActiveBank) = 6;
EmitCmd_x21(1, 2, 0);
return TRUE;
}
else if (gBattleMoves[gUnknown_02024250[gActiveBank]].power == 0 && Random() & 1)
{
*(gBattleStruct->field_294 + gActiveBank) = 6;
EmitCmd_x21(1, 2, 0);
return TRUE;
}
if (FindMonWithFlagsAndSuperEffective(MOVESTATUS_NOTAFFECTED, 1))
return TRUE;
if (FindMonWithFlagsAndSuperEffective(MOVESTATUS_NOTVERYEFFECTIVE, 1))
return TRUE;
if (Random() & 1)
{
*(gBattleStruct->field_294 + gActiveBank) = 6;
EmitCmd_x21(1, 2, 0);
return TRUE;
}
return FALSE;
}
static bool8 HasSuperEffectiveMoveAgainstOpponents(bool8 noRng)
{
u8 opposingIdentity;
u8 opposingBank;
s32 i;
u8 moveFlags;
u16 move;
opposingIdentity = GetBankIdentity(gActiveBank) ^ BIT_SIDE;
opposingBank = GetBankByIdentity(opposingIdentity);
if (!(gAbsentBankFlags & gBitTable[opposingBank]))
{
for (i = 0; i < 4; i++)
{
move = gBattleMons[gActiveBank].moves[i];
if (move == MOVE_NONE)
continue;
moveFlags = AI_TypeCalc(move, gBattleMons[opposingBank].species, gBattleMons[opposingBank].ability);
if (moveFlags & MOVESTATUS_SUPEREFFECTIVE)
{
if (noRng)
return TRUE;
if (Random() % 10 != 0)
return TRUE;
}
}
}
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
return FALSE;
opposingBank = GetBankByIdentity(opposingIdentity ^ BIT_MON);
if (!(gAbsentBankFlags & gBitTable[opposingBank]))
{
for (i = 0; i < 4; i++)
{
move = gBattleMons[gActiveBank].moves[i];
if (move == MOVE_NONE)
continue;
moveFlags = AI_TypeCalc(move, gBattleMons[opposingBank].species, gBattleMons[opposingBank].ability);
if (moveFlags & MOVESTATUS_SUPEREFFECTIVE)
{
if (noRng)
return TRUE;
if (Random() % 10 != 0)
return TRUE;
}
}
}
return FALSE;
}
static bool8 AreStatsRaised(void)
{
u8 buffedStatsValue = 0;
s32 i;
for (i = 0; i < BATTLE_STATS_NO; i++)
{
if (gBattleMons[gActiveBank].statStages[i] > 6)
buffedStatsValue += gBattleMons[gActiveBank].statStages[i] - 6;
}
return (buffedStatsValue > 3);
}
static bool8 FindMonWithFlagsAndSuperEffective(u8 flags, u8 moduloPercent)
{
u8 bankIn1, bankIn2;
s32 firstId;
s32 lastId; // + 1
struct Pokemon *party;
s32 i, j;
u16 move;
u8 moveFlags;
if (gUnknown_02024250[gActiveBank] == 0)
return FALSE;
if (gUnknown_02024250[gActiveBank] == 0xFFFF)
return FALSE;
if (gUnknown_02024270[gActiveBank] == 0xFF)
return FALSE;
if (gBattleMoves[gUnknown_02024250[gActiveBank]].power == 0)
return FALSE;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
bankIn1 = gActiveBank;
if (gAbsentBankFlags & gBitTable[GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON)])
bankIn2 = gActiveBank;
else
bankIn2 = GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON);
}
else
{
bankIn1 = gActiveBank;
bankIn2 = gActiveBank;
}
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBank & BIT_MON) == 0)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
if (GetBankSide(gActiveBank) == SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
for (i = firstId; i < lastId; i++)
{
u16 species;
u8 monAbility;
if (GetMonData(&party[i], MON_DATA_HP) == 0)
continue;
if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_NONE)
continue;
if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG)
continue;
if (i == gBattlePartyID[bankIn1])
continue;
if (i == gBattlePartyID[bankIn2])
continue;
if (i == *(gBattleStruct->field_5C + bankIn1))
continue;
if (i == *(gBattleStruct->field_5C + bankIn2))
continue;
species = GetMonData(&party[i], MON_DATA_SPECIES);
if (GetMonData(&party[i], MON_DATA_ALT_ABILITY) != 0)
monAbility = gBaseStats[species].ability2;
else
monAbility = gBaseStats[species].ability1;
moveFlags = AI_TypeCalc(gUnknown_02024250[gActiveBank], species, monAbility);
if (moveFlags & flags)
{
bankIn1 = gUnknown_02024270[gActiveBank];
for (j = 0; j < 4; j++)
{
move = GetMonData(&party[i], MON_DATA_MOVE1 + j);
if (move == 0)
continue;
moveFlags = AI_TypeCalc(move, gBattleMons[bankIn1].species, gBattleMons[bankIn1].ability);
if (moveFlags & MOVESTATUS_SUPEREFFECTIVE && Random() % moduloPercent == 0)
{
*(gBattleStruct->field_294 + gActiveBank) = i;
EmitCmd_x21(1, 2, 0);
return TRUE;
}
}
}
}
return FALSE;
}
static bool8 ShouldSwitch(void)
{
u8 bankIn1, bankIn2;
u8 *activeBankPtr; // needed to match
s32 firstId;
s32 lastId; // + 1
struct Pokemon *party;
s32 i;
s32 availableToSwitch;
if (gBattleMons[*(activeBankPtr = &gActiveBank)].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION))
return FALSE;
if (gStatuses3[gActiveBank] & STATUS3_ROOTED)
return FALSE;
if (AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBank, ABILITY_SHADOW_TAG, 0, 0))
return FALSE;
if (AbilityBattleEffects(ABILITYEFFECT_CHECK_OTHER_SIDE, gActiveBank, ABILITY_ARENA_TRAP, 0, 0))
return FALSE; // misses the flying or levitate check
if (AbilityBattleEffects(ABILITYEFFECT_FIELD_SPORT, 0, ABILITY_MAGNET_PULL, 0, 0))
{
if (gBattleMons[gActiveBank].type1 == TYPE_STEEL)
return FALSE;
if (gBattleMons[gActiveBank].type2 == TYPE_STEEL)
return FALSE;
}
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
return FALSE;
availableToSwitch = 0;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
bankIn1 = *activeBankPtr;
if (gAbsentBankFlags & gBitTable[GetBankByIdentity(GetBankIdentity(*activeBankPtr) ^ BIT_MON)])
bankIn2 = *activeBankPtr;
else
bankIn2 = GetBankByIdentity(GetBankIdentity(*activeBankPtr) ^ BIT_MON);
}
else
{
bankIn1 = *activeBankPtr;
bankIn2 = *activeBankPtr;
}
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBank & BIT_MON) == 0)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
if (GetBankSide(gActiveBank) == SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
for (i = firstId; i < lastId; i++)
{
if (GetMonData(&party[i], MON_DATA_HP) == 0)
continue;
if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_NONE)
continue;
if (GetMonData(&party[i], MON_DATA_SPECIES2) == SPECIES_EGG)
continue;
if (i == gBattlePartyID[bankIn1])
continue;
if (i == gBattlePartyID[bankIn2])
continue;
if (i == *(gBattleStruct->field_5C + bankIn1))
continue;
if (i == *(gBattleStruct->field_5C + bankIn2))
continue;
availableToSwitch++;
}
if (availableToSwitch == 0)
return FALSE;
if (ShouldSwitchIfPerishSong())
return TRUE;
if (ShouldSwitchIfWonderGuard())
return TRUE;
if (FindMonThatAbsorbsOpponentsMove())
return TRUE;
if (ShouldSwitchIfNaturalCure())
return TRUE;
if (HasSuperEffectiveMoveAgainstOpponents(FALSE))
return FALSE;
if (AreStatsRaised())
return FALSE;
if (FindMonWithFlagsAndSuperEffective(MOVESTATUS_NOTAFFECTED, 2)
|| FindMonWithFlagsAndSuperEffective(MOVESTATUS_NOTVERYEFFECTIVE, 3))
return TRUE;
return FALSE;
}
void AI_TrySwitchOrUseItem(void)
{
struct Pokemon *party;
u8 bankIn1, bankIn2;
s32 firstId;
s32 lastId; // + 1
u8 bankIdentity = GetBankIdentity(gActiveBank);
if (GetBankSide(gActiveBank) == SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER)
{
if (ShouldSwitch())
{
if (*(gBattleStruct->field_294 + gActiveBank) == 6)
{
s32 monToSwitchId = GetMostSuitableMonToSwitchInto();
if (monToSwitchId == 6)
{
if (!(gBattleTypeFlags & BATTLE_TYPE_DOUBLE))
{
bankIn1 = GetBankByIdentity(bankIdentity);
bankIn2 = bankIn1;
}
else
{
bankIn1 = GetBankByIdentity(bankIdentity);
bankIn2 = GetBankByIdentity(bankIdentity ^ BIT_MON);
}
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBank & BIT_MON) == 0)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
for (monToSwitchId = firstId; monToSwitchId < lastId; monToSwitchId++)
{
if (GetMonData(&party[monToSwitchId], MON_DATA_HP) == 0)
continue;
if (monToSwitchId == gBattlePartyID[bankIn1])
continue;
if (monToSwitchId == gBattlePartyID[bankIn2])
continue;
if (monToSwitchId == *(gBattleStruct->field_5C + bankIn1))
continue;
if (monToSwitchId == *(gBattleStruct->field_5C + bankIn2))
continue;
break;
}
}
*(gBattleStruct->field_294 + gActiveBank) = monToSwitchId;
}
*(gBattleStruct->field_5C + gActiveBank) = *(gBattleStruct->field_294 + gActiveBank);
return;
}
else if (ShouldUseItem())
{
return;
}
}
EmitCmd_x21(1, 0, (gActiveBank ^ BIT_SIDE) << 8);
}
#define TYPE_FORESIGHT 0xFE
#define TYPE_ENDTABLE 0xFF
static void ModulateByTypeEffectiveness(u8 atkType, u8 defType1, u8 defType2, u8 *var)
{
s32 i = 0;
while (gTypeEffectiveness[i] != TYPE_ENDTABLE)
{
if (gTypeEffectiveness[i] == TYPE_FORESIGHT)
{
i += 3;
continue;
}
else if (gTypeEffectiveness[i] == atkType)
{
// check type1
if (gTypeEffectiveness[i + 1] == defType1)
*var = (*var * gTypeEffectiveness[i + 2]) / 10;
// check type2
if (gTypeEffectiveness[i + 1] == defType2 && defType1 != defType2)
*var = (*var * gTypeEffectiveness[i + 2]) / 10;
}
i += 3;
}
}
u8 GetMostSuitableMonToSwitchInto(void)
{
u8 opposingBank;
u8 bestDmg; // note : should be changed to u32 for obvious reasons
u8 bestMonId;
u8 bankIn1, bankIn2;
s32 firstId;
s32 lastId; // + 1
struct Pokemon *party;
s32 i, j;
u8 invalidMons;
u16 move;
if (*(gBattleStruct->field_5C + gActiveBank) != 6)
return *(gBattleStruct->field_5C + gActiveBank);
if (gBattleTypeFlags & BATTLE_TYPE_ARENA)
return gBattlePartyID[gActiveBank] + 1;
if (gBattleTypeFlags & BATTLE_TYPE_DOUBLE)
{
bankIn1 = gActiveBank;
if (gAbsentBankFlags & gBitTable[GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON)])
bankIn2 = gActiveBank;
else
bankIn2 = GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_MON);
// UB: It considers the opponent only player's side even though it can battle alongside player;
opposingBank = Random() & BIT_MON;
if (gAbsentBankFlags & gBitTable[opposingBank])
opposingBank ^= BIT_MON;
}
else
{
opposingBank = GetBankByIdentity(GetBankIdentity(gActiveBank) ^ BIT_SIDE);
bankIn1 = gActiveBank;
bankIn2 = gActiveBank;
}
if (gBattleTypeFlags & (BATTLE_TYPE_TWO_OPPONENTS | BATTLE_TYPE_x800000))
{
if ((gActiveBank & BIT_MON) == 0)
firstId = 0, lastId = 3;
else
firstId = 3, lastId = 6;
}
else
{
firstId = 0, lastId = 6;
}
if (GetBankSide(gActiveBank) == SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
invalidMons = 0;
while (invalidMons != 0x3F) // all mons are invalid
{
bestDmg = 0;
bestMonId = 6;
// find the mon which type is the most suitable offensively
for (i = firstId; i < lastId; i++)
{
u16 species = GetMonData(&party[i], MON_DATA_SPECIES);
if (species != SPECIES_NONE
&& GetMonData(&party[i], MON_DATA_HP) != 0
&& !(gBitTable[i] & invalidMons)
&& gBattlePartyID[bankIn1] != i
&& gBattlePartyID[bankIn2] != i
&& i != *(gBattleStruct->field_5C + bankIn1)
&& i != *(gBattleStruct->field_5C + bankIn2))
{
u8 type1 = gBaseStats[species].type1;
u8 type2 = gBaseStats[species].type2;
u8 typeDmg = 10;
ModulateByTypeEffectiveness(gBattleMons[opposingBank].type1, type1, type2, &typeDmg);
ModulateByTypeEffectiveness(gBattleMons[opposingBank].type2, type1, type2, &typeDmg);
if (bestDmg < typeDmg)
{
bestDmg = typeDmg;
bestMonId = i;
}
}
else
{
invalidMons |= gBitTable[i];
}
}
// ok, we know the mon has the right typing but does it have at least one super effective move?
if (bestMonId != 6)
{
for (i = 0; i < 4; i++)
{
move = GetMonData(&party[bestMonId], MON_DATA_MOVE1 + i);
if (move != MOVE_NONE && TypeCalc(move, gActiveBank, opposingBank) & MOVESTATUS_SUPEREFFECTIVE)
break;
}
if (i != 4)
return bestMonId; // has both the typing and at least one super effective move
invalidMons |= gBitTable[bestMonId]; // sorry buddy, we want something better
}
else
{
invalidMons = 0x3F; // no viable mon to switch
}
}
gDynamicBasePower = 0;
gBattleStruct->dynamicMoveType = 0;
gBattleScripting.dmgMultiplier = 1;
gBattleMoveFlags = 0;
gCritMultiplier = 1;
bestDmg = 0;
bestMonId = 6;
// if we couldn't find the best mon in terms of typing, find the one that deals most damage
for (i = firstId; i < lastId; i++)
{
if ((u16)(GetMonData(&party[i], MON_DATA_SPECIES)) == SPECIES_NONE)
continue;
if (GetMonData(&party[i], MON_DATA_HP) == 0)
continue;
if (gBattlePartyID[bankIn1] == i)
continue;
if (gBattlePartyID[bankIn2] == i)
continue;
if (i == *(gBattleStruct->field_5C + bankIn1))
continue;
if (i == *(gBattleStruct->field_5C + bankIn2))
continue;
for (j = 0; j < 4; j++)
{
move = GetMonData(&party[i], MON_DATA_MOVE1 + j);
gBattleMoveDamage = 0;
if (move != MOVE_NONE && gBattleMoves[move].power != 1)
{
AI_CalcDmg(gActiveBank, opposingBank);
TypeCalc(move, gActiveBank, opposingBank);
}
if (bestDmg < gBattleMoveDamage)
{
bestDmg = gBattleMoveDamage;
bestMonId = i;
}
}
}
return bestMonId;
}
// TODO: use PokemonItemEffect struct instead of u8 once it's documented
static u8 GetAI_ItemType(u8 itemId, const u8 *itemEffect) // NOTE: should take u16 as item Id argument
{
if (itemId == ITEM_FULL_RESTORE)
return AI_ITEM_FULL_RESTORE;
if (itemEffect[4] & 4)
return AI_ITEM_HEAL_HP;
if (itemEffect[3] & 0x3F)
return AI_ITEM_CURE_CONDITION;
if (itemEffect[0] & 0x3F || itemEffect[1] != 0 || itemEffect[2] != 0)
return AI_ITEM_X_STAT;
if (itemEffect[3] & 0x80)
return AI_ITEM_GUARD_SPECS;
return AI_ITEM_NOT_RECOGNIZABLE;
}
static bool8 ShouldUseItem(void)
{
struct Pokemon *party;
s32 i;
u8 validMons = 0;
bool8 shouldUse = FALSE;
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && GetBankIdentity(gActiveBank) == IDENTITY_PLAYER_MON2)
return FALSE;
if (GetBankSide(gActiveBank) == SIDE_PLAYER)
party = gPlayerParty;
else
party = gEnemyParty;
for (i = 0; i < 6; i++)
{
if (GetMonData(&party[i], MON_DATA_HP) != 0
&& GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_NONE
&& GetMonData(&party[i], MON_DATA_SPECIES2) != SPECIES_EGG)
{
validMons++;
}
}
for (i = 0; i < 4; i++)
{
u16 item;
const u8 *itemEffects;
u8 paramOffset;
u8 bankSide;
if (i != 0 && validMons > (gBattleResources->battleHistory->itemsNo - i) + 1)
continue;
item = gBattleResources->battleHistory->trainerItems[i];
if (item == ITEM_NONE)
continue;
if (gItemEffectTable[item - 13] == NULL)
continue;
if (item == ITEM_ENIGMA_BERRY)
itemEffects = gSaveBlock1Ptr->enigmaBerry.itemEffect;
else
itemEffects = gItemEffectTable[item - 13];
*(gBattleStruct->AI_itemType + gActiveBank / 2) = GetAI_ItemType(item, itemEffects);
switch (*(gBattleStruct->AI_itemType + gActiveBank / 2))
{
case AI_ITEM_FULL_RESTORE:
if (gBattleMons[gActiveBank].hp >= gBattleMons[gActiveBank].maxHP / 4)
break;
if (gBattleMons[gActiveBank].hp == 0)
break;
shouldUse = TRUE;
break;
case AI_ITEM_HEAL_HP:
paramOffset = GetItemEffectParamOffset(item, 4, 4);
if (paramOffset == 0)
break;
if (gBattleMons[gActiveBank].hp == 0)
break;
if (gBattleMons[gActiveBank].hp < gBattleMons[gActiveBank].maxHP / 4 || gBattleMons[gActiveBank].maxHP - gBattleMons[gActiveBank].hp > itemEffects[paramOffset])
shouldUse = TRUE;
break;
case AI_ITEM_CURE_CONDITION:
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) = 0;
if (itemEffects[3] & 0x20 && gBattleMons[gActiveBank].status1 & STATUS_SLEEP)
{
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x20;
shouldUse = TRUE;
}
if (itemEffects[3] & 0x10 && (gBattleMons[gActiveBank].status1 & STATUS_POISON || gBattleMons[gActiveBank].status1 & STATUS_TOXIC_POISON))
{
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x10;
shouldUse = TRUE;
}
if (itemEffects[3] & 0x8 && gBattleMons[gActiveBank].status1 & STATUS_BURN)
{
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x8;
shouldUse = TRUE;
}
if (itemEffects[3] & 0x4 && gBattleMons[gActiveBank].status1 & STATUS_FREEZE)
{
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x4;
shouldUse = TRUE;
}
if (itemEffects[3] & 0x2 && gBattleMons[gActiveBank].status1 & STATUS_PARALYSIS)
{
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x2;
shouldUse = TRUE;
}
if (itemEffects[3] & 0x1 && gBattleMons[gActiveBank].status2 & STATUS2_CONFUSION)
{
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x1;
shouldUse = TRUE;
}
break;
case AI_ITEM_X_STAT:
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) = 0;
if (gDisableStructs[gActiveBank].isFirstTurn == 0)
break;
if (itemEffects[0] & 0xF)
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x1;
if (itemEffects[1] & 0xF0)
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x2;
if (itemEffects[1] & 0xF)
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x4;
if (itemEffects[2] & 0xF)
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x8;
if (itemEffects[2] & 0xF0)
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x20;
if (itemEffects[0] & 0x30)
*(gBattleStruct->AI_itemFlags + gActiveBank / 2) |= 0x80;
shouldUse = TRUE;
break;
case AI_ITEM_GUARD_SPECS:
bankSide = GetBankSide(gActiveBank);
if (gDisableStructs[gActiveBank].isFirstTurn != 0 && gSideTimers[bankSide].mistTimer == 0)
shouldUse = TRUE;
break;
case AI_ITEM_NOT_RECOGNIZABLE:
return FALSE;
}
if (shouldUse)
{
EmitCmd_x21(1, 1, 0);
*(gBattleStruct->field_C0 + (gActiveBank / 2) * 2) = item;
gBattleResources->battleHistory->trainerItems[i] = 0;
return shouldUse;
}
}
return FALSE;
}

View File

@@ -17,7 +17,7 @@ extern const struct CompressedSpritePalette gTrainerFrontPicPaletteTable[];
extern const union AffineAnimCmd *const gUnknown_082FF618[];
extern const union AffineAnimCmd *const gUnknown_082FF694[];
extern const union AnimCmd *const gUnknown_082FF70C[];
extern const union AnimCmd *const *const gUnknown_08309AAC[NUM_SPECIES];
extern const union AnimCmd *const *const gMonAnimationsSpriteAnimsPtrTable[NUM_SPECIES];
extern const union AnimCmd *const *const gUnknown_0830536C[];
extern const u8 gUnknown_0831F578[];
@@ -282,7 +282,7 @@ u16 sub_818D3E4(u16 species, u32 otId, u32 personality, u8 flags, s16 x, s16 y,
images[j].size = 0x800;
}
gUnknown_0203CCEC.tileTag = 0xFFFF;
gUnknown_0203CCEC.anims = gUnknown_08309AAC[species];
gUnknown_0203CCEC.anims = gMonAnimationsSpriteAnimsPtrTable[species];
gUnknown_0203CCEC.images = images;
if (flags2 == 0x01)
{

2333
src/battle_message.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -34,6 +34,7 @@
#include "pokemon_storage_system.h"
#include "task.h"
#include "naming_screen.h"
#include "battle_string_ids.h"
// variables
@@ -1375,7 +1376,7 @@ static void atk02_attackstring(void)
return;
if (!(gHitMarker & (HITMARKER_NO_ATTACKSTRING | HITMARKER_ATTACKSTRING_PRINTED)))
{
PrepareStringBattle(4, gBankAttacker);
PrepareStringBattle(STRINGID_USEDMOVE, gBankAttacker);
gHitMarker |= HITMARKER_ATTACKSTRING_PRINTED;
}
gBattlescriptCurrInstr++;
@@ -1771,11 +1772,11 @@ u8 TypeCalc(u16 move, u8 bankAtk, u8 bankDef)
return flags;
}
u8 AI_TypeCalc(u16 move, u16 species, u8 ability)
u8 AI_TypeCalc(u16 move, u16 targetSpecies, u8 targetAbility)
{
s32 i = 0;
u8 flags = 0;
u8 type1 = gBaseStats[species].type1, type2 = gBaseStats[species].type2;
u8 type1 = gBaseStats[targetSpecies].type1, type2 = gBaseStats[targetSpecies].type2;
u8 moveType;
if (move == MOVE_STRUGGLE)
@@ -1783,7 +1784,7 @@ u8 AI_TypeCalc(u16 move, u16 species, u8 ability)
moveType = gBattleMoves[move].type;
if (ability == ABILITY_LEVITATE && moveType == TYPE_GROUND)
if (targetAbility == ABILITY_LEVITATE && moveType == TYPE_GROUND)
{
flags = MOVESTATUS_MISSED | MOVESTATUS_NOTAFFECTED;
}
@@ -1808,7 +1809,7 @@ u8 AI_TypeCalc(u16 move, u16 species, u8 ability)
i += 3;
}
}
if (ability == ABILITY_WONDER_GUARD
if (targetAbility == ABILITY_WONDER_GUARD
&& (!(flags & MOVESTATUS_SUPEREFFECTIVE) || ((flags & (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)) == (MOVESTATUS_SUPEREFFECTIVE | MOVESTATUS_NOTVERYEFFECTIVE)))
&& gBattleMoves[move].power)
flags |= MOVESTATUS_NOTAFFECTED;
@@ -2000,7 +2001,7 @@ static void atk0B_healthbarupdate(void)
if (gBattleMons[gActiveBank].status2 & STATUS2_SUBSTITUTE && gDisableStructs[gActiveBank].substituteHP && !(gHitMarker & HITMARKER_IGNORE_SUBSTITUTE))
{
PrepareStringBattle(0x80, gActiveBank);
PrepareStringBattle(STRINGID_SUBSTITUTEDAMAGED, gActiveBank);
}
else
{
@@ -2157,7 +2158,7 @@ static void atk0D_critmessage(void)
{
if (gCritMultiplier == 2 && !(gBattleMoveFlags & MOVESTATUS_NOEFFECT))
{
PrepareStringBattle(0xD9, gBankAttacker);
PrepareStringBattle(STRINGID_CRITICALHIT, gBankAttacker);
gBattleCommunication[MSG_DISPLAY] = 1;
}
gBattlescriptCurrInstr++;
@@ -2229,22 +2230,22 @@ static void atk0F_resultmessage(void)
switch (gBattleMoveFlags & (u8)(~(MOVESTATUS_MISSED)))
{
case MOVESTATUS_SUPEREFFECTIVE:
stringId = 0xDE;
stringId = STRINGID_SUPEREFFECTIVE;
break;
case MOVESTATUS_NOTVERYEFFECTIVE:
stringId = 0xDD;
stringId = STRINGID_NOTVERYEFFECTIVE;
break;
case MOVESTATUS_ONEHITKO:
stringId = 0xDA;
stringId = STRINGID_ONEHITKO;
break;
case MOVESTATUS_ENDURED:
stringId = 0x99;
stringId = STRINGID_PKMNENDUREDHIT;
break;
case MOVESTATUS_FAILED:
stringId = 0xE5;
stringId = STRINGID_BUTITFAILED;
break;
case MOVESTATUS_NOTAFFECTED:
stringId = 0x1B;
stringId = STRINGID_ITDOESNTAFFECT;
break;
case MOVESTATUS_HUNGON:
gLastUsedItem = gBattleMons[gBankTarget].item;
@@ -2256,7 +2257,7 @@ static void atk0F_resultmessage(void)
default:
if (gBattleMoveFlags & MOVESTATUS_NOTAFFECTED)
{
stringId = 0x1B;
stringId = STRINGID_ITDOESNTAFFECT;
}
else if (gBattleMoveFlags & MOVESTATUS_ONEHITKO)
{
@@ -2285,7 +2286,7 @@ static void atk0F_resultmessage(void)
}
else if (gBattleMoveFlags & MOVESTATUS_FAILED)
{
stringId = 0xE5;
stringId = STRINGID_BUTITFAILED;
}
else
{
@@ -3592,7 +3593,7 @@ static void atk23_getexp(void)
PREPARE_WORD_NUMBER_BUFFER(gBattleTextBuff3, 5, gBattleMoveDamage)
PrepareStringBattle(0xD, gBattleStruct->expGetterBank);
PrepareStringBattle(STRINGID_PKMNGAINEDEXP, gBattleStruct->expGetterBank);
MonGainEVs(&gPlayerParty[gBattleStruct->expGetterId], gBattleMons[gBank1].species);
}
gBattleStruct->sentInPokes >>= 1;
@@ -6181,7 +6182,7 @@ static void atk5A_yesnoboxlearnmove(void)
u16 moveId = GetMonData(&gPlayerParty[gBattleStruct->expGetterId], MON_DATA_MOVE1 + movePosition);
if (IsHMMove2(moveId))
{
PrepareStringBattle(0x13F, gActiveBank);
PrepareStringBattle(STRINGID_HMMOVESCANTBEFORGOTTEN, gActiveBank);
gBattleScripting.learnMoveState = 6;
}
else
@@ -11086,7 +11087,7 @@ static void atkEF_pokeball_catch_calculation(void)
{
if (gLastUsedItem == ITEM_MASTER_BALL)
{
gBattleResults.unk5_1 = 1;
gBattleResults.usedMasterBall = TRUE;
}
else
{

File diff suppressed because it is too large Load Diff

View File

@@ -220,7 +220,7 @@ bool8 ShouldDoBrailleStrengthEffect(void)
void sub_8179834(void)
{
gFieldEffectSpawnParams[0] = brm_get_pokemon_selection();
gFieldEffectArguments[0] = brm_get_pokemon_selection();
FieldEffectStart(FLDEFF_USE_FLY_ANCIENT_TOMB);
}
@@ -256,7 +256,7 @@ bool8 ShouldDoBrailleFlyEffect(void)
void sub_8179918(void)
{
gFieldEffectSpawnParams[0] = brm_get_pokemon_selection();
gFieldEffectArguments[0] = brm_get_pokemon_selection();
FieldEffectStart(FLDEFF_USE_FLY_ANCIENT_TOMB);
}
@@ -417,7 +417,7 @@ bool8 ShouldDoBrailleRegicePuzzle(void)
}
// TODO: Find what flags 2 and 3 are.
FlagSet(3);
FlagReset(2);
FlagClear(2);
return FALSE;
}
#else
@@ -568,7 +568,7 @@ _08179B44:\n\
movs r0, 0x3\n\
bl FlagSet\n\
movs r0, 0x2\n\
bl FlagReset\n\
bl FlagClear\n\
_08179B5A:\n\
movs r0, 0\n\
_08179B5C:\n\

View File

@@ -54,7 +54,7 @@ void SetCoins(u16 coinAmount)
}
/* Can't match it lol
bool8 AddCoins(u16 toAdd)
bool8 GiveCoins(u16 toAdd)
{
u16 newAmount;
u16 ownedCoins = GetCoins();

View File

@@ -1,4 +1,5 @@
#include "global.h"
#include "diploma.h"
#include "palette.h"
#include "main.h"
#include "gpu_regs.h"
@@ -33,7 +34,7 @@ static void InitDiplomaBg(void);
static void InitDiplomaWindow(void);
static void PrintDiplomaText(u8 *, u8, u8);
EWRAM_DATA void **gDiplomaTilemapPtr = {NULL};
EWRAM_DATA static void **sDiplomaTilemapPtr = {NULL};
static void VBlankCB(void)
{
@@ -42,14 +43,14 @@ static void VBlankCB(void)
TransferPlttBuffer();
}
static const u16 gDiplomaPalettes[][16] =
static const u16 sDiplomaPalettes[][16] =
{
INCBIN_U16("graphics/misc/diploma_national.gbapal"),
INCBIN_U16("graphics/misc/diploma_hoenn.gbapal"),
};
static const u8 gDiplomaTilemap[] = INCBIN_U8("graphics/misc/diploma_map.bin.lz");
static const u8 gDiplomaTiles[] = INCBIN_U8("graphics/misc/diploma.4bpp.lz");
static const u8 sDiplomaTilemap[] = INCBIN_U8("graphics/misc/diploma_map.bin.lz");
static const u8 sDiplomaTiles[] = INCBIN_U8("graphics/misc/diploma.4bpp.lz");
void CB2_ShowDiploma(void)
{
@@ -76,15 +77,15 @@ void CB2_ShowDiploma(void)
ResetSpriteData();
ResetPaletteFade();
FreeAllSpritePalettes();
LoadPalette(gDiplomaPalettes, 0, 64);
gDiplomaTilemapPtr = malloc(0x1000);
LoadPalette(sDiplomaPalettes, 0, 64);
sDiplomaTilemapPtr = malloc(0x1000);
InitDiplomaBg();
InitDiplomaWindow();
reset_temp_tile_data_buffers();
decompress_and_copy_tile_data_to_vram(1, &gDiplomaTiles, 0, 0, 0);
decompress_and_copy_tile_data_to_vram(1, &sDiplomaTiles, 0, 0, 0);
while (free_temp_tile_data_buffers_if_possible())
;
LZDecompressWram(&gDiplomaTilemap, gDiplomaTilemapPtr);
LZDecompressWram(&sDiplomaTilemap, sDiplomaTilemapPtr);
CopyBgTilemapBufferToVram(1);
DisplayDiplomaText();
BlendPalettes(-1, 16, 0);
@@ -122,7 +123,7 @@ static void Task_DiplomaFadeOut(u8 taskId)
{
if (!gPaletteFade.active)
{
Free(gDiplomaTilemapPtr);
Free(sDiplomaTilemapPtr);
FreeAllWindowBuffers();
DestroyTask(taskId);
SetMainCallback2(sub_80861E8);
@@ -147,7 +148,7 @@ static void DisplayDiplomaText(void)
CopyWindowToVram(0, 3);
}
static const struct BgTemplate gDiplomaBgTemplates[2] =
static const struct BgTemplate sDiplomaBgTemplates[2] =
{
{
.bg = 0,
@@ -172,8 +173,8 @@ static const struct BgTemplate gDiplomaBgTemplates[2] =
static void InitDiplomaBg(void)
{
ResetBgsAndClearDma3BusyFlags(0);
InitBgsFromTemplates(0, gDiplomaBgTemplates, 2);
SetBgTilemapBuffer(1, gDiplomaTilemapPtr);
InitBgsFromTemplates(0, sDiplomaBgTemplates, 2);
SetBgTilemapBuffer(1, sDiplomaTilemapPtr);
SetGpuReg(REG_OFFSET_DISPCNT, DISPCNT_OBJ_ON | DISPCNT_OBJ_1D_MAP);
ShowBg(0);
ShowBg(1);
@@ -182,7 +183,7 @@ static void InitDiplomaBg(void)
SetGpuReg(REG_OFFSET_BLDY, DISPCNT_MODE_0);
}
static const struct WindowTemplate gDiplomaWinTemplates[2] =
static const struct WindowTemplate sDiplomaWinTemplates[2] =
{
{
.priority = 0,
@@ -198,7 +199,7 @@ static const struct WindowTemplate gDiplomaWinTemplates[2] =
static void InitDiplomaWindow(void)
{
InitWindows(gDiplomaWinTemplates);
InitWindows(sDiplomaWinTemplates);
DeactivateAllTextPrinters();
LoadPalette(gUnknown_0860F074, 0xF0, 0x20);
FillWindowPixelBuffer(0, 0);

View File

@@ -59,7 +59,7 @@ extern u8* GetMonNick(struct Pokemon* mon, u8* dst);
extern u8* GetBoxMonNick(struct BoxPokemon* boxMon, u8* dst);
extern u8 sav1_map_get_name(void);
extern s8 sub_8198C58(void);
extern void sub_81DB5E8(u8* str1, u8* str2, u8);
extern void TVShowConvertInternationalString(u8* str1, u8* str2, u8);
extern void sub_806A068(u16, u8);
extern void fade_screen(u8, u8);
extern void overworld_free_bg_tilemaps(void);
@@ -404,8 +404,8 @@ static bool8 sub_807158C(struct DaycareData* daycare, u8 daycareId)
|| StringCompareWithoutExtCtrlCodes(gSaveBlock2Ptr->playerName, daycareMon->OT_name) != 0))
{
StringCopy(gStringVar1, nick);
sub_81DB5E8(gStringVar2, daycareMon->OT_name, daycareMon->language_maybe);
sub_81DB5E8(gStringVar3, daycareMon->monName, daycareMon->unknown);
TVShowConvertInternationalString(gStringVar2, daycareMon->OT_name, daycareMon->language_maybe);
TVShowConvertInternationalString(gStringVar3, daycareMon->monName, daycareMon->unknown);
return TRUE;
}
return FALSE;

View File

@@ -40,11 +40,11 @@ void ClearTempFieldEventData(void)
{
memset(gSaveBlock1Ptr->flags, 0, TEMP_FLAGS_SIZE);
memset(gSaveBlock1Ptr->vars, 0, TEMP_VARS_SIZE);
FlagReset(SYS_ENC_UP_ITEM);
FlagReset(SYS_ENC_DOWN_ITEM);
FlagReset(SYS_USE_STRENGTH);
FlagReset(SYS_CTRL_OBJ_DELETE);
FlagReset(SYS_UNKNOWN_880);
FlagClear(SYS_ENC_UP_ITEM);
FlagClear(SYS_ENC_DOWN_ITEM);
FlagClear(SYS_USE_STRENGTH);
FlagClear(SYS_CTRL_OBJ_DELETE);
FlagClear(SYS_UNKNOWN_880);
}
// probably had different flag splits at one point.
@@ -58,7 +58,7 @@ void DisableNationalPokedex(void)
u16 *nationalDexVar = GetVarPointer(VAR_NATIONAL_DEX);
gSaveBlock2Ptr->pokedex.nationalMagic = 0;
*nationalDexVar = 0;
FlagReset(SYS_NATIONAL_DEX);
FlagClear(SYS_NATIONAL_DEX);
}
void EnableNationalPokedex(void)
@@ -82,7 +82,7 @@ bool32 IsNationalPokedexEnabled(void)
void DisableMysteryEvent(void)
{
FlagReset(SYS_MYSTERY_EVENT_ENABLE);
FlagClear(SYS_MYSTERY_EVENT_ENABLE);
}
void EnableMysteryEvent(void)
@@ -97,7 +97,7 @@ bool32 IsMysteryEventEnabled(void)
void DisableMysteryGift(void)
{
FlagReset(SYS_MYSTERY_GIFT_ENABLE);
FlagClear(SYS_MYSTERY_GIFT_ENABLE);
}
void EnableMysteryGift(void)
@@ -112,22 +112,22 @@ bool32 IsMysteryGiftEnabled(void)
void sub_809D4D8(void)
{
FlagReset(0x1E4);
FlagReset(0x1E5);
FlagReset(0x1E6);
FlagReset(0x1E7);
FlagReset(0x1E8);
FlagReset(0x1E9);
FlagReset(0x1EA);
FlagReset(0x1EB);
FlagReset(0x1EC);
FlagReset(0x1ED);
FlagReset(0x1EE);
FlagReset(0x1EF);
FlagReset(0x1F0);
FlagReset(0x1F1);
FlagReset(0x1F2);
FlagReset(0x1F3);
FlagClear(0x1E4);
FlagClear(0x1E5);
FlagClear(0x1E6);
FlagClear(0x1E7);
FlagClear(0x1E8);
FlagClear(0x1E9);
FlagClear(0x1EA);
FlagClear(0x1EB);
FlagClear(0x1EC);
FlagClear(0x1ED);
FlagClear(0x1EE);
FlagClear(0x1EF);
FlagClear(0x1F0);
FlagClear(0x1F1);
FlagClear(0x1F2);
FlagClear(0x1F3);
}
void sub_809D570(void)
@@ -145,7 +145,7 @@ void sub_809D570(void)
void DisableResetRTC(void)
{
VarSet(VAR_RESET_RTC_ENABLE, 0);
FlagReset(SYS_RESET_RTC_ENABLE);
FlagClear(SYS_RESET_RTC_ENABLE);
}
void EnableResetRTC(void)
@@ -214,7 +214,7 @@ u8 FlagSet(u16 id)
return 0;
}
u8 FlagReset(u16 id)
u8 FlagClear(u16 id)
{
u8 *ptr = GetFlagPointer(id);
if (ptr)

View File

@@ -3,7 +3,7 @@
#include "global.h"
#include "malloc.h"
#include "sprite.h"
#include "rom4.h"
#include "overworld.h"
#include "rng.h"
#include "event_scripts.h"
#include "berry.h"
@@ -2386,10 +2386,10 @@ bool8 do_berry_tree_growth_sparkle_1 (struct MapObject *mapObject, struct Sprite
{
if (!(sprite->data7 & 0x0004) && sprite->animNum == 4)
{
gFieldEffectSpawnParams[0] = mapObject->coords2.x;
gFieldEffectSpawnParams[1] = mapObject->coords2.y;
gFieldEffectSpawnParams[2] = sprite->subpriority - 1;
gFieldEffectSpawnParams[3] = sprite->oam.priority;
gFieldEffectArguments[0] = mapObject->coords2.x;
gFieldEffectArguments[1] = mapObject->coords2.y;
gFieldEffectArguments[2] = sprite->subpriority - 1;
gFieldEffectArguments[3] = sprite->oam.priority;
FieldEffectStart(FLDEFF_BERRY_TREE_GROWTH_SPARKLE);
sprite->animNum = berryStage;
}
@@ -2425,10 +2425,10 @@ bool8 do_berry_tree_growth_sparkle_2 (struct MapObject *mapObject, struct Sprite
sprite->data1 = 3;
sprite->data2 = 0;
sprite->data7 |= 0x0002;
gFieldEffectSpawnParams[0] = mapObject->coords2.x;
gFieldEffectSpawnParams[1] = mapObject->coords2.y;
gFieldEffectSpawnParams[2] = sprite->subpriority - 1;
gFieldEffectSpawnParams[3] = sprite->oam.priority;
gFieldEffectArguments[0] = mapObject->coords2.x;
gFieldEffectArguments[1] = mapObject->coords2.y;
gFieldEffectArguments[2] = sprite->subpriority - 1;
gFieldEffectArguments[3] = sprite->oam.priority;
FieldEffectStart(FLDEFF_BERRY_TREE_GROWTH_SPARKLE);
return TRUE;
}
@@ -3425,7 +3425,7 @@ void FieldObjectCB_TreeDisguise(struct Sprite *sprite)
mapObject = &gMapObjects[sprite->data0];
if (mapObject->mapobj_unk_21 == 0 || (mapObject->mapobj_unk_21 == 1 && !sprite->data7))
{
FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectSpawnParams[0], (u8 *)&gFieldEffectSpawnParams[1], (u8 *)&gFieldEffectSpawnParams[2]);
FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
mapObject->mapobj_unk_1A = FieldEffectStart(FLDEFF_TREE_DISGUISE);
mapObject->mapobj_unk_21 = 1;
sprite->data7 ++;
@@ -3446,7 +3446,7 @@ void FieldObjectCB_MountainDisguise(struct Sprite *sprite)
mapObject = &gMapObjects[sprite->data0];
if (mapObject->mapobj_unk_21 == 0 || (mapObject->mapobj_unk_21 == 1 && !sprite->data7))
{
FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectSpawnParams[0], (u8 *)&gFieldEffectSpawnParams[1], (u8 *)&gFieldEffectSpawnParams[2]);
FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
mapObject->mapobj_unk_1A = FieldEffectStart(FLDEFF_MOUNTAIN_DISGUISE);
mapObject->mapobj_unk_21 = 1;
sprite->data7 ++;
@@ -4693,7 +4693,7 @@ bool8 sub_80954CC(struct MapObject *mapObject, struct Sprite *sprite)
bool8 do_exclamation_mark_bubble_1(struct MapObject *mapObject, struct Sprite *sprite)
{
FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectSpawnParams[0], (u8 *)&gFieldEffectSpawnParams[1], (u8 *)&gFieldEffectSpawnParams[2]);
FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON_1);
sprite->data2 = 1;
return TRUE;
@@ -4701,7 +4701,7 @@ bool8 do_exclamation_mark_bubble_1(struct MapObject *mapObject, struct Sprite *s
bool8 do_exclamation_mark_bubble_2(struct MapObject *mapObject, struct Sprite *sprite)
{
FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectSpawnParams[0], (u8 *)&gFieldEffectSpawnParams[1], (u8 *)&gFieldEffectSpawnParams[2]);
FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
FieldEffectStart(FLDEFF_EXCLAMATION_MARK_ICON_2);
sprite->data2 = 1;
return TRUE;
@@ -4709,7 +4709,7 @@ bool8 do_exclamation_mark_bubble_2(struct MapObject *mapObject, struct Sprite *s
bool8 do_heart_bubble(struct MapObject *mapObject, struct Sprite *sprite)
{
FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectSpawnParams[0], (u8 *)&gFieldEffectSpawnParams[1], (u8 *)&gFieldEffectSpawnParams[2]);
FieldObjectGetLocalIdAndMap(mapObject, (u8 *)&gFieldEffectArguments[0], (u8 *)&gFieldEffectArguments[1], (u8 *)&gFieldEffectArguments[2]);
FieldEffectStart(FLDEFF_HEART_ICON);
sprite->data2 = 1;
return TRUE;

View File

@@ -13,10 +13,10 @@
#define SECONDS(value) ((signed) (60.0 * value + 0.5))
extern u8 GetSSTidalLocation(s8 *, s8 *, s16 *, s16 *); // should be in field_specials.h
extern void warp1_set(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y);
extern bool8 sub_80D3340(u8, u8, u8);
extern void Overworld_SetWarpDestination(s8 mapGroup, s8 mapNum, s8 warpId, s8 x, s8 y);
extern bool8 ScriptMovement_IsObjectMovementFinished(u8, u8, u8);
extern bool32 CountSSTidalStep(u16);
extern bool8 exec_movement(u8, u8, u8, u8 *);
extern bool8 ScriptMovement_StartObjectMovementScript(u8, u8, u8, u8 *);
extern void copy_saved_warp2_bank_and_enter_x_to_warp1(u8 unused);
extern void sp13E_warp_to_last_warp(void);
extern void saved_warp2_set(int unused, s8 mapGroup, s8 mapNum, s8 warpId);
@@ -264,7 +264,7 @@ bool8 sub_80FB59C(void)
}
else
{
warp1_set(mapGroup, mapNum, -1, x, y);
Overworld_SetWarpDestination(mapGroup, mapNum, -1, x, y);
return TRUE;
}
}
@@ -287,7 +287,7 @@ void Task_HandlePorthole(u8 taskId)
case IDLE_CHECK: // idle and move.
if (gMain.newKeys & A_BUTTON)
data[1] = 1;
if (!sub_80D3340(0xFF, location->mapNum, location->mapGroup))
if (!ScriptMovement_IsObjectMovementFinished(0xFF, location->mapNum, location->mapGroup))
return;
if (CountSSTidalStep(1) == TRUE)
{
@@ -308,18 +308,18 @@ void Task_HandlePorthole(u8 taskId)
// run this once.
if (*var == 2) // which direction?
{
exec_movement(0xFF, location->mapNum, location->mapGroup, gUnknown_0858E8AB);
ScriptMovement_StartObjectMovementScript(0xFF, location->mapNum, location->mapGroup, gUnknown_0858E8AB);
data[0] = IDLE_CHECK; // run case 1.
}
else
{
exec_movement(0xFF, location->mapNum, location->mapGroup, gUnknown_0858E8AD);
ScriptMovement_StartObjectMovementScript(0xFF, location->mapNum, location->mapGroup, gUnknown_0858E8AD);
data[0] = IDLE_CHECK; // run case 1.
}
break;
case EXIT_PORTHOLE: // exit porthole.
FlagReset(0x4001);
FlagReset(0x4000);
FlagClear(0x4001);
FlagClear(0x4000);
copy_saved_warp2_bank_and_enter_x_to_warp1(0);
sp13E_warp_to_last_warp();
DestroyTask(taskId);

View File

@@ -4,7 +4,7 @@
#include "global.h"
#include "main.h"
#include "rom4.h"
#include "overworld.h"
#include "rom6.h"
#include "event_data.h"
#include "script.h"

View File

@@ -110,7 +110,7 @@ void AddMoney(u32* moneyPtr, u32 toAdd)
SetMoney(moneyPtr, toSet);
}
void SubtractMoney(u32* moneyPtr, u32 toSub)
void RemoveMoney(u32* moneyPtr, u32 toSub)
{
u32 toSet = GetMoney(moneyPtr);
@@ -130,7 +130,7 @@ bool8 IsEnoughForCostInVar0x8005(void)
void SubtractMoneyFromVar0x8005(void)
{
SubtractMoney(&gSaveBlock1Ptr->money, gSpecialVar_0x8005);
RemoveMoney(&gSaveBlock1Ptr->money, gSpecialVar_0x8005);
}
void PrintMoneyAmountInMoneyBox(u8 windowId, int amount, u8 speed)

View File

@@ -17,6 +17,7 @@
#include "easy_chat.h"
#include "event_data.h"
#include "money.h"
#include "tv.h"
#include "coins.h"
#include "text.h"
@@ -28,7 +29,7 @@ extern u8 gUnknown_030060B0;
// TODO: replace those declarations with file headers
extern u16 GetGeneratedTrainerIdLower(void);
extern void ClearContestWinnerPicsInContestHall(void);
extern void warp1_set(s8 mapBank, s8 mapNo, s8 warpNo, s8 xPos, s8 yPos);
extern void Overworld_SetWarpDestination(s8 mapBank, s8 mapNo, s8 warpNo, s8 xPos, s8 yPos);
extern void warp_in(void);
extern void sub_80BB358(void);
extern void ResetBagScrollPositions(void);
@@ -36,7 +37,6 @@ extern void sub_813624C(void); // clears something pokeblock related
extern void ResetPokedex(void);
extern void sub_8084400(void);
extern void ClearMailData(void);
extern void ClearTVShowData(void);
extern void ResetGabbyAndTy(void);
extern void ResetSecretBases(void);
extern void ResetLinkContestBoolean(void);
@@ -131,7 +131,7 @@ void sub_8084400(void)
void WarpToTruck(void)
{
warp1_set(25, 40, -1, -1, -1); // inside of truck
Overworld_SetWarpDestination(25, 40, -1, -1, -1); // inside of truck
warp_in();
}

View File

@@ -53,13 +53,13 @@ static void UpdateBlendRegisters(void);
static bool8 IsSoftwarePaletteFadeFinishing(void);
static void sub_80A2D54(u8 taskId);
EWRAM_DATA u16 gPlttBufferUnfaded[0x200] = {0};
EWRAM_DATA u16 gPlttBufferFaded[0x200] = {0};
EWRAM_DATA u16 gPlttBufferUnfaded[PLTT_BUFFER_SIZE] = {0};
EWRAM_DATA u16 gPlttBufferFaded[PLTT_BUFFER_SIZE] = {0};
EWRAM_DATA struct PaletteStruct sPaletteStructs[0x10] = {0};
EWRAM_DATA struct PaletteFadeControl gPaletteFade = {0};
static EWRAM_DATA u32 gFiller_2037FE0 = 0;
static EWRAM_DATA u32 sPlttBufferTransferPending = 0;
EWRAM_DATA u8 gPaletteDecompressionBuffer[0x400] = {0};
EWRAM_DATA u8 gPaletteDecompressionBuffer[PLTT_DECOMP_BUFFER_SIZE] = {0};
static const struct PaletteStructTemplate gDummyPaletteStructTemplate = {
.uid = 0xFFFF,

View File

@@ -28,7 +28,7 @@ extern const u32 gBitTable[];
extern const struct SpriteTemplate gUnknown_08329D98[];
extern const struct SpriteTemplate gUnknown_08329DF8[];
extern const union AnimCmd* gUnknown_082FF70C[];
extern const union AnimCmd* const * const gUnknown_08309AAC[];
extern const union AnimCmd* const * const gMonAnimationsSpriteAnimsPtrTable[];
extern const union AnimCmd* const * const gUnknown_08305D0C[];
extern const union AnimCmd* const * const gUnknown_0830536C[];
extern const u8 gText_BadEgg[];
@@ -165,9 +165,9 @@ void sub_806A068(u16 species, u8 bankIdentity)
if (bankIdentity == 0 || bankIdentity == 2)
gUnknown_0202499C.anims = gUnknown_082FF70C;
else if (species > 500)
gUnknown_0202499C.anims = gUnknown_08309AAC[species - 500];
gUnknown_0202499C.anims = gMonAnimationsSpriteAnimsPtrTable[species - 500];
else
gUnknown_0202499C.anims = gUnknown_08309AAC[species];
gUnknown_0202499C.anims = gMonAnimationsSpriteAnimsPtrTable[species];
}
void sub_806A12C(u16 trainerSpriteId, u8 bankIdentity)
@@ -1089,7 +1089,7 @@ u8 SendMonToPC(struct Pokemon* mon)
gSpecialVar_0x8012 = boxNo;
gSpecialVar_0x8013 = boxPos;
if (get_unknown_box_id() != boxNo)
FlagReset(SYS_STORAGE_UNKNOWN_FLAG);
FlagClear(SYS_STORAGE_UNKNOWN_FLAG);
VarSet(VAR_STORAGE_UNKNOWN, boxNo);
return MON_GIVEN_TO_PC;
}

View File

@@ -5,7 +5,7 @@
#include "load_save.h"
#include "save.h"
#include "new_game.h"
#include "rom4.h"
#include "overworld.h"
#include "malloc.h"
void sub_81700F8(void)

354
src/reshow_battle_screen.c Normal file
View File

@@ -0,0 +1,354 @@
#include "global.h"
#include "reshow_battle_screen.h"
#include "battle.h"
#include "palette.h"
#include "main.h"
#include "unknown_task.h"
#include "text.h"
#include "gpu_regs.h"
#include "bg.h"
#include "battle_controllers.h"
#include "link.h"
#include "sprite.h"
#include "species.h"
#include "battle_interface.h"
extern u16 gBattle_BG0_X;
extern u16 gBattle_BG0_Y;
extern u16 gBattle_BG1_X;
extern u16 gBattle_BG1_Y;
extern u16 gBattle_BG2_X;
extern u16 gBattle_BG2_Y;
extern u16 gBattle_BG3_X;
extern u16 gBattle_BG3_Y;
extern u8 gReservedSpritePaletteCount;
extern u8 gActionSelectionCursor[BATTLE_BANKS_COUNT];
extern u8 gBankInMenu;
extern u16 gBattlePartyID[BATTLE_BANKS_COUNT];
extern u8 gNoOfAllBanks;
extern u32 gBattleTypeFlags;
extern u8 gBankSpriteIds[BATTLE_BANKS_COUNT];
extern u8 gBattleMonForms[BATTLE_BANKS_COUNT];
extern u8 gHealthBoxesIds[BATTLE_BANKS_COUNT];
extern struct SpriteTemplate gUnknown_0202499C;
extern const union AnimCmd * const * const gMonAnimationsSpriteAnimsPtrTable[];
extern void dp12_8087EA4(void);
extern void trs_config(void);
extern bool8 IsDoubleBattle(void);
extern u8 sub_80A614C(u8 bank);
extern u8 sub_80A6138(u8 bank);
extern u8 sub_80A82E4(u8 bank);
extern void sub_806A068(u16 species, u8 bankIdentity);
extern void sub_806A12C(u16 backPicId, u8 bankIdentity);
extern u8 sub_80A5C6C(u8 bank, u8 caseId);
// this file's functions
static void CB2_ReshowBattleScreenAfterMenu(void);
static bool8 LoadBankSpriteGfx(u8 bank);
static void CreateBankSprite(u8 bank);
static void CreateHealthboxSprite(u8 bank);
static void sub_80A95F4(void);
void nullsub_35(void)
{
}
void ReshowBattleScreenAfterMenu(void)
{
gPaletteFade.bufferTransferDisabled = 1;
SetHBlankCallback(NULL);
SetVBlankCallback(NULL);
SetGpuReg(REG_OFFSET_MOSAIC, 0);
gBattleScripting.reshowMainState = 0;
gBattleScripting.reshowHelperState = 0;
SetMainCallback2(CB2_ReshowBattleScreenAfterMenu);
}
static void CB2_ReshowBattleScreenAfterMenu(void)
{
switch (gBattleScripting.reshowMainState)
{
case 0:
dp12_8087EA4();
trs_config();
SetBgAttribute(1, BG_CTRL_ATTR_VISIBLE, 0);
SetBgAttribute(2, BG_CTRL_ATTR_VISIBLE, 0);
ShowBg(0);
ShowBg(1);
ShowBg(2);
ShowBg(3);
ResetPaletteFade();
gBattle_BG0_X = 0;
gBattle_BG0_Y = 0;
gBattle_BG1_X = 0;
gBattle_BG1_Y = 0;
gBattle_BG2_X = 0;
gBattle_BG2_Y = 0;
gBattle_BG3_X = 0;
gBattle_BG3_Y = 0;
break;
case 1:
CpuFastFill(0, (void*)(VRAM), VRAM_SIZE);
break;
case 2:
LoadBattleTextboxAndBackground();
break;
case 3:
ResetSpriteData();
break;
case 4:
FreeAllSpritePalettes();
gReservedSpritePaletteCount = 4;
break;
case 5:
sub_805E350();
break;
case 6:
if (BattleLoadAllHealthBoxesGfx(gBattleScripting.reshowHelperState))
{
gBattleScripting.reshowHelperState = 0;
}
else
{
gBattleScripting.reshowHelperState++;
gBattleScripting.reshowMainState--;
}
break;
case 7:
if (!LoadBankSpriteGfx(0))
gBattleScripting.reshowMainState--;
break;
case 8:
if (!LoadBankSpriteGfx(1))
gBattleScripting.reshowMainState--;
break;
case 9:
if (!LoadBankSpriteGfx(2))
gBattleScripting.reshowMainState--;
break;
case 10:
if (!LoadBankSpriteGfx(3))
gBattleScripting.reshowMainState--;
break;
case 11:
CreateBankSprite(0);
break;
case 12:
CreateBankSprite(1);
break;
case 13:
CreateBankSprite(2);
break;
case 14:
CreateBankSprite(3);
break;
case 15:
CreateHealthboxSprite(0);
break;
case 16:
CreateHealthboxSprite(1);
break;
case 17:
CreateHealthboxSprite(2);
break;
case 18:
CreateHealthboxSprite(3);
break;
case 19:
{
u8 opponentBank;
u16 species;
LoadAndCreateEnemyShadowSprites();
opponentBank = GetBankByIdentity(IDENTITY_OPPONENT_MON1);
species = GetMonData(&gEnemyParty[gBattlePartyID[opponentBank]], MON_DATA_SPECIES);
SetBankEnemyShadowSpriteCallback(opponentBank, species);
if (IsDoubleBattle())
{
opponentBank = GetBankByIdentity(IDENTITY_OPPONENT_MON2);
species = GetMonData(&gEnemyParty[gBattlePartyID[opponentBank]], MON_DATA_SPECIES);
SetBankEnemyShadowSpriteCallback(opponentBank, species);
}
ActionSelectionCreateCursorAt(gActionSelectionCursor[gBankInMenu], 0);
if (gLinkVSyncDisabled != 0 && gReceivedRemoteLinkPlayers != 0)
{
sub_800E0E8();
sub_800DFB4(0, 0);
}
}
break;
default:
SetVBlankCallback(VBlankCB_Battle);
sub_80A95F4();
BeginHardwarePaletteFade(0xFF, 0, 0x10, 0, 1);
gPaletteFade.bufferTransferDisabled = 0;
SetMainCallback2(BattleMainCB2);
sub_805EF14();
break;
}
gBattleScripting.reshowMainState++;
}
static void sub_80A95F4(void)
{
struct BGCntrlBitfield *regBgcnt1, *regBgcnt2;
regBgcnt1 = (struct BGCntrlBitfield *)(&REG_BG1CNT);
regBgcnt1->charBaseBlock = 0;
regBgcnt2 = (struct BGCntrlBitfield *)(&REG_BG2CNT);
regBgcnt2->charBaseBlock = 0;
}
static bool8 LoadBankSpriteGfx(u8 bank)
{
if (bank < gNoOfAllBanks)
{
if (GetBankSide(bank) != SIDE_PLAYER)
{
if (!gBattleSpritesDataPtr->bankData[bank].behindSubstitute)
BattleLoadOpponentMonSpriteGfx(&gEnemyParty[gBattlePartyID[bank]], bank);
else
BattleLoadSubstituteSpriteGfx(bank, FALSE);
}
else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0)
LoadBackTrainerBankSpriteGfx(gSaveBlock2Ptr->playerGender, bank);
else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0)
LoadBackTrainerBankSpriteGfx(BACK_PIC_WALLY, bank);
else if (!gBattleSpritesDataPtr->bankData[bank].behindSubstitute)
BattleLoadPlayerMonSpriteGfx(&gPlayerParty[gBattlePartyID[bank]], bank);
else
BattleLoadSubstituteSpriteGfx(bank, FALSE);
gBattleScripting.reshowHelperState = 0;
}
return TRUE;
}
// todo: get rid of it once the struct is declared in a header
struct MonCoords
{
// This would use a bitfield, but sub_8079F44
// uses it as a u8 and casting won't match.
u8 coords; // u8 x:4, y:4;
u8 y_offset;
};
extern const struct MonCoords gTrainerBackPicCoords[];
static void CreateBankSprite(u8 bank)
{
if (bank < gNoOfAllBanks)
{
u8 posY;
if (gBattleSpritesDataPtr->bankData[bank].behindSubstitute)
posY = sub_80A614C(bank);
else
posY = sub_80A6138(bank);
if (GetBankSide(bank) != SIDE_PLAYER)
{
if (GetMonData(&gEnemyParty[gBattlePartyID[bank]], MON_DATA_HP) == 0)
return;
sub_806A068(GetMonData(&gEnemyParty[gBattlePartyID[bank]], MON_DATA_SPECIES), GetBankIdentity(bank));
gBankSpriteIds[bank] = CreateSprite(&gUnknown_0202499C, sub_80A5C6C(bank, 2), posY, sub_80A82E4(bank));
gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank;
gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy;
gSprites[gBankSpriteIds[bank]].data0 = bank;
gSprites[gBankSpriteIds[bank]].data2 = GetMonData(&gEnemyParty[gBattlePartyID[bank]], MON_DATA_SPECIES);
StartSpriteAnim(&gSprites[gBankSpriteIds[bank]], gBattleMonForms[bank]);
if (gBattleSpritesDataPtr->bankData[bank].transformSpecies == SPECIES_CASTFORM)
gSprites[gBankSpriteIds[bank]].anims = gMonAnimationsSpriteAnimsPtrTable[SPECIES_CASTFORM];
}
else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0)
{
sub_806A12C(gSaveBlock2Ptr->playerGender, GetBankIdentity(IDENTITY_PLAYER_MON1));
gBankSpriteIds[bank] = CreateSprite(&gUnknown_0202499C, 0x50,
(8 - gTrainerBackPicCoords[gSaveBlock2Ptr->playerGender].coords) * 4 + 80,
sub_80A82E4(0));
gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank;
gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy;
gSprites[gBankSpriteIds[bank]].data0 = bank;
}
else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0)
{
sub_806A12C(BACK_PIC_WALLY, GetBankIdentity(0));
gBankSpriteIds[bank] = CreateSprite(&gUnknown_0202499C, 0x50,
(8 - gTrainerBackPicCoords[BACK_PIC_WALLY].coords) * 4 + 80,
sub_80A82E4(0));
gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank;
gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy;
gSprites[gBankSpriteIds[bank]].data0 = bank;
}
else
{
if (GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_HP) == 0)
return;
sub_806A068(GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_SPECIES), GetBankIdentity(bank));
gBankSpriteIds[bank] = CreateSprite(&gUnknown_0202499C, sub_80A5C6C(bank, 2), posY, sub_80A82E4(bank));
gSprites[gBankSpriteIds[bank]].oam.paletteNum = bank;
gSprites[gBankSpriteIds[bank]].callback = SpriteCallbackDummy;
gSprites[gBankSpriteIds[bank]].data0 = bank;
gSprites[gBankSpriteIds[bank]].data2 = GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_SPECIES);
StartSpriteAnim(&gSprites[gBankSpriteIds[bank]], gBattleMonForms[bank]);
if (gBattleSpritesDataPtr->bankData[bank].transformSpecies == SPECIES_CASTFORM)
gSprites[gBankSpriteIds[bank]].anims = gMonAnimationsSpriteAnimsPtrTable[SPECIES_CASTFORM];
}
gSprites[gBankSpriteIds[bank]].invisible = gBattleSpritesDataPtr->bankData[bank].invisible;
}
}
static void CreateHealthboxSprite(u8 bank)
{
if (bank < gNoOfAllBanks)
{
u8 healthboxSpriteId;
if (gBattleTypeFlags & BATTLE_TYPE_SAFARI && bank == 0)
healthboxSpriteId = CreateSafariPlayerHealthboxSprites();
else if (gBattleTypeFlags & BATTLE_TYPE_WALLY_TUTORIAL && bank == 0)
return;
else
healthboxSpriteId = CreateBankHealthboxSprites(bank);
gHealthBoxesIds[bank] = healthboxSpriteId;
SetBankHealthboxSpritePos(bank);
SetHealthboxSpriteVisible(healthboxSpriteId);
if (GetBankSide(bank) != SIDE_PLAYER)
UpdateHealthboxAttribute(gHealthBoxesIds[bank], &gEnemyParty[gBattlePartyID[bank]], HEALTHBOX_ALL);
else if (gBattleTypeFlags & BATTLE_TYPE_SAFARI)
UpdateHealthboxAttribute(gHealthBoxesIds[bank], &gPlayerParty[gBattlePartyID[bank]], HEALTHBOX_SAFARI_ALL_TEXT);
else
UpdateHealthboxAttribute(gHealthBoxesIds[bank], &gPlayerParty[gBattlePartyID[bank]], HEALTHBOX_ALL);
if (GetBankIdentity(bank) == IDENTITY_OPPONENT_MON2 || GetBankIdentity(bank) == IDENTITY_PLAYER_MON2)
nullsub_30(gHealthBoxesIds[bank], TRUE);
else
nullsub_30(gHealthBoxesIds[bank], FALSE);
if (GetBankSide(bank) != SIDE_PLAYER)
{
if (GetMonData(&gEnemyParty[gBattlePartyID[bank]], MON_DATA_HP) == 0)
SetHealthboxSpriteInvisible(healthboxSpriteId);
}
else if (!(gBattleTypeFlags & BATTLE_TYPE_SAFARI))
{
if (GetMonData(&gPlayerParty[gBattlePartyID[bank]], MON_DATA_HP) == 0)
SetHealthboxSpriteInvisible(healthboxSpriteId);
}
}
}

View File

@@ -60,7 +60,7 @@ void SetSafariZoneFlag(void)
void ResetSafariZoneFlag(void)
{
FlagReset(SYS_SAFARI_MODE);
FlagClear(SYS_SAFARI_MODE);
}
void EnterSafariMode(void)
@@ -114,7 +114,7 @@ void sub_80FC190(void)
{
SetMainCallback2(c2_exit_to_overworld_2_switch);
}
else if (gBattleOutcome == 8)
else if (gBattleOutcome == BATTLE_SAFARI_OUT_OF_BALLS)
{
ScriptContext2_RunNewScript(gUnknown_082A4B4C);
warp_in();

View File

@@ -1,4 +1,5 @@
#include "global.h"
#include "save_location.h"
#include "map_constants.h"
// used to make the list defines a little less ugly.
@@ -26,7 +27,7 @@ static bool32 IsCurMapInLocationList(const u16 *list)
}
// TODO: Not require a packed u16 array for these lists
static const u16 gSaveLocationPokeCenterList[] =
static const u16 sSaveLocationPokeCenterList[] =
{
MAP(OLDALE_TOWN_POKEMON_CENTER_1F),
MAP(OLDALE_TOWN_POKEMON_CENTER_2F),
@@ -71,10 +72,10 @@ static const u16 gSaveLocationPokeCenterList[] =
static bool32 IsCurMapPokeCenter(void)
{
return IsCurMapInLocationList(gSaveLocationPokeCenterList);
return IsCurMapInLocationList(sSaveLocationPokeCenterList);
}
static const u16 gSaveLocationReloadLocList[] = // there's only 1 location, and it's presumed its for the save reload feature for battle tower
static const u16 sSaveLocationReloadLocList[] = // there's only 1 location, and it's presumed its for the save reload feature for battle tower
{
MAP(BATTLE_TOWER_LOBBY),
0xFFFF,
@@ -82,18 +83,18 @@ static const u16 gSaveLocationReloadLocList[] = // there's only 1 location, and
static bool32 IsCurMapReloadLocation(void)
{
return IsCurMapInLocationList(gSaveLocationReloadLocList);
return IsCurMapInLocationList(sSaveLocationReloadLocList);
}
// nulled out list. unknown what this would have been
static const u16 gUnknown_0861440E[] =
static const u16 sUnknown_0861440E[] =
{
0xFFFF,
};
bool32 sub_81AFCEC(void)
{
return IsCurMapInLocationList(gUnknown_0861440E);
return IsCurMapInLocationList(sUnknown_0861440E);
}
static void TrySetPokeCenterWarpStatus(void)

File diff suppressed because it is too large Load Diff

View File

@@ -134,12 +134,12 @@ const u8 *ScriptPop(struct ScriptContext *ctx)
return ctx->stack[ctx->stackDepth];
}
void ScriptJump(struct ScriptContext *ctx, u8 *ptr)
void ScriptJump(struct ScriptContext *ctx, const u8 *ptr)
{
ctx->scriptPtr = ptr;
}
void ScriptCall(struct ScriptContext *ctx, u8 *ptr)
void ScriptCall(struct ScriptContext *ctx, const u8 *ptr)
{
ScriptPush(ctx, ctx->scriptPtr);
ctx->scriptPtr = ptr;

View File

@@ -170,13 +170,13 @@ extern const u8 gText_BattlePyramidFloor[];
void DisplayPyramidFloorWindow(void)
{
// TODO: fix location
if (*(u16*)(&gSaveBlock2Ptr->field_CAA[8]) == 7)
if (gSaveBlock2Ptr->field_CAA[4] == 7)
sBattlePyramidFloorWindowId = AddWindow(&gPyramidFloorWindowTemplate_1);
else
sBattlePyramidFloorWindowId = AddWindow(&gPyramidFloorWindowTemplate_2);
PutWindowTilemap(sBattlePyramidFloorWindowId);
sub_81973FC(sBattlePyramidFloorWindowId, 0);
StringCopy(gStringVar1, gUnknown_08510510[*(u16*)(&gSaveBlock2Ptr->field_CAA[8])]);
StringCopy(gStringVar1, gUnknown_08510510[gSaveBlock2Ptr->field_CAA[4]]);
StringExpandPlaceholders(gStringVar4, gText_BattlePyramidFloor);
PrintTextOnWindow(sBattlePyramidFloorWindowId, 1, gStringVar4, 0, 1, 0xFF, NULL);
CopyWindowToVram(sBattlePyramidFloorWindowId, 2);

View File

@@ -625,7 +625,7 @@ u8 *WriteColorChangeControlCode(u8 *dest, u32 colorType, u8 color)
return dest;
}
bool32 sub_8009228(u8 *str)
bool32 IsStringJapanese(u8 *str)
{
while (*str != EOS)
{

View File

@@ -145,7 +145,7 @@ void DeactivateAllTextPrinters (void)
gTextPrinters[printer].sub_union.sub.active = 0;
}
u16 PrintTextOnWindow(u8 windowId, u8 fontId, u8 *str, u8 x, u8 y, u8 speed, void (*callback)(struct TextSubPrinter *, u16))
u16 PrintTextOnWindow(u8 windowId, u8 fontId, const u8 *str, u8 x, u8 y, u8 speed, void (*callback)(struct TextSubPrinter *, u16))
{
struct TextSubPrinter subPrinter;

7927
src/tv.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -112,7 +112,7 @@ static const u16 sCrc16Table[] =
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78,
};
const u8 gMiscBlank_Gfx[] = INCBIN_U8("graphics/interface/blank.4bpp"); // unused in Emerald
const u8 gMiscBlank_Gfx[] = INCBIN_U8("graphics/interface/blank.4bpp");
u8 CreateInvisibleSpriteWithCallback(void (*callback)(struct Sprite *))
{