Add createmon Script Cmd, Support for 2v1Wild Battles (#4688)
* add createmon and setwilddoubleflag script cmds to support createing mons at given player or enemy slots and setting up 2v1 battles * give givemon macro PARTY_SIZE for tests * style fixes * add createmon test --------- Co-authored-by: ghoulslash <pokevoyager0@gmail.com>
This commit is contained in:
parent
43310716af
commit
353727a805
5 changed files with 131 additions and 27 deletions
|
@ -997,7 +997,69 @@
|
|||
@ Gives the player a Pokémon of the specified species and level, and allows to customize extra parameters.
|
||||
@ VAR_RESULT will be set to MON_GIVEN_TO_PARTY, MON_GIVEN_TO_PC, or MON_CANT_GIVE depending on the outcome.
|
||||
.macro givemon species:req, level:req, item, ball, nature, abilityNum, gender, hpEv, atkEv, defEv, speedEv, spAtkEv, spDefEv, hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv, move1, move2, move3, move4, isShiny, ggMaxFactor, teraType
|
||||
callnative ScrCmd_givemon
|
||||
callnative ScrCmd_createmon
|
||||
.byte 0
|
||||
.byte 6 @ PARTY_SIZE - assign to first empty slot
|
||||
.set givemon_flags, 0
|
||||
.2byte \species
|
||||
.2byte \level
|
||||
.ifnb \item; .set givemon_flags, givemon_flags | (1 << 0); .endif
|
||||
.ifnb \ball; .set givemon_flags, givemon_flags | (1 << 1); .endif
|
||||
.ifnb \nature; .set givemon_flags, givemon_flags | (1 << 2); .endif
|
||||
.ifnb \abilityNum; .set givemon_flags, givemon_flags | (1 << 3); .endif
|
||||
.ifnb \gender; .set givemon_flags, givemon_flags | (1 << 4); .endif
|
||||
.ifnb \hpEv; .set givemon_flags, givemon_flags | (1 << 5); .endif
|
||||
.ifnb \atkEv; .set givemon_flags, givemon_flags | (1 << 6); .endif
|
||||
.ifnb \defEv; .set givemon_flags, givemon_flags | (1 << 7); .endif
|
||||
.ifnb \speedEv; .set givemon_flags, givemon_flags | (1 << 8); .endif
|
||||
.ifnb \spAtkEv; .set givemon_flags, givemon_flags | (1 << 9); .endif
|
||||
.ifnb \spDefEv; .set givemon_flags, givemon_flags | (1 << 10); .endif
|
||||
.ifnb \hpIv; .set givemon_flags, givemon_flags | (1 << 11); .endif
|
||||
.ifnb \atkIv; .set givemon_flags, givemon_flags | (1 << 12); .endif
|
||||
.ifnb \defIv; .set givemon_flags, givemon_flags | (1 << 13); .endif
|
||||
.ifnb \speedIv; .set givemon_flags, givemon_flags | (1 << 14); .endif
|
||||
.ifnb \spAtkIv; .set givemon_flags, givemon_flags | (1 << 15); .endif
|
||||
.ifnb \spDefIv; .set givemon_flags, givemon_flags | (1 << 16); .endif
|
||||
.ifnb \move1; .set givemon_flags, givemon_flags | (1 << 17); .endif
|
||||
.ifnb \move2; .set givemon_flags, givemon_flags | (1 << 18); .endif
|
||||
.ifnb \move3; .set givemon_flags, givemon_flags | (1 << 19); .endif
|
||||
.ifnb \move4; .set givemon_flags, givemon_flags | (1 << 20); .endif
|
||||
.ifnb \isShiny; .set givemon_flags, givemon_flags | (1 << 21); .endif
|
||||
.ifnb \ggMaxFactor; .set givemon_flags, givemon_flags | (1 << 22); .endif
|
||||
.ifnb \teraType; .set givemon_flags, givemon_flags | (1 << 23); .endif
|
||||
.4byte givemon_flags
|
||||
.ifnb \item; .2byte \item; .endif
|
||||
.ifnb \ball; .2byte \ball; .endif
|
||||
.ifnb \nature; .2byte \nature; .endif
|
||||
.ifnb \abilityNum; .2byte \abilityNum; .endif
|
||||
.ifnb \gender; .2byte \gender; .endif
|
||||
.ifnb \hpEv; .2byte \hpEv; .endif
|
||||
.ifnb \atkEv; .2byte \atkEv; .endif
|
||||
.ifnb \defEv; .2byte \defEv; .endif
|
||||
.ifnb \speedEv; .2byte \speedEv; .endif
|
||||
.ifnb \spAtkEv; .2byte \spAtkEv; .endif
|
||||
.ifnb \spDefEv; .2byte \spDefEv; .endif
|
||||
.ifnb \hpIv; .2byte \hpIv; .endif
|
||||
.ifnb \atkIv; .2byte \atkIv; .endif
|
||||
.ifnb \defIv; .2byte \defIv; .endif
|
||||
.ifnb \speedIv; .2byte \speedIv; .endif
|
||||
.ifnb \spAtkIv; .2byte \spAtkIv; .endif
|
||||
.ifnb \spDefIv; .2byte \spDefIv; .endif
|
||||
.ifnb \move1; .2byte \move1; .endif
|
||||
.ifnb \move2; .2byte \move2; .endif
|
||||
.ifnb \move3; .2byte \move3; .endif
|
||||
.ifnb \move4; .2byte \move4; .endif
|
||||
.ifnb \isShiny; .2byte \isShiny; .endif
|
||||
.ifnb \ggMaxFactor; .2byte \ggMaxFactor; .endif
|
||||
.ifnb \teraType; .2byte \teraType; .endif
|
||||
.endm
|
||||
|
||||
@ creates a mon for a given party and slot
|
||||
@ otherwise
|
||||
.macro createmon side:req, slot:req, species:req, level:req, item, ball, nature, abilityNum, gender, hpEv, atkEv, defEv, speedEv, spAtkEv, spDefEv, hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv, move1, move2, move3, move4, isShiny, ggMaxFactor, teraType
|
||||
callnative ScrCmd_createmon
|
||||
.byte \side @ 0 - player, 1 - opponent
|
||||
.byte \slot @ 0-5
|
||||
.set givemon_flags, 0
|
||||
.2byte \species
|
||||
.2byte \level
|
||||
|
@ -2233,3 +2295,9 @@
|
|||
.byte \sourceId
|
||||
.byte \targetId
|
||||
.endm
|
||||
|
||||
@ set the wild double battle flag
|
||||
@ can be used in conjunection with createmon to set up a wild battle with 2 player mons vs. 1 enemy mon
|
||||
.macro setwilddoubleflag
|
||||
callnative ScriptSetDoubleBattleFlag
|
||||
.endm
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define GUARD_SCRIPT_POKEMON_UTIL_H
|
||||
|
||||
u32 ScriptGiveMon(u16, u8, u16);
|
||||
u32 ScriptGiveMonParameterized(u16, u8, u16, u8, u8, u8, u8, u8 *, u8 *, u16 *, bool8, bool8, u8);
|
||||
u8 ScriptGiveEgg(u16);
|
||||
void CreateScriptedWildMon(u16, u8, u16);
|
||||
void CreateScriptedDoubleWildMon(u16, u8, u16, u16, u8, u16);
|
||||
|
|
|
@ -2467,3 +2467,8 @@ bool8 ScrCmd_warpwhitefade(struct ScriptContext *ctx)
|
|||
ResetInitialPlayerAvatarState();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void ScriptSetDoubleBattleFlag(struct ScriptContext *ctx)
|
||||
{
|
||||
sIsScriptedWildDouble = TRUE;
|
||||
}
|
||||
|
|
|
@ -313,7 +313,11 @@ void SetTeraType(struct ScriptContext *ctx)
|
|||
SetMonData(&gPlayerParty[partyIndex], MON_DATA_TERA_TYPE, &type);
|
||||
}
|
||||
|
||||
u32 ScriptGiveMonParameterized(u16 species, u8 level, u16 item, u8 ball, u8 nature, u8 abilityNum, u8 gender, u8 *evs, u8 *ivs, u16 *moves, bool8 isShiny, bool8 ggMaxFactor, u8 teraType)
|
||||
/* Creates a Pokemon via script
|
||||
* if side/slot are assigned, it will create the mon at the assigned party location
|
||||
* if slot == PARTY_SIZE, it will give the mon to first available party or storage slot
|
||||
*/
|
||||
static u32 ScriptGiveMonParameterized(u8 side, u8 slot, u16 species, u8 level, u16 item, u8 ball, u8 nature, u8 abilityNum, u8 gender, u8 *evs, u8 *ivs, u16 *moves, bool8 isShiny, bool8 ggMaxFactor, u8 teraType)
|
||||
{
|
||||
u16 nationalDexNum;
|
||||
int sentToPc;
|
||||
|
@ -408,6 +412,16 @@ u32 ScriptGiveMonParameterized(u16 species, u8 level, u16 item, u8 ball, u8 natu
|
|||
SetMonData(&mon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName);
|
||||
SetMonData(&mon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender);
|
||||
|
||||
if (slot < PARTY_SIZE)
|
||||
{
|
||||
if (side == 0)
|
||||
CopyMon(&gPlayerParty[slot], &mon, sizeof(struct Pokemon));
|
||||
else
|
||||
CopyMon(&gEnemyParty[slot], &mon, sizeof(struct Pokemon));
|
||||
sentToPc = MON_GIVEN_TO_PARTY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// find empty party slot to decide whether the Pokémon goes to the Player's party or the storage system.
|
||||
for (i = 0; i < PARTY_SIZE; i++)
|
||||
{
|
||||
|
@ -424,18 +438,17 @@ u32 ScriptGiveMonParameterized(u16 species, u8 level, u16 item, u8 ball, u8 natu
|
|||
CopyMon(&gPlayerParty[i], &mon, sizeof(mon));
|
||||
gPlayerPartyCount = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (side == 0)
|
||||
{
|
||||
// set pokédex flags
|
||||
nationalDexNum = SpeciesToNationalPokedexNum(species);
|
||||
switch (sentToPc)
|
||||
if (sentToPc != MON_CANT_GIVE)
|
||||
{
|
||||
case MON_GIVEN_TO_PARTY:
|
||||
case MON_GIVEN_TO_PC:
|
||||
GetSetPokedexFlag(nationalDexNum, FLAG_SET_SEEN);
|
||||
GetSetPokedexFlag(nationalDexNum, FLAG_SET_CAUGHT);
|
||||
break;
|
||||
case MON_CANT_GIVE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return sentToPc;
|
||||
|
@ -448,13 +461,17 @@ u32 ScriptGiveMon(u16 species, u8 level, u16 item)
|
|||
MAX_PER_STAT_IVS + 1, MAX_PER_STAT_IVS + 1, MAX_PER_STAT_IVS + 1}; // ScriptGiveMonParameterized won't touch the stats' IV.
|
||||
u16 moves[MAX_MON_MOVES] = {MOVE_NONE, MOVE_NONE, MOVE_NONE, MOVE_NONE};
|
||||
|
||||
return ScriptGiveMonParameterized(species, level, item, ITEM_POKE_BALL, NUM_NATURES, NUM_ABILITY_PERSONALITY, MON_GENDERLESS, evs, ivs, moves, FALSE, FALSE, NUMBER_OF_MON_TYPES);
|
||||
return ScriptGiveMonParameterized(0, PARTY_SIZE, species, level, item, ITEM_POKE_BALL, NUM_NATURES, NUM_ABILITY_PERSONALITY, MON_GENDERLESS, evs, ivs, moves, FALSE, FALSE, NUMBER_OF_MON_TYPES);
|
||||
}
|
||||
|
||||
#define PARSE_FLAG(n, default_) (flags & (1 << (n))) ? VarGet(ScriptReadHalfword(ctx)) : (default_)
|
||||
|
||||
void ScrCmd_givemon(struct ScriptContext *ctx)
|
||||
/* Give or create a mon to either player or opponent
|
||||
*/
|
||||
void ScrCmd_createmon(struct ScriptContext *ctx)
|
||||
{
|
||||
u8 side = ScriptReadByte(ctx);
|
||||
u8 slot = ScriptReadByte(ctx);
|
||||
u16 species = VarGet(ScriptReadHalfword(ctx));
|
||||
u8 level = VarGet(ScriptReadHalfword(ctx));
|
||||
|
||||
|
@ -488,7 +505,7 @@ void ScrCmd_givemon(struct ScriptContext *ctx)
|
|||
u8 ivs[NUM_STATS] = {hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv};
|
||||
u16 moves[MAX_MON_MOVES] = {move1, move2, move3, move4};
|
||||
|
||||
gSpecialVar_Result = ScriptGiveMonParameterized(species, level, item, ball, nature, abilityNum, gender, evs, ivs, moves, isShiny, ggMaxFactor, teraType);
|
||||
gSpecialVar_Result = ScriptGiveMonParameterized(side, slot, species, level, item, ball, nature, abilityNum, gender, evs, ivs, moves, isShiny, ggMaxFactor, teraType);
|
||||
}
|
||||
|
||||
#undef PARSE_FLAG
|
||||
|
|
|
@ -340,3 +340,18 @@ TEST("checkteratype/setteratype work")
|
|||
);
|
||||
EXPECT(VarGet(VAR_RESULT) == TYPE_FIRE);
|
||||
}
|
||||
|
||||
TEST("createmon [simple]")
|
||||
{
|
||||
ZeroPlayerPartyMons();
|
||||
|
||||
RUN_OVERWORLD_SCRIPT(
|
||||
createmon 1, 0, SPECIES_WOBBUFFET, 100;
|
||||
createmon 1, 1, SPECIES_WYNAUT, 10;
|
||||
);
|
||||
|
||||
EXPECT_EQ(GetMonData(&gEnemyParty[0], MON_DATA_SPECIES), SPECIES_WOBBUFFET);
|
||||
EXPECT_EQ(GetMonData(&gEnemyParty[0], MON_DATA_LEVEL), 100);
|
||||
EXPECT_EQ(GetMonData(&gEnemyParty[1], MON_DATA_SPECIES), SPECIES_WYNAUT);
|
||||
EXPECT_EQ(GetMonData(&gEnemyParty[1], MON_DATA_LEVEL), 10);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue