Skip to content

Commit

Permalink
add script command
Browse files Browse the repository at this point in the history
  • Loading branch information
ghoulslash committed Sep 1, 2020
1 parent 5773bb8 commit 9a628c5
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 1 deletion.
118 changes: 117 additions & 1 deletion asm/macros/event.inc
Expand Up @@ -1606,7 +1606,123 @@
.2byte \item
.2byte \quantity
.endm

.macro givecustommon species:req, level:req, item, ball, nature, abilityNum, hpEv, atkEv, defEv, speedEv, spAtkEv, spDefEv, hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv, move1, move2, move3, move4, isShiny
.byte 0xe3
.2byte \species
.byte \level
.ifb \item
.2byte ITEM_NONE
.else
.2byte \item
.endif
.ifb \ball
.byte 0
.else
.byte \ball
.endif
.ifb \nature
.byte NUM_NATURES
.else
.byte \nature
.endif
.ifb \abilityNum
.byte 3
.else
.byte \abilityNum
.endif
@evs
.ifb \hpEv
.byte 0
.else
.byte \hpEv
.endif
.ifb \atkEv
.byte 0
.else
.byte \atkEv
.endif
.ifb \defEv
.byte 0
.else
.byte \defEv
.endif
.ifb \speedEv
.byte 0
.else
.byte \speedEv
.endif
.ifb \spAtkEv
.byte 0
.else
.byte \spAtkEv
.endif
.ifb \spDefEv
.byte 0
.else
.byte \spDefEv
.endif
@ivs
.ifb \hpIv
.byte 32
.else
.byte \hpIv
.endif
.ifb \atkIv
.byte 32
.else
.byte \atkIv
.endif
.ifb \defIv
.byte 32
.else
.byte \defIv
.endif
.ifb \speedIv
.byte 32
.else
.byte \speedIv
.endif
.ifb \spAtkIv
.byte 32
.else
.byte \spAtkIv
.endif
.ifb \spDefIv
.byte 32
.else
.byte \spDefIv
.endif
.ifb \move1
.2byte 0
.else
.2byte \move1
.endif
.ifb \move2
.2byte 0
.else
.2byte \move2
.endif
.ifb \move3
.2byte 0
.else
.2byte \move3
.endif
.ifb \move4
.2byte 0
.else
.2byte \move4
.endif
.ifb \isShiny
.byte 0
.else
.byte \isShiny
.endif
.endm
.macro givemonmoves species:req, level:req, move1:req, move2:req, move3:req, move4:req
customgivemon \species, \level, 0, 0, NUM_NATURES, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \move1, \move2, \move3, \move4, 0
.endm

@ Supplementary

Expand Down
1 change: 1 addition & 0 deletions data/script_cmd_table.inc
Expand Up @@ -227,6 +227,7 @@ gScriptCmdTable:: @ 81DB67C
.4byte ScrCmd_warpsootopolislegend
.4byte ScrCmd_buffercontesttype
.4byte ScrCmd_bufferitemnameplural
.4byte ScrCmd_givecustommon

gScriptCmdTableEnd:: @ 81DBA08
.4byte ScrCmd_nop
1 change: 1 addition & 0 deletions include/pokemon.h
Expand Up @@ -416,5 +416,6 @@ bool8 HasTwoFramesAnimation(u16 species);
struct Unknown_806F160_Struct *sub_806F2AC(u8 id, u8 arg1);
void sub_806F47C(u8 id);
u8 *sub_806F4F8(u8 id, u8 arg1);
void CreateShinyMonWithNature(struct Pokemon *mon, u16 species, u8 level, u8 nature);

#endif // GUARD_POKEMON_H
1 change: 1 addition & 0 deletions include/script_pokemon_util.h
Expand Up @@ -7,5 +7,6 @@ void CreateScriptedWildMon(u16, u8, u16);
void ScriptSetMonMoveSlot(u8, u16, u8);
void ReducePlayerPartyToSelectedMons(void);
void HealPlayerParty(void);
u8 ScriptGiveCustomMon(u16 species, u8 level, u16 item, u8 ball, u8 nature, u8 abilityNum, u8 *evs, u8 *ivs, u16 *moves, bool8 isShiny);

#endif // GUARD_SCRIPT_POKEMON_UTIL
17 changes: 17 additions & 0 deletions src/pokemon.c
Expand Up @@ -6980,3 +6980,20 @@ u8 *sub_806F4F8(u8 id, u8 arg1)
return structPtr->byteArrays[arg1];
}
}

void CreateShinyMonWithNature(struct Pokemon *mon, u16 species, u8 level, u8 nature)
{
u32 personality;
u32 otid = gSaveBlock2Ptr->playerTrainerId[0]
| (gSaveBlock2Ptr->playerTrainerId[1] << 8)
| (gSaveBlock2Ptr->playerTrainerId[2] << 16)
| (gSaveBlock2Ptr->playerTrainerId[3] << 24);

do
{
personality = Random32();
personality = ((((Random() % 8) ^ (HIHALF(otid) ^ LOHALF(otid))) ^ LOHALF(personality)) << 16) | LOHALF(personality);
} while (nature != GetNatureFromPersonality(personality));

CreateMon(mon, species, level, 32, 1, personality, OT_ID_PRESET, otid);
}
35 changes: 35 additions & 0 deletions src/scrcmd.c
Expand Up @@ -2302,3 +2302,38 @@ bool8 ScrCmd_warpsootopolislegend(struct ScriptContext *ctx)
ResetInitialPlayerAvatarState();
return TRUE;
}

bool8 ScrCmd_givecustommon(struct ScriptContext *ctx)
{
u16 species = ScriptReadHalfword(ctx);
u8 level = ScriptReadByte(ctx);
u16 item = ScriptReadHalfword(ctx);
u8 ball = ScriptReadByte(ctx);
u8 nature = ScriptReadByte(ctx);
u8 abilityNum = ScriptReadByte(ctx);
u8 hpEv = ScriptReadByte(ctx);
u8 atkEv = ScriptReadByte(ctx);
u8 defEv = ScriptReadByte(ctx);
u8 speedEv = ScriptReadByte(ctx);
u8 spAtkEv = ScriptReadByte(ctx);
u8 spDefEv = ScriptReadByte(ctx);
u8 hpIv = ScriptReadByte(ctx);
u8 atkIv = ScriptReadByte(ctx);
u8 defIv = ScriptReadByte(ctx);
u8 speedIv = ScriptReadByte(ctx);
u8 spAtkIv = ScriptReadByte(ctx);
u8 spDefIv = ScriptReadByte(ctx);
u16 move1 = ScriptReadHalfword(ctx);
u16 move2 = ScriptReadHalfword(ctx);
u16 move3 = ScriptReadHalfword(ctx);
u16 move4 = ScriptReadHalfword(ctx);
bool8 isShiny = ScriptReadByte(ctx);

u8 evs[NUM_STATS] = {hpEv, atkEv, defEv, speedEv, spAtkEv, spDefEv};
u8 ivs[NUM_STATS] = {hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv};
u16 moves[4] = {move1, move2, move3, move4};

gSpecialVar_Result = ScriptGiveCustomMon(species, level, item, ball, nature, abilityNum, evs, ivs, moves, isShiny);
return FALSE;
}

100 changes: 100 additions & 0 deletions src/script_pokemon_util.c
Expand Up @@ -14,6 +14,7 @@
#include "overworld.h"
#include "palette.h"
#include "party_menu.h"
#include "pokeball.h"
#include "pokedex.h"
#include "pokemon.h"
#include "random.h"
Expand Down Expand Up @@ -222,3 +223,102 @@ void ReducePlayerPartyToSelectedMons(void)

CalculatePlayerPartyCount();
}

u8 ScriptGiveCustomMon(u16 species, u8 level, u16 item, u8 ball, u8 nature, u8 abilityNum, u8 *evs, u8 *ivs, u16 *moves, bool8 isShiny)
{
u16 nationalDexNum;
int sentToPc;
u8 heldItem[2];
struct Pokemon mon;
u8 i;
u8 evTotal = 0;

if (nature == NUM_NATURES || nature == 0xFF)
nature = Random() % NUM_NATURES;

if (isShiny)
CreateShinyMonWithNature(&mon, species, level, nature);
else
CreateMonWithNature(&mon, species, level, 32, nature);

for (i = 0; i < NUM_STATS; i++)
{
// ev
if (evs[i] != 0xFF && evTotal < 510)
{
// only up to 510 evs
if ((evTotal + evs[i]) > 510)
evs[i] = (510 - evTotal);

evTotal += evs[i];
SetMonData(&mon, MON_DATA_HP_EV + i, &evs[i]);
}

// iv
if (ivs[i] != 32 && ivs[i] != 0xFF)
SetMonData(&mon, MON_DATA_HP_IV + i, &ivs[i]);
}
CalculateMonStats(&mon);

for (i = 0; i < MAX_MON_MOVES; i++)
{
if (moves[i] == 0 || moves[i] == 0xFF || moves[i] > MOVES_COUNT)
continue;

SetMonMoveSlot(&mon, moves[i], i);
}

//ability
if (abilityNum == 0xFF || GetAbilityBySpecies(species, abilityNum) == 0)
{
do {
abilityNum = Random() % 3; // includes hidden abilities
} while (GetAbilityBySpecies(species, abilityNum) == 0);
}

SetMonData(&mon, MON_DATA_ABILITY_NUM, &abilityNum);

//ball
if (ball <= POKEBALL_COUNT)
SetMonData(&mon, MON_DATA_POKEBALL, &ball);

//item
heldItem[0] = item;
heldItem[1] = item >> 8;
SetMonData(&mon, MON_DATA_HELD_ITEM, heldItem);

// give player the mon
//sentToPc = GiveMonToPlayer(&mon);
SetMonData(&mon, MON_DATA_OT_NAME, gSaveBlock2Ptr->playerName);
SetMonData(&mon, MON_DATA_OT_GENDER, &gSaveBlock2Ptr->playerGender);
for (i = 0; i < PARTY_SIZE; i++)
{
if (GetMonData(&gPlayerParty[i], MON_DATA_SPECIES, NULL) == SPECIES_NONE)
break;
}

if (i >= PARTY_SIZE)
{
sentToPc = SendMonToPC(&mon);
}
else
{
sentToPc = MON_GIVEN_TO_PARTY;
CopyMon(&gPlayerParty[i], &mon, sizeof(mon));
gPlayerPartyCount = i + 1;
}

nationalDexNum = SpeciesToNationalPokedexNum(species);
switch(sentToPc)
{
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;
}

0 comments on commit 9a628c5

Please sign in to comment.