Hopefully illusion works as intended now

This commit is contained in:
DizzyEggg 2020-06-28 19:45:48 +02:00
parent 5d037198b3
commit 3bdf675221
9 changed files with 78 additions and 16 deletions

View file

@ -407,6 +407,8 @@ B_ATK_TEAM2 = FD 38
B_DEF_NAME = FD 39 B_DEF_NAME = FD 39
B_DEF_TEAM1 = FD 3A B_DEF_TEAM1 = FD 3A
B_DEF_TEAM2 = FD 3B B_DEF_TEAM2 = FD 3B
B_ACTIVE_NAME = FD 3C
B_ACTIVE_NAME2 = FD 3D @ no Illusion check
@ indicates the end of a town/city name (before " TOWN" or " CITY") @ indicates the end of a town/city name (before " TOWN" or " CITY")
NAME_END = FC 00 NAME_END = FC 00

View file

@ -4946,6 +4946,7 @@ BattleScript_FaintedMonTryChooseAnother:
jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_x400000, BattleScript_FaintedMonChooseAnother jumpifword CMP_COMMON_BITS, gHitMarker, HITMARKER_x400000, BattleScript_FaintedMonChooseAnother
jumpifbyte CMP_EQUAL, sBATTLE_STYLE, 0x1, BattleScript_FaintedMonChooseAnother jumpifbyte CMP_EQUAL, sBATTLE_STYLE, 0x1, BattleScript_FaintedMonChooseAnother
jumpifcantswitch BS_PLAYER1, BattleScript_FaintedMonChooseAnother jumpifcantswitch BS_PLAYER1, BattleScript_FaintedMonChooseAnother
setbyte sILLUSION_NICK_HACK, 1
printstring STRINGID_ENEMYABOUTTOSWITCHPKMN printstring STRINGID_ENEMYABOUTTOSWITCHPKMN
setbyte gBattleCommunication, 0x0 setbyte gBattleCommunication, 0x0
yesnobox yesnobox

View file

@ -429,9 +429,10 @@ struct MegaEvolutionData
struct Illusion struct Illusion
{ {
u8 on:1; u8 on;
u8 broken:1; u8 set;
u8 partyId:3; u8 broken;
u8 partyId;
struct Pokemon *mon; struct Pokemon *mon;
}; };
@ -616,6 +617,7 @@ struct BattleScripting
u16 savedMoveEffect; // For moves hitting multiple targets. u16 savedMoveEffect; // For moves hitting multiple targets.
u16 moveEffect; u16 moveEffect;
u16 multihitMoveEffect; u16 multihitMoveEffect;
u8 illusionNickHack; // To properly display nick in STRINGID_ENEMYABOUTTOSWITCHPKMN.
}; };
// rom_80A5C6C // rom_80A5C6C

View file

@ -64,6 +64,8 @@
#define B_TXT_DEF_NAME 0x39 #define B_TXT_DEF_NAME 0x39
#define B_TXT_DEF_TEAM1 0x3A // Your/The opposing #define B_TXT_DEF_TEAM1 0x3A // Your/The opposing
#define B_TXT_DEF_TEAM2 0x3B // your/the opposing #define B_TXT_DEF_TEAM2 0x3B // your/the opposing
#define B_TXT_ACTIVE_NAME 0x3C
#define B_TXT_ACTIVE_NAME2 0x3D // no Illusion check
// for B_TXT_BUFF1, B_TXT_BUFF2 and B_TXT_BUFF3 // for B_TXT_BUFF1, B_TXT_BUFF2 and B_TXT_BUFF3

View file

@ -34,6 +34,7 @@
#define sSAVED_MOVE_EFFECT gBattleScripting + 0x2C #define sSAVED_MOVE_EFFECT gBattleScripting + 0x2C
#define sMOVE_EFFECT gBattleScripting + 0x2E #define sMOVE_EFFECT gBattleScripting + 0x2E
#define sMULTIHIT_EFFECT gBattleScripting + 0x30 #define sMULTIHIT_EFFECT gBattleScripting + 0x30
#define sILLUSION_NICK_HACK gBattleScripting + 0x32
#define cMULTISTRING_CHOOSER gBattleCommunication + 5 #define cMULTISTRING_CHOOSER gBattleCommunication + 5

View file

@ -411,7 +411,7 @@ bool8 TryHandleLaunchBattleTableAnimation(u8 activeBattler, u8 atkBattler, u8 de
} }
if (tableId == B_ANIM_ILLUSION_OFF) if (tableId == B_ANIM_ILLUSION_OFF)
ClearIllusionMon(activeBattler); gBattleStruct->illusion[activeBattler].broken = 1;
gBattleAnimAttacker = atkBattler; gBattleAnimAttacker = atkBattler;
gBattleAnimTarget = defBattler; gBattleAnimTarget = defBattler;
@ -1158,11 +1158,6 @@ void ClearTemporarySpeciesSpriteData(u8 battlerId, bool8 dontClearSubstitute)
gBattleMonForms[battlerId] = 0; gBattleMonForms[battlerId] = 0;
if (!dontClearSubstitute) if (!dontClearSubstitute)
ClearBehindSubstituteBit(battlerId); ClearBehindSubstituteBit(battlerId);
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
SetIllusionMon(&gPlayerParty[gBattlerPartyIndexes[battlerId]], battlerId);
else
SetIllusionMon(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId);
} }
void AllocateMonSpritesGfx(void) void AllocateMonSpritesGfx(void)

View file

@ -2971,6 +2971,7 @@ void SwitchInClearSetData(void)
s32 i; s32 i;
struct DisableStruct disableStructCopy = gDisableStructs[gActiveBattler]; struct DisableStruct disableStructCopy = gDisableStructs[gActiveBattler];
ClearIllusionMon(gActiveBattler);
if (gBattleMoves[gCurrentMove].effect != EFFECT_BATON_PASS) if (gBattleMoves[gCurrentMove].effect != EFFECT_BATON_PASS)
{ {
for (i = 0; i < NUM_BATTLE_STATS; i++) for (i = 0; i < NUM_BATTLE_STATS; i++)

View file

@ -19,6 +19,7 @@
#include "text.h" #include "text.h"
#include "trainer_hill.h" #include "trainer_hill.h"
#include "window.h" #include "window.h"
#include "constants/abilities.h"
#include "constants/battle_string_ids.h" #include "constants/battle_string_ids.h"
#include "constants/frontier_util.h" #include "constants/frontier_util.h"
#include "constants/items.h" #include "constants/items.h"
@ -1529,7 +1530,7 @@ const u8 gText_PkmnIsEvolving[] = _("What?\n{STR_VAR_1} is evolving!");
const u8 gText_CongratsPkmnEvolved[] = _("Congratulations! Your {STR_VAR_1}\nevolved into {STR_VAR_2}!{WAIT_SE}\p"); const u8 gText_CongratsPkmnEvolved[] = _("Congratulations! Your {STR_VAR_1}\nevolved into {STR_VAR_2}!{WAIT_SE}\p");
const u8 gText_PkmnStoppedEvolving[] = _("Huh? {STR_VAR_1}\nstopped evolving!\p"); const u8 gText_PkmnStoppedEvolving[] = _("Huh? {STR_VAR_1}\nstopped evolving!\p");
const u8 gText_EllipsisQuestionMark[] = _("……?\p"); const u8 gText_EllipsisQuestionMark[] = _("……?\p");
const u8 gText_WhatWillPkmnDo[] = _("What will\n{B_ACTIVE_NAME_WITH_PREFIX} do?"); const u8 gText_WhatWillPkmnDo[] = _("What will\n{B_ACTIVE_NAME2} do?");
const u8 gText_WhatWillPkmnDo2[] = _("What will\n{B_PLAYER_NAME} do?"); const u8 gText_WhatWillPkmnDo2[] = _("What will\n{B_PLAYER_NAME} do?");
const u8 gText_WhatWillWallyDo[] = _("What will\nWALLY do?"); const u8 gText_WhatWillWallyDo[] = _("What will\nWALLY do?");
const u8 gText_LinkStandby[] = _("{PAUSE 16}Link standby…"); const u8 gText_LinkStandby[] = _("{PAUSE 16}Link standby…");
@ -2919,6 +2920,18 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
GetBattlerNick(gBattlerTarget, text); GetBattlerNick(gBattlerTarget, text);
toCpy = text; toCpy = text;
break; break;
case B_TXT_ACTIVE_NAME: // active name
GetBattlerNick(gActiveBattler, text);
toCpy = text;
break;
case B_TXT_ACTIVE_NAME2: // active battlerId name with prefix, no illusion
if (GetBattlerSide(gActiveBattler) == B_SIDE_PLAYER)
GetMonData(&gPlayerParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_NICKNAME, text);
else
GetMonData(&gEnemyParty[gBattlerPartyIndexes[gActiveBattler]], MON_DATA_NICKNAME, text);
StringGetEnd10(text);
toCpy = text;
break;
case B_TXT_EFF_NAME_WITH_PREFIX: // effect battlerId name with prefix case B_TXT_EFF_NAME_WITH_PREFIX: // effect battlerId name with prefix
HANDLE_NICKNAME_STRING_CASE(gEffectBattler) HANDLE_NICKNAME_STRING_CASE(gEffectBattler)
break; break;
@ -3234,6 +3247,37 @@ u32 BattleStringExpandPlaceholders(const u8 *src, u8 *dst)
return dstID; return dstID;
} }
static void IllusionNickHack(u32 battlerId, u32 partyId, u8 *dst)
{
s32 id, i;
// we know it's gEnemyParty
struct Pokemon *mon = &gEnemyParty[partyId], *partnerMon;
if (GetMonAbility(mon) == ABILITY_ILLUSION)
{
if (IsBattlerAlive(BATTLE_PARTNER(battlerId)))
partnerMon = &gEnemyParty[gBattlerPartyIndexes[BATTLE_PARTNER(battlerId)]];
else
partnerMon = mon;
// Find last alive non-egg pokemon.
for (i = PARTY_SIZE - 1; i >= 0; i--)
{
id = i;
if (GetMonData(&gEnemyParty[id], MON_DATA_SANITY_HAS_SPECIES)
&& GetMonData(&gEnemyParty[id], MON_DATA_HP)
&& &gEnemyParty[id] != mon
&& &gEnemyParty[id] != partnerMon)
{
GetMonData(&gEnemyParty[id], MON_DATA_NICKNAME, dst);
return;
}
}
}
GetMonData(mon, MON_DATA_NICKNAME, dst);
}
static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst) static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst)
{ {
u32 srcID = 1; u32 srcID = 1;
@ -3306,6 +3350,12 @@ static void ExpandBattleTextBuffPlaceholders(const u8 *src, u8 *dst)
{ {
GetBattlerNick(src[srcID + 1], dst); GetBattlerNick(src[srcID + 1], dst);
} }
else if (gBattleScripting.illusionNickHack) // for STRINGID_ENEMYABOUTTOSWITCHPKMN
{
gBattleScripting.illusionNickHack = 0;
IllusionNickHack(src[srcID + 1], src[srcID + 2], dst);
StringGetEnd10(dst);
}
else else
{ {
if (GetBattlerSide(src[srcID + 1]) == B_SIDE_PLAYER) if (GetBattlerSide(src[srcID + 1]) == B_SIDE_PLAYER)

View file

@ -3802,7 +3802,7 @@ u8 AbilityBattleEffects(u8 caseID, u8 battler, u8 ability, u8 special, u16 moveA
} }
break; break;
case ABILITY_ILLUSION: case ABILITY_ILLUSION:
if (gBattleStruct->illusion[battler].on && !gBattleStruct->illusion[battler].broken && IsBattlerAlive(battler) && TARGET_TURN_DAMAGED) if (gBattleStruct->illusion[gBattlerTarget].on && !gBattleStruct->illusion[gBattlerTarget].broken && TARGET_TURN_DAMAGED)
{ {
BattleScriptPushCursor(); BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_IllusionOff; gBattlescriptCurrInstr = BattleScript_IllusionOff;
@ -6750,7 +6750,16 @@ bool32 CanBattlerGetOrLoseItem(u8 battlerId, u16 itemId)
struct Pokemon *GetIllusionMonPtr(u32 battlerId) struct Pokemon *GetIllusionMonPtr(u32 battlerId)
{ {
if (!gBattleStruct->illusion[battlerId].on || gBattleStruct->illusion[battlerId].broken) if (gBattleStruct->illusion[battlerId].broken)
return NULL;
if (!gBattleStruct->illusion[battlerId].set)
{
if (GetBattlerSide(battlerId) == B_SIDE_PLAYER)
SetIllusionMon(&gPlayerParty[gBattlerPartyIndexes[battlerId]], battlerId);
else
SetIllusionMon(&gEnemyParty[gBattlerPartyIndexes[battlerId]], battlerId);
}
if (!gBattleStruct->illusion[battlerId].on)
return NULL; return NULL;
return gBattleStruct->illusion[battlerId].mon; return gBattleStruct->illusion[battlerId].mon;
@ -6758,9 +6767,7 @@ struct Pokemon *GetIllusionMonPtr(u32 battlerId)
void ClearIllusionMon(u32 battlerId) void ClearIllusionMon(u32 battlerId)
{ {
gBattleStruct->illusion[battlerId].on = 0; memset(&gBattleStruct->illusion[battlerId], 0, sizeof(gBattleStruct->illusion[battlerId]));
gBattleStruct->illusion[battlerId].mon = NULL;
gBattleStruct->illusion[battlerId].broken = 1;
} }
bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId) bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId)
@ -6768,6 +6775,7 @@ bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId)
struct Pokemon *party, *partnerMon; struct Pokemon *party, *partnerMon;
s32 i, id; s32 i, id;
gBattleStruct->illusion[battlerId].set = 1;
if (GetMonAbility(mon) != ABILITY_ILLUSION) if (GetMonAbility(mon) != ABILITY_ILLUSION)
return FALSE; return FALSE;
@ -6784,7 +6792,7 @@ bool32 SetIllusionMon(struct Pokemon *mon, u32 battlerId)
// Find last alive non-egg pokemon. // Find last alive non-egg pokemon.
for (i = PARTY_SIZE - 1; i >= 0; i--) for (i = PARTY_SIZE - 1; i >= 0; i--)
{ {
id = GetPartyIdFromBattlePartyId(i); id = i;
if (GetMonData(&party[id], MON_DATA_SANITY_HAS_SPECIES) if (GetMonData(&party[id], MON_DATA_SANITY_HAS_SPECIES)
&& GetMonData(&party[id], MON_DATA_HP) && GetMonData(&party[id], MON_DATA_HP)
&& &party[id] != mon && &party[id] != mon