Fixes shininess for givemon (#7847)

This commit is contained in:
cawtds 2025-10-07 23:16:48 +02:00 committed by GitHub
parent 93661eeb39
commit c64c276d77
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 38 additions and 28 deletions

View File

@ -986,7 +986,7 @@
@ 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, gmaxFactor, teraType, dmaxLevel
.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, shinyMode, gmaxFactor, teraType, dmaxLevel
callnative ScrCmd_createmon, requests_effects=1
.byte 0
.byte PARTY_SIZE @ assign to first empty slot
@ -1014,7 +1014,7 @@
.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 \shinyMode; .set givemon_flags, givemon_flags | (1 << 21); .endif
.ifnb \gmaxFactor; .set givemon_flags, givemon_flags | (1 << 22); .endif
.ifnb \teraType; .set givemon_flags, givemon_flags | (1 << 23); .endif
.ifnb \dmaxLevel; .set givemon_flags, givemon_flags | (1 << 24); .endif
@ -1040,7 +1040,7 @@
.ifnb \move2; .2byte \move2; .endif
.ifnb \move3; .2byte \move3; .endif
.ifnb \move4; .2byte \move4; .endif
.ifnb \isShiny; .2byte \isShiny; .endif
.ifnb \shinyMode; .2byte \shinyMode; .endif
.ifnb \gmaxFactor; .2byte \gmaxFactor; .endif
.ifnb \teraType; .2byte \teraType; .endif
.ifnb \dmaxLevel; .2byte \dmaxLevel; .endif
@ -1048,7 +1048,7 @@
@ 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, gmaxFactor, teraType, dmaxLevel
.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, shinyMode, gmaxFactor, teraType, dmaxLevel
callnative ScrCmd_createmon, requests_effects=1
.byte \side @ 0 - player, 1 - opponent
.byte \slot @ 0-5
@ -1076,7 +1076,7 @@
.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 \shinyMode; .set givemon_flags, givemon_flags | (1 << 21); .endif
.ifnb \gmaxFactor; .set givemon_flags, givemon_flags | (1 << 22); .endif
.ifnb \teraType; .set givemon_flags, givemon_flags | (1 << 23); .endif
.ifnb \dmaxLevel; .set givemon_flags, givemon_flags | (1 << 24); .endif
@ -1102,7 +1102,7 @@
.ifnb \move2; .2byte \move2; .endif
.ifnb \move3; .2byte \move3; .endif
.ifnb \move4; .2byte \move4; .endif
.ifnb \isShiny; .2byte \isShiny; .endif
.ifnb \shinyMode; .2byte \shinyMode; .endif
.ifnb \gmaxFactor; .2byte \gmaxFactor; .endif
.ifnb \teraType; .2byte \teraType; .endif
.ifnb \dmaxLevel; .2byte \dmaxLevel; .endif

View File

@ -347,6 +347,12 @@ enum EvoSpinDirections {
SPIN_EITHER, // Player spins either clockwise or counter-clockwise
};
enum ShinyMode {
SHINY_MODE_ALWAYS,
SHINY_MODE_RANDOM,
SHINY_MODE_NEVER
};
#define MON_PIC_WIDTH 64
#define MON_PIC_HEIGHT 64
#define MON_PIC_SIZE (MON_PIC_WIDTH * MON_PIC_HEIGHT / 2)

View File

@ -332,7 +332,7 @@ void SetTeraType(struct ScriptContext *ctx)
* 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, enum PokeBall ball, u8 nature, u8 abilityNum, u8 gender, u8 *evs, u8 *ivs, u16 *moves, bool8 isShiny, bool8 gmaxFactor, u8 teraType, u8 dmaxLevel)
static u32 ScriptGiveMonParameterized(u8 side, u8 slot, u16 species, u8 level, u16 item, enum PokeBall ball, u8 nature, u8 abilityNum, u8 gender, u8 *evs, u8 *ivs, u16 *moves, enum ShinyMode shinyMode, bool8 gmaxFactor, u8 teraType, u8 dmaxLevel)
{
enum NationalDexOrder nationalDexNum;
int sentToPc;
@ -340,6 +340,7 @@ static u32 ScriptGiveMonParameterized(u8 side, u8 slot, u16 species, u8 level, u
u32 i;
u8 genderRatio = gSpeciesInfo[species].genderRatio;
u16 targetSpecies;
bool32 isShiny;
// check whether to use a specific nature or a random one
if (nature >= NUM_NATURES)
@ -360,10 +361,13 @@ static u32 ScriptGiveMonParameterized(u8 side, u8 slot, u16 species, u8 level, u
CreateMonWithNature(&mon, species, level, 32, nature);
// shininess
if (P_FLAG_FORCE_SHINY != 0 && FlagGet(P_FLAG_FORCE_SHINY))
if (shinyMode == SHINY_MODE_ALWAYS || (P_FLAG_FORCE_SHINY != 0 && FlagGet(P_FLAG_FORCE_SHINY)))
isShiny = TRUE;
else if (P_FLAG_FORCE_NO_SHINY != 0 && FlagGet(P_FLAG_FORCE_NO_SHINY))
else if (shinyMode == SHINY_MODE_NEVER || (P_FLAG_FORCE_NO_SHINY != 0 && FlagGet(P_FLAG_FORCE_NO_SHINY)))
isShiny = FALSE;
else
isShiny = GetMonData(&mon, MON_DATA_IS_SHINY);
SetMonData(&mon, MON_DATA_IS_SHINY, &isShiny);
// gigantamax factor
@ -479,7 +483,7 @@ 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(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, 0);
return ScriptGiveMonParameterized(0, PARTY_SIZE, species, level, item, ITEM_POKE_BALL, NUM_NATURES, NUM_ABILITY_PERSONALITY, MON_GENDERLESS, evs, ivs, moves, SHINY_MODE_RANDOM, FALSE, NUMBER_OF_MON_TYPES, 0);
}
#define PARSE_FLAG(n, default_) (flags & (1 << (n))) ? VarGet(ScriptReadHalfword(ctx)) : (default_)
@ -542,20 +546,20 @@ void ScrCmd_createmon(struct ScriptContext *ctx)
}
}
}
hpIv = PARSE_FLAG(11, hpIv);
atkIv = PARSE_FLAG(12, atkIv);
defIv = PARSE_FLAG(13, defIv);
speedIv = PARSE_FLAG(14, speedIv);
spAtkIv = PARSE_FLAG(15, spAtkIv);
spDefIv = PARSE_FLAG(16, spDefIv);
u16 move1 = PARSE_FLAG(17, MOVE_NONE);
u16 move2 = PARSE_FLAG(18, MOVE_NONE);
u16 move3 = PARSE_FLAG(19, MOVE_NONE);
u16 move4 = PARSE_FLAG(20, MOVE_NONE);
bool8 isShiny = PARSE_FLAG(21, FALSE);
bool8 gmaxFactor = PARSE_FLAG(22, FALSE);
u8 teraType = PARSE_FLAG(23, NUMBER_OF_MON_TYPES);
u8 dmaxLevel = PARSE_FLAG(24, 0);
hpIv = PARSE_FLAG(11, hpIv);
atkIv = PARSE_FLAG(12, atkIv);
defIv = PARSE_FLAG(13, defIv);
speedIv = PARSE_FLAG(14, speedIv);
spAtkIv = PARSE_FLAG(15, spAtkIv);
spDefIv = PARSE_FLAG(16, spDefIv);
u16 move1 = PARSE_FLAG(17, MOVE_NONE);
u16 move2 = PARSE_FLAG(18, MOVE_NONE);
u16 move3 = PARSE_FLAG(19, MOVE_NONE);
u16 move4 = PARSE_FLAG(20, MOVE_NONE);
enum ShinyMode shinyMode = PARSE_FLAG(21, SHINY_MODE_RANDOM);
bool8 gmaxFactor = PARSE_FLAG(22, FALSE);
u8 teraType = PARSE_FLAG(23, NUMBER_OF_MON_TYPES);
u8 dmaxLevel = PARSE_FLAG(24, 0);
u8 evs[NUM_STATS] = {hpEv, atkEv, defEv, speedEv, spAtkEv, spDefEv};
u8 ivs[NUM_STATS] = {hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv};
@ -566,7 +570,7 @@ void ScrCmd_createmon(struct ScriptContext *ctx)
else
Script_RequestEffects(SCREFF_V1);
gSpecialVar_Result = ScriptGiveMonParameterized(side, slot, species, level, item, ball, nature, abilityNum, gender, evs, ivs, moves, isShiny, gmaxFactor, teraType, dmaxLevel);
gSpecialVar_Result = ScriptGiveMonParameterized(side, slot, species, level, item, ball, nature, abilityNum, gender, evs, ivs, moves, shinyMode, gmaxFactor, teraType, dmaxLevel);
}
#undef PARSE_FLAG

View File

@ -304,7 +304,7 @@ TEST("givemon [all]")
ZeroPlayerPartyMons();
RUN_OVERWORLD_SCRIPT(
givemon SPECIES_WOBBUFFET, 100, item=ITEM_LEFTOVERS, ball=ITEM_MASTER_BALL, nature=NATURE_BOLD, abilityNum=2, gender=MON_MALE, hpEv=1, atkEv=2, defEv=3, speedEv=4, spAtkEv=5, spDefEv=6, hpIv=7, atkIv=8, defIv=9, speedIv=10, spAtkIv=11, spDefIv=12, move1=MOVE_SCRATCH, move2=MOVE_SPLASH, move3=MOVE_CELEBRATE, move4=MOVE_EXPLOSION, isShiny=TRUE, gmaxFactor=TRUE, teraType=TYPE_FIRE, dmaxLevel=7;
givemon SPECIES_WOBBUFFET, 100, item=ITEM_LEFTOVERS, ball=ITEM_MASTER_BALL, nature=NATURE_BOLD, abilityNum=2, gender=MON_MALE, hpEv=1, atkEv=2, defEv=3, speedEv=4, spAtkEv=5, spDefEv=6, hpIv=7, atkIv=8, defIv=9, speedIv=10, spAtkIv=11, spDefIv=12, move1=MOVE_SCRATCH, move2=MOVE_SPLASH, move3=MOVE_CELEBRATE, move4=MOVE_EXPLOSION, shinyMode=SHINY_MODE_ALWAYS, gmaxFactor=TRUE, teraType=TYPE_FIRE, dmaxLevel=7;
);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_WOBBUFFET);
@ -363,13 +363,13 @@ TEST("givemon [vars]")
VarSet(VAR_TEMP_6, MOVE_SPLASH);
VarSet(VAR_TEMP_7, MOVE_CELEBRATE);
VarSet(VAR_TEMP_8, MOVE_EXPLOSION);
VarSet(VAR_TEMP_9, TRUE);
VarSet(VAR_TEMP_9, SHINY_MODE_ALWAYS);
VarSet(VAR_TEMP_A, TRUE);
VarSet(VAR_TEMP_B, TYPE_FIRE);
VarSet(VAR_TEMP_E, 7);
RUN_OVERWORLD_SCRIPT(
givemon VAR_TEMP_C, VAR_TEMP_D, item=VAR_0x8000, ball=VAR_0x8001, nature=VAR_0x8002, abilityNum=VAR_0x8003, gender=VAR_0x8004, hpEv=VAR_0x8005, atkEv=VAR_0x8006, defEv=VAR_0x8007, speedEv=VAR_0x8008, spAtkEv=VAR_0x8009, spDefEv=VAR_0x800A, hpIv=VAR_0x800B, atkIv=VAR_TEMP_0, defIv=VAR_TEMP_1, speedIv=VAR_TEMP_2, spAtkIv=VAR_TEMP_3, spDefIv=VAR_TEMP_4, move1=VAR_TEMP_5, move2=VAR_TEMP_6, move3=VAR_TEMP_7, move4=VAR_TEMP_8, isShiny=VAR_TEMP_9, gmaxFactor=VAR_TEMP_A, teraType=VAR_TEMP_B, dmaxLevel=VAR_TEMP_E;
givemon VAR_TEMP_C, VAR_TEMP_D, item=VAR_0x8000, ball=VAR_0x8001, nature=VAR_0x8002, abilityNum=VAR_0x8003, gender=VAR_0x8004, hpEv=VAR_0x8005, atkEv=VAR_0x8006, defEv=VAR_0x8007, speedEv=VAR_0x8008, spAtkEv=VAR_0x8009, spDefEv=VAR_0x800A, hpIv=VAR_0x800B, atkIv=VAR_TEMP_0, defIv=VAR_TEMP_1, speedIv=VAR_TEMP_2, spAtkIv=VAR_TEMP_3, spDefIv=VAR_TEMP_4, move1=VAR_TEMP_5, move2=VAR_TEMP_6, move3=VAR_TEMP_7, move4=VAR_TEMP_8, shinyMode=VAR_TEMP_9, gmaxFactor=VAR_TEMP_A, teraType=VAR_TEMP_B, dmaxLevel=VAR_TEMP_E;
);
EXPECT_EQ(GetMonData(&gPlayerParty[0], MON_DATA_SPECIES), SPECIES_WOBBUFFET);