mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-03-21 18:04:50 -05:00
Adds B_VAR_DIFFICULTY and related functions READ DESC (#5337)
Co-authored-by: sbird <sbird@no.tld> Co-authored-by: Philipp AUER <SBird1337@users.noreply.github.com> Co-authored-by: Martin Griffin <martinrgriffin@gmail.com> Co-authored-by: hedara90 <90hedara@gmail.com>
This commit is contained in:
parent
03684c6539
commit
a7f77ed08d
|
|
@ -2437,3 +2437,19 @@
|
|||
.2byte \dest
|
||||
.endm
|
||||
|
||||
.macro increasedifficulty
|
||||
callnative Script_IncreaseDifficulty
|
||||
.endm
|
||||
|
||||
.macro decreasedifficulty
|
||||
callnative Script_DecreaseDifficulty
|
||||
.endm
|
||||
|
||||
.macro getdifficulty var:req
|
||||
callnative Script_GetDifficulty
|
||||
.endm
|
||||
|
||||
.macro setdifficulty difficulty:req
|
||||
callnative Script_SetDifficulty
|
||||
.byte \difficulty
|
||||
.endm
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "constants/contest.h"
|
||||
#include "constants/daycare.h"
|
||||
#include "constants/decorations.h"
|
||||
#include "constants/difficulty.h"
|
||||
#include "constants/easy_chat.h"
|
||||
#include "constants/event_objects.h"
|
||||
#include "constants/event_object_movement.h"
|
||||
|
|
|
|||
|
|
@ -206,6 +206,7 @@
|
|||
#define B_VAR_STARTING_STATUS 0 // If this var has a value, assigning a STATUS_FIELD_xx_TERRAIN to it before battle causes the battle to start with that terrain active.
|
||||
#define B_VAR_STARTING_STATUS_TIMER 0 // If this var has a value greater or equal than 1 field terrains will last that number of turns, otherwise they will last until they're overwritten.
|
||||
#define B_VAR_WILD_AI_FLAGS 0 // If not 0, you can use this var to add to default wild AI flags. NOT usable with flags above (1 << 15)
|
||||
#define B_VAR_DIFFICULTY 0 // If not 0, you can use this var to control which difficulty version of a Trainer is loaded. This should be manually set by the developer using Script_SetDifficulty AFTER NewGameInitData has run.
|
||||
|
||||
// Sky Battles
|
||||
#define B_FLAG_SKY_BATTLE 0 // If this flag has a value, the player will be able to engage in scripted Sky Battles.
|
||||
|
|
|
|||
|
|
@ -1129,6 +1129,10 @@
|
|||
#undef P_FAMILY_PECHARUNT
|
||||
#define P_FAMILY_PECHARUNT TRUE
|
||||
|
||||
// Vars
|
||||
#undef B_VAR_DIFFICULTY
|
||||
#define B_VAR_DIFFICULTY VAR_UNUSED_0x404E
|
||||
|
||||
// Flags
|
||||
#undef B_FLAG_SLEEP_CLAUSE
|
||||
#define B_FLAG_SLEEP_CLAUSE FLAG_SPECIAL_FLAG_UNUSED_0x4003
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
#ifndef GUARD_CONSTANTS_BATTLE_PARTNERS_H
|
||||
#define GUARD_CONSTANTS_BATTLE_PARTNERS_H
|
||||
|
||||
#define PARTNER_NONE 0
|
||||
#define PARTNER_STEVEN 1
|
||||
#define PARTNER_NONE 0
|
||||
#define PARTNER_STEVEN 1
|
||||
#define PARTNER_COUNT 2
|
||||
|
||||
#endif // GUARD_CONSTANTS_BATTLE_PARTNERS_H
|
||||
|
|
|
|||
15
include/constants/difficulty.h
Normal file
15
include/constants/difficulty.h
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#ifndef GUARD_DIFFICULTY_CONSTANTS_H
|
||||
#define GUARD_DIFFICULTY_CONSTANTS_H
|
||||
|
||||
enum DifficultyLevel
|
||||
{
|
||||
DIFFICULTY_EASY,
|
||||
DIFFICULTY_NORMAL, //If you rename this, the word "Normal" in fprint_trainers must be replaced with the new difficulty name.
|
||||
DIFFICULTY_HARD,
|
||||
DIFFICULTY_COUNT,
|
||||
};
|
||||
|
||||
#define DIFFICULTY_MIN 0
|
||||
#define DIFFICULTY_MAX (DIFFICULTY_COUNT - 1)
|
||||
|
||||
#endif // GUARD_DIFFICULTY_CONSTANTS_H
|
||||
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "constants/moves.h"
|
||||
#include "constants/trainers.h"
|
||||
#include "constants/battle.h"
|
||||
#include "difficulty.h"
|
||||
|
||||
#define MAX_TRAINER_ITEMS 4
|
||||
|
||||
|
|
@ -164,8 +166,8 @@ extern const union AnimCmd *const sAnims_Trainer[];
|
|||
extern const struct TrainerSprite gTrainerSprites[];
|
||||
extern const struct TrainerBacksprite gTrainerBacksprites[];
|
||||
|
||||
extern const struct Trainer gTrainers[];
|
||||
extern const struct Trainer gBattlePartners[];
|
||||
extern const struct Trainer gTrainers[DIFFICULTY_COUNT][TRAINERS_COUNT];
|
||||
extern const struct Trainer gBattlePartners[DIFFICULTY_COUNT][PARTNER_COUNT];
|
||||
|
||||
extern const struct TrainerClass gTrainerClasses[TRAINER_CLASS_COUNT];
|
||||
|
||||
|
|
@ -191,71 +193,103 @@ static inline u16 SanitizeTrainerId(u16 trainerId)
|
|||
|
||||
static inline const struct Trainer *GetTrainerStructFromId(u16 trainerId)
|
||||
{
|
||||
return &gTrainers[SanitizeTrainerId(trainerId)];
|
||||
u32 sanitizedTrainerId = SanitizeTrainerId(trainerId);
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
|
||||
return &gTrainers[difficulty][sanitizedTrainerId];
|
||||
}
|
||||
|
||||
static inline const u8 GetTrainerClassFromId(u16 trainerId)
|
||||
{
|
||||
return gTrainers[SanitizeTrainerId(trainerId)].trainerClass;
|
||||
u32 sanitizedTrainerId = SanitizeTrainerId(trainerId);
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
|
||||
return gTrainers[difficulty][sanitizedTrainerId].trainerClass;
|
||||
}
|
||||
|
||||
static inline const u8 *GetTrainerClassNameFromId(u16 trainerId)
|
||||
{
|
||||
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(trainerId);
|
||||
|
||||
if (trainerId > TRAINER_PARTNER(PARTNER_NONE))
|
||||
return gTrainerClasses[gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerClass].name;
|
||||
return gTrainerClasses[gBattlePartners[difficulty][trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerClass].name;
|
||||
return gTrainerClasses[GetTrainerClassFromId(trainerId)].name;
|
||||
}
|
||||
|
||||
static inline const u8 *GetTrainerNameFromId(u16 trainerId)
|
||||
{
|
||||
u32 sanitizedTrainerId = SanitizeTrainerId(trainerId);
|
||||
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
|
||||
enum DifficultyLevel partnerDifficulty = GetBattlePartnerDifficultyLevel(trainerId);
|
||||
|
||||
if (trainerId > TRAINER_PARTNER(PARTNER_NONE))
|
||||
return gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName;
|
||||
return gTrainers[SanitizeTrainerId(trainerId)].trainerName;
|
||||
return gBattlePartners[partnerDifficulty][trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName;
|
||||
return gTrainers[difficulty][sanitizedTrainerId].trainerName;
|
||||
}
|
||||
|
||||
static inline const u8 GetTrainerPicFromId(u16 trainerId)
|
||||
{
|
||||
return gTrainers[SanitizeTrainerId(trainerId)].trainerPic;
|
||||
u32 sanitizedTrainerId = SanitizeTrainerId(trainerId);
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
|
||||
return gTrainers[difficulty][sanitizedTrainerId].trainerPic;
|
||||
}
|
||||
|
||||
static inline const u8 GetTrainerStartingStatusFromId(u16 trainerId)
|
||||
{
|
||||
return gTrainers[SanitizeTrainerId(trainerId)].startingStatus;
|
||||
return gTrainers[GetCurrentDifficultyLevel()][SanitizeTrainerId(trainerId)].startingStatus;
|
||||
}
|
||||
|
||||
static inline const bool32 IsTrainerDoubleBattle(u16 trainerId)
|
||||
{
|
||||
return gTrainers[SanitizeTrainerId(trainerId)].doubleBattle;
|
||||
u32 sanitizedTrainerId = SanitizeTrainerId(trainerId);
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
|
||||
return gTrainers[difficulty][sanitizedTrainerId].doubleBattle;
|
||||
}
|
||||
|
||||
static inline const u8 GetTrainerPartySizeFromId(u16 trainerId)
|
||||
{
|
||||
return gTrainers[SanitizeTrainerId(trainerId)].partySize;
|
||||
u32 sanitizedTrainerId = SanitizeTrainerId(trainerId);
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
|
||||
return gTrainers[difficulty][sanitizedTrainerId].partySize;
|
||||
}
|
||||
|
||||
static inline const bool32 DoesTrainerHaveMugshot(u16 trainerId)
|
||||
{
|
||||
return gTrainers[SanitizeTrainerId(trainerId)].mugshotColor;
|
||||
return gTrainers[GetCurrentDifficultyLevel()][SanitizeTrainerId(trainerId)].mugshotColor;
|
||||
}
|
||||
|
||||
static inline const u8 GetTrainerMugshotColorFromId(u16 trainerId)
|
||||
{
|
||||
return gTrainers[SanitizeTrainerId(trainerId)].mugshotColor;
|
||||
return gTrainers[GetCurrentDifficultyLevel()][SanitizeTrainerId(trainerId)].mugshotColor;
|
||||
}
|
||||
|
||||
static inline const u16 *GetTrainerItemsFromId(u16 trainerId)
|
||||
{
|
||||
return gTrainers[SanitizeTrainerId(trainerId)].items;
|
||||
u32 sanitizedTrainerId = SanitizeTrainerId(trainerId);
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
|
||||
return gTrainers[difficulty][sanitizedTrainerId].items;
|
||||
}
|
||||
|
||||
static inline const struct TrainerMon *GetTrainerPartyFromId(u16 trainerId)
|
||||
{
|
||||
return gTrainers[SanitizeTrainerId(trainerId)].party;
|
||||
u32 sanitizedTrainerId = SanitizeTrainerId(trainerId);
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
|
||||
return gTrainers[difficulty][sanitizedTrainerId].party;
|
||||
}
|
||||
|
||||
static inline const bool32 GetTrainerAIFlagsFromId(u16 trainerId)
|
||||
{
|
||||
return gTrainers[SanitizeTrainerId(trainerId)].aiFlags;
|
||||
u32 sanitizedTrainerId = SanitizeTrainerId(trainerId);
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
|
||||
return gTrainers[difficulty][sanitizedTrainerId].aiFlags;
|
||||
}
|
||||
|
||||
#endif // GUARD_DATA_H
|
||||
|
|
|
|||
17
include/difficulty.h
Normal file
17
include/difficulty.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef GUARD_DIFFICULTY_H
|
||||
#define GUARD_DIFFICULTY_H
|
||||
|
||||
#include "constants/difficulty.h"
|
||||
#include "script.h"
|
||||
|
||||
enum DifficultyLevel GetCurrentDifficultyLevel(void);
|
||||
void SetCurrentDifficultyLevel(enum DifficultyLevel);
|
||||
|
||||
enum DifficultyLevel GetBattlePartnerDifficultyLevel(u16);
|
||||
enum DifficultyLevel GetTrainerDifficultyLevel(u16);
|
||||
void Script_IncreaseDifficulty(void);
|
||||
void Script_DecreaseDifficulty(void);
|
||||
void Script_GetDifficulty(void);
|
||||
void Script_SetDifficulty(struct ScriptContext *);
|
||||
|
||||
#endif // GUARD_DIFFICULTY_H
|
||||
|
|
@ -297,9 +297,11 @@ static void PlayerPartnerHandleDrawTrainerPic(u32 battler)
|
|||
s16 xPos, yPos;
|
||||
u32 trainerPicId;
|
||||
|
||||
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(gPartnerTrainerId);
|
||||
|
||||
if (gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE))
|
||||
{
|
||||
trainerPicId = gBattlePartners[gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerPic;
|
||||
trainerPicId = gBattlePartners[difficulty][gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerPic;
|
||||
xPos = 90;
|
||||
yPos = (8 - gTrainerBacksprites[trainerPicId].coordinates.size) * 4 + 80;
|
||||
}
|
||||
|
|
@ -427,9 +429,10 @@ static void PlayerPartnerHandleHealthBarUpdate(u32 battler)
|
|||
static void PlayerPartnerHandleIntroTrainerBallThrow(u32 battler)
|
||||
{
|
||||
const u32 *trainerPal;
|
||||
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(gPartnerTrainerId);
|
||||
|
||||
if (gPartnerTrainerId > TRAINER_PARTNER(PARTNER_NONE))
|
||||
trainerPal = gTrainerBacksprites[gBattlePartners[gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerPic].palette.data;
|
||||
trainerPal = gTrainerBacksprites[gBattlePartners[difficulty][gPartnerTrainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerPic].palette.data;
|
||||
else if (IsAiVsAiBattle())
|
||||
trainerPal = gTrainerSprites[GetTrainerPicFromId(gPartnerTrainerId)].palette.data;
|
||||
else
|
||||
|
|
|
|||
|
|
@ -3560,8 +3560,10 @@ struct TrainerSlide
|
|||
const u8 *msgDynamax;
|
||||
};
|
||||
|
||||
static const struct TrainerSlide sTrainerSlides[] =
|
||||
static const struct TrainerSlide sTrainerSlides[DIFFICULTY_COUNT][TRAINERS_COUNT] =
|
||||
{
|
||||
[DIFFICULTY_NORMAL] =
|
||||
{
|
||||
/* Put any trainer slide-in messages inside this array.
|
||||
Example:
|
||||
{
|
||||
|
|
@ -3580,7 +3582,14 @@ static const struct TrainerSlide sTrainerSlides[] =
|
|||
.msgBeforeFirstTurn = sText_GravityIntensified,
|
||||
.msgDynamax = sText_TargetWokeUp,
|
||||
},
|
||||
},
|
||||
[DIFFICULTY_EASY] =
|
||||
{
|
||||
},
|
||||
[DIFFICULTY_HARD] =
|
||||
{
|
||||
*/
|
||||
},
|
||||
};
|
||||
|
||||
static u32 GetEnemyMonCount(u32 firstId, u32 lastId, bool32 onlyAlive)
|
||||
|
|
@ -3657,118 +3666,120 @@ u32 ShouldDoTrainerSlide(u32 battler, u32 which)
|
|||
trainerId = gTrainerBattleOpponent_A;
|
||||
}
|
||||
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(trainerId);
|
||||
|
||||
for (i = 0; i < ARRAY_COUNT(sTrainerSlides); i++)
|
||||
{
|
||||
if (trainerId == sTrainerSlides[i].trainerId
|
||||
&& (((gBattleTypeFlags & BATTLE_TYPE_FRONTIER) && sTrainerSlides[i].isFrontierTrainer)
|
||||
|| (!(gBattleTypeFlags & BATTLE_TYPE_FRONTIER) && !sTrainerSlides[i].isFrontierTrainer)))
|
||||
if (trainerId == sTrainerSlides[difficulty]->trainerId
|
||||
&& (((gBattleTypeFlags & BATTLE_TYPE_FRONTIER) && sTrainerSlides[difficulty]->isFrontierTrainer)
|
||||
|| (!(gBattleTypeFlags & BATTLE_TYPE_FRONTIER) && !sTrainerSlides[difficulty]->isFrontierTrainer)))
|
||||
{
|
||||
gBattleScripting.battler = battler;
|
||||
switch (which)
|
||||
{
|
||||
case TRAINER_SLIDE_LAST_SWITCHIN:
|
||||
if (sTrainerSlides[i].msgLastSwitchIn != NULL && !CanBattlerSwitch(battler))
|
||||
if (sTrainerSlides[difficulty]->msgLastSwitchIn != NULL && !CanBattlerSwitch(battler))
|
||||
{
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgLastSwitchIn;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgLastSwitchIn;
|
||||
return retValue;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_LAST_LOW_HP:
|
||||
if (sTrainerSlides[i].msgLastLowHp != NULL
|
||||
if (sTrainerSlides[difficulty]->msgLastLowHp != NULL
|
||||
&& GetEnemyMonCount(firstId, lastId, TRUE) == 1
|
||||
&& BattlerHPPercentage(battler, LESS_THAN_OR_EQUAL, 4)
|
||||
&& !gBattleStruct->trainerSlideLowHpMsgDone)
|
||||
{
|
||||
gBattleStruct->trainerSlideLowHpMsgDone = TRUE;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgLastLowHp;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgLastLowHp;
|
||||
return retValue;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_FIRST_DOWN:
|
||||
if (sTrainerSlides[i].msgFirstDown != NULL && GetEnemyMonCount(firstId, lastId, TRUE) == GetEnemyMonCount(firstId, lastId, FALSE) - 1)
|
||||
if (sTrainerSlides[difficulty]->msgFirstDown != NULL && GetEnemyMonCount(firstId, lastId, TRUE) == GetEnemyMonCount(firstId, lastId, FALSE) - 1)
|
||||
{
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgFirstDown;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgFirstDown;
|
||||
return retValue;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_LAST_HALF_HP:
|
||||
if (sTrainerSlides[i].msgLastHalfHp != NULL
|
||||
if (sTrainerSlides[difficulty]->msgLastHalfHp != NULL
|
||||
&& GetEnemyMonCount(firstId, lastId, TRUE) == GetEnemyMonCount(firstId, lastId, FALSE) - 1
|
||||
&& BattlerHPPercentage(battler, LESS_THAN_OR_EQUAL, 2) && BattlerHPPercentage(battler, GREATER_THAN, 4)
|
||||
&& !gBattleStruct->trainerSlideHalfHpMsgDone)
|
||||
{
|
||||
gBattleStruct->trainerSlideHalfHpMsgDone = TRUE;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgLastHalfHp;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgLastHalfHp;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_FIRST_CRITICAL_HIT:
|
||||
if (sTrainerSlides[i].msgFirstCriticalHit != NULL && gBattleStruct->trainerSlideFirstCriticalHitMsgState == 1)
|
||||
if (sTrainerSlides[difficulty]->msgFirstCriticalHit != NULL && gBattleStruct->trainerSlideFirstCriticalHitMsgState == 1)
|
||||
{
|
||||
gBattleStruct->trainerSlideFirstCriticalHitMsgState = 2;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgFirstCriticalHit;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgFirstCriticalHit;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_FIRST_SUPER_EFFECTIVE_HIT:
|
||||
if (sTrainerSlides[i].msgFirstSuperEffectiveHit != NULL
|
||||
if (sTrainerSlides[difficulty]->msgFirstSuperEffectiveHit != NULL
|
||||
&& gBattleStruct->trainerSlideFirstSuperEffectiveHitMsgState == 1
|
||||
&& gBattleMons[battler].hp)
|
||||
{
|
||||
gBattleStruct->trainerSlideFirstSuperEffectiveHitMsgState = 2;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgFirstSuperEffectiveHit;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgFirstSuperEffectiveHit;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_FIRST_STAB_MOVE:
|
||||
if (sTrainerSlides[i].msgFirstSTABMove != NULL
|
||||
if (sTrainerSlides[difficulty]->msgFirstSTABMove != NULL
|
||||
&& gBattleStruct->trainerSlideFirstSTABMoveMsgState == 1
|
||||
&& GetEnemyMonCount(firstId, lastId, TRUE) == GetEnemyMonCount(firstId, lastId, FALSE))
|
||||
{
|
||||
gBattleStruct->trainerSlideFirstSTABMoveMsgState = 2;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgFirstSTABMove;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgFirstSTABMove;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_PLAYER_MON_UNAFFECTED:
|
||||
if (sTrainerSlides[i].msgPlayerMonUnaffected != NULL
|
||||
if (sTrainerSlides[difficulty]->msgPlayerMonUnaffected != NULL
|
||||
&& gBattleStruct->trainerSlidePlayerMonUnaffectedMsgState == 1
|
||||
&& GetEnemyMonCount(firstId, lastId, TRUE) == GetEnemyMonCount(firstId, lastId, FALSE))
|
||||
{
|
||||
gBattleStruct->trainerSlidePlayerMonUnaffectedMsgState = 2;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgPlayerMonUnaffected;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgPlayerMonUnaffected;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_MEGA_EVOLUTION:
|
||||
if (sTrainerSlides[i].msgMegaEvolution != NULL && !gBattleStruct->trainerSlideMegaEvolutionMsgDone)
|
||||
if (sTrainerSlides[difficulty]->msgMegaEvolution != NULL && !gBattleStruct->trainerSlideMegaEvolutionMsgDone)
|
||||
{
|
||||
gBattleStruct->trainerSlideMegaEvolutionMsgDone = TRUE;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgMegaEvolution;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgMegaEvolution;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_Z_MOVE:
|
||||
if (sTrainerSlides[i].msgZMove != NULL && !gBattleStruct->trainerSlideZMoveMsgDone)
|
||||
if (sTrainerSlides[difficulty]->msgZMove != NULL && !gBattleStruct->trainerSlideZMoveMsgDone)
|
||||
{
|
||||
gBattleStruct->trainerSlideZMoveMsgDone = TRUE;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgZMove;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgZMove;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_BEFORE_FIRST_TURN:
|
||||
if (sTrainerSlides[i].msgBeforeFirstTurn != NULL && !gBattleStruct->trainerSlideBeforeFirstTurnMsgDone)
|
||||
if (sTrainerSlides[difficulty]->msgBeforeFirstTurn != NULL && !gBattleStruct->trainerSlideBeforeFirstTurnMsgDone)
|
||||
{
|
||||
gBattleStruct->trainerSlideBeforeFirstTurnMsgDone = TRUE;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgBeforeFirstTurn;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgBeforeFirstTurn;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
case TRAINER_SLIDE_DYNAMAX:
|
||||
if (sTrainerSlides[i].msgDynamax != NULL && !gBattleStruct->trainerSlideDynamaxMsgDone)
|
||||
if (sTrainerSlides[difficulty]->msgDynamax != NULL && !gBattleStruct->trainerSlideDynamaxMsgDone)
|
||||
{
|
||||
gBattleStruct->trainerSlideDynamaxMsgDone = TRUE;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[i].msgDynamax;
|
||||
gBattleStruct->trainerSlideMsg = sTrainerSlides[difficulty]->msgDynamax;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -699,7 +699,7 @@ static const u8 *const *const sPartnerApprenticeTextTables[NUM_APPRENTICES] =
|
|||
#include "data/battle_frontier/battle_tent.h"
|
||||
|
||||
#include "data/partner_parties.h"
|
||||
const struct Trainer gBattlePartners[] =
|
||||
const struct Trainer gBattlePartners[DIFFICULTY_COUNT][PARTNER_COUNT] =
|
||||
{
|
||||
#include "data/battle_partners.h"
|
||||
};
|
||||
|
|
@ -1355,6 +1355,7 @@ u8 GetFrontierTrainerFrontSpriteId(u16 trainerId)
|
|||
u8 GetFrontierOpponentClass(u16 trainerId)
|
||||
{
|
||||
u8 trainerClass = 0;
|
||||
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(trainerId);
|
||||
SetFacilityPtrsGetLevel();
|
||||
|
||||
#if FREE_BATTLE_TOWER_E_READER == FALSE
|
||||
|
|
@ -1371,7 +1372,7 @@ u8 GetFrontierOpponentClass(u16 trainerId)
|
|||
}
|
||||
else if (trainerId > TRAINER_PARTNER(PARTNER_NONE))
|
||||
{
|
||||
trainerClass = gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerClass;
|
||||
trainerClass = gBattlePartners[difficulty][trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerClass;
|
||||
}
|
||||
else if (trainerId < FRONTIER_TRAINERS_COUNT)
|
||||
{
|
||||
|
|
@ -1441,6 +1442,7 @@ static u8 GetFrontierTrainerFacilityClass(u16 trainerId)
|
|||
void GetFrontierTrainerName(u8 *dst, u16 trainerId)
|
||||
{
|
||||
s32 i = 0;
|
||||
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(trainerId);
|
||||
SetFacilityPtrsGetLevel();
|
||||
|
||||
if (trainerId == TRAINER_EREADER)
|
||||
|
|
@ -1457,8 +1459,8 @@ void GetFrontierTrainerName(u8 *dst, u16 trainerId)
|
|||
}
|
||||
else if (trainerId > TRAINER_PARTNER(PARTNER_NONE))
|
||||
{
|
||||
for (i = 0; gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName[i] != EOS; i++)
|
||||
dst[i] = gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName[i];
|
||||
for (i = 0; gBattlePartners[difficulty][trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName[i] != EOS; i++)
|
||||
dst[i] = gBattlePartners[difficulty][trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName[i];
|
||||
}
|
||||
else if (trainerId < FRONTIER_TRAINERS_COUNT)
|
||||
{
|
||||
|
|
@ -2965,6 +2967,7 @@ static void FillPartnerParty(u16 trainerId)
|
|||
u32 otID;
|
||||
u8 trainerName[(PLAYER_NAME_LENGTH * 3) + 1];
|
||||
s32 ball = -1;
|
||||
enum DifficultyLevel difficulty = GetBattlePartnerDifficultyLevel(trainerId);
|
||||
SetFacilityPtrsGetLevel();
|
||||
|
||||
if (trainerId > TRAINER_PARTNER(PARTNER_NONE))
|
||||
|
|
@ -2972,10 +2975,10 @@ static void FillPartnerParty(u16 trainerId)
|
|||
for (i = 0; i < 3; i++)
|
||||
ZeroMonData(&gPlayerParty[i + 3]);
|
||||
|
||||
for (i = 0; i < 3 && i < gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].partySize; i++)
|
||||
for (i = 0; i < 3 && i < gBattlePartners[difficulty][trainerId - TRAINER_PARTNER(PARTNER_NONE)].partySize; i++)
|
||||
{
|
||||
const struct TrainerMon *partyData = gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].party;
|
||||
const u8 *partnerName = gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName;
|
||||
const struct TrainerMon *partyData = gBattlePartners[difficulty][trainerId - TRAINER_PARTNER(PARTNER_NONE)].party;
|
||||
const u8 *partnerName = gBattlePartners[difficulty][trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName;
|
||||
|
||||
for (k = 0; partnerName[k] != EOS && k < 3; k++)
|
||||
{
|
||||
|
|
@ -3046,9 +3049,9 @@ static void FillPartnerParty(u16 trainerId)
|
|||
}
|
||||
CalculateMonStats(&gPlayerParty[i + 3]);
|
||||
|
||||
StringCopy(trainerName, gBattlePartners[trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName);
|
||||
StringCopy(trainerName, gBattlePartners[difficulty][trainerId - TRAINER_PARTNER(PARTNER_NONE)].trainerName);
|
||||
SetMonData(&gPlayerParty[i + 3], MON_DATA_OT_NAME, trainerName);
|
||||
j = gBattlePartners[SanitizeTrainerId(trainerId - TRAINER_PARTNER(PARTNER_NONE))].encounterMusic_gender >> 7;
|
||||
j = gBattlePartners[difficulty][SanitizeTrainerId(trainerId - TRAINER_PARTNER(PARTNER_NONE))].encounterMusic_gender >> 7;
|
||||
SetMonData(&gPlayerParty[i + 3], MON_DATA_OT_GENDER, &j);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,7 +227,7 @@ const union AnimCmd *const sAnims_Trainer[] ={
|
|||
|
||||
#include "data/trainer_parties.h"
|
||||
|
||||
const struct Trainer gTrainers[] =
|
||||
const struct Trainer gTrainers[DIFFICULTY_COUNT][TRAINERS_COUNT] =
|
||||
{
|
||||
#include "data/trainers.h"
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#line 1 "src/data/battle_partners.party"
|
||||
|
||||
#line 1
|
||||
[PARTNER_NONE] =
|
||||
[DIFFICULTY_NORMAL][PARTNER_NONE] =
|
||||
{
|
||||
#line 3
|
||||
.trainerClass = TRAINER_CLASS_PKMN_TRAINER_1,
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
},
|
||||
},
|
||||
#line 8
|
||||
[PARTNER_STEVEN] =
|
||||
[DIFFICULTY_NORMAL][PARTNER_STEVEN] =
|
||||
{
|
||||
#line 9
|
||||
.trainerName = _("STEVEN"),
|
||||
|
|
|
|||
1710
src/data/trainers.h
1710
src/data/trainers.h
File diff suppressed because it is too large
Load Diff
95
src/difficulty.c
Normal file
95
src/difficulty.c
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
#include "global.h"
|
||||
#include "data.h"
|
||||
#include "event_data.h"
|
||||
#include "script.h"
|
||||
#include "constants/battle.h"
|
||||
|
||||
enum DifficultyLevel GetCurrentDifficultyLevel(void)
|
||||
{
|
||||
if (!B_VAR_DIFFICULTY)
|
||||
return DIFFICULTY_NORMAL;
|
||||
|
||||
return VarGet(B_VAR_DIFFICULTY);
|
||||
}
|
||||
|
||||
void SetCurrentDifficultyLevel(enum DifficultyLevel desiredDifficulty)
|
||||
{
|
||||
if (!B_VAR_DIFFICULTY)
|
||||
return;
|
||||
|
||||
if (desiredDifficulty > DIFFICULTY_MAX)
|
||||
desiredDifficulty = DIFFICULTY_MAX;
|
||||
|
||||
VarSet(B_VAR_DIFFICULTY, desiredDifficulty);
|
||||
}
|
||||
|
||||
enum DifficultyLevel GetBattlePartnerDifficultyLevel(u16 partnerId)
|
||||
{
|
||||
enum DifficultyLevel difficulty = GetCurrentDifficultyLevel();
|
||||
|
||||
if (partnerId > TRAINER_PARTNER(PARTNER_NONE))
|
||||
partnerId -= TRAINER_PARTNER(PARTNER_NONE);
|
||||
|
||||
if (difficulty == DIFFICULTY_NORMAL)
|
||||
return DIFFICULTY_NORMAL;
|
||||
|
||||
if (gBattlePartners[difficulty][partnerId].party == NULL)
|
||||
return DIFFICULTY_NORMAL;
|
||||
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
enum DifficultyLevel GetTrainerDifficultyLevel(u16 trainerId)
|
||||
{
|
||||
enum DifficultyLevel difficulty = GetCurrentDifficultyLevel();
|
||||
|
||||
if (difficulty == DIFFICULTY_NORMAL)
|
||||
return DIFFICULTY_NORMAL;
|
||||
|
||||
if (gTrainers[difficulty][trainerId].party == NULL)
|
||||
return DIFFICULTY_NORMAL;
|
||||
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
void Script_IncreaseDifficulty(void)
|
||||
{
|
||||
enum DifficultyLevel currentDifficulty;
|
||||
|
||||
if (!B_VAR_DIFFICULTY)
|
||||
return;
|
||||
|
||||
currentDifficulty = GetCurrentDifficultyLevel();
|
||||
|
||||
if (currentDifficulty++ > DIFFICULTY_MAX)
|
||||
return;
|
||||
|
||||
SetCurrentDifficultyLevel(currentDifficulty);
|
||||
}
|
||||
|
||||
void Script_DecreaseDifficulty(void)
|
||||
{
|
||||
enum DifficultyLevel currentDifficulty;
|
||||
|
||||
if (!B_VAR_DIFFICULTY)
|
||||
return;
|
||||
|
||||
currentDifficulty = GetCurrentDifficultyLevel();
|
||||
|
||||
if (!currentDifficulty)
|
||||
return;
|
||||
|
||||
SetCurrentDifficultyLevel(--currentDifficulty);
|
||||
}
|
||||
|
||||
void Script_GetDifficulty(void)
|
||||
{
|
||||
gSpecialVar_Result = GetCurrentDifficultyLevel();
|
||||
}
|
||||
|
||||
void Script_SetDifficulty(struct ScriptContext *ctx)
|
||||
{
|
||||
enum DifficultyLevel desiredDifficulty = ScriptReadByte(ctx);
|
||||
|
||||
SetCurrentDifficultyLevel(desiredDifficulty);
|
||||
}
|
||||
|
|
@ -46,6 +46,7 @@
|
|||
#include "union_room_chat.h"
|
||||
#include "constants/map_groups.h"
|
||||
#include "constants/items.h"
|
||||
#include "difficulty.h"
|
||||
|
||||
extern const u8 EventScript_ResetAllMapFlags[];
|
||||
|
||||
|
|
@ -207,6 +208,7 @@ void NewGameInitData(void)
|
|||
WipeTrainerNameRecords();
|
||||
ResetTrainerHillResults();
|
||||
ResetContestLinkResults();
|
||||
SetCurrentDifficultyLevel(DIFFICULTY_NORMAL);
|
||||
ResetItemFlags();
|
||||
ResetDexNav();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5143,12 +5143,15 @@ s32 GetBattlerMultiplayerId(u16 id)
|
|||
|
||||
u8 GetTrainerEncounterMusicId(u16 trainerOpponentId)
|
||||
{
|
||||
u32 sanitizedTrainerId = SanitizeTrainerId(trainerOpponentId);
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevel(sanitizedTrainerId);
|
||||
|
||||
if (InBattlePyramid())
|
||||
return GetTrainerEncounterMusicIdInBattlePyramid(trainerOpponentId);
|
||||
else if (InTrainerHillChallenge())
|
||||
return GetTrainerEncounterMusicIdInTrainerHill(trainerOpponentId);
|
||||
else
|
||||
return gTrainers[SanitizeTrainerId(trainerOpponentId)].encounterMusic_gender & (F_TRAINER_FEMALE - 1);
|
||||
return gTrainers[difficulty][sanitizedTrainerId].encounterMusic_gender & (F_TRAINER_FEMALE - 1);
|
||||
}
|
||||
|
||||
u16 ModifyStatByNature(u8 nature, u16 stat, u8 statIndex)
|
||||
|
|
@ -6088,7 +6091,7 @@ const u8 *GetTrainerPartnerName(void)
|
|||
{
|
||||
if (gPartnerTrainerId == TRAINER_PARTNER(PARTNER_STEVEN))
|
||||
{
|
||||
return GetTrainerNameFromId(TRAINER_STEVEN);
|
||||
return GetTrainerNameFromId(PARTNER_STEVEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,16 +11,32 @@
|
|||
#include "constants/trainers.h"
|
||||
#include "constants/battle.h"
|
||||
|
||||
static const struct Trainer sTestTrainers[] =
|
||||
#define NUM_TEST_TRAINERS 3
|
||||
|
||||
static const struct Trainer sTestTrainers[DIFFICULTY_COUNT][NUM_TEST_TRAINERS] =
|
||||
{
|
||||
#include "trainer_control.h"
|
||||
};
|
||||
|
||||
enum DifficultyLevel GetTrainerDifficultyLevelTest(u16 trainerId)
|
||||
{
|
||||
enum DifficultyLevel difficulty = GetCurrentDifficultyLevel();
|
||||
|
||||
if (difficulty == DIFFICULTY_NORMAL)
|
||||
return DIFFICULTY_NORMAL;
|
||||
|
||||
if (sTestTrainers[difficulty][trainerId].party == NULL)
|
||||
return DIFFICULTY_NORMAL;
|
||||
|
||||
return difficulty;
|
||||
}
|
||||
|
||||
TEST("CreateNPCTrainerPartyForTrainer generates customized Pokémon")
|
||||
{
|
||||
u32 currTrainer = 0;
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u8 nickBuffer[20];
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[0], TRUE, BATTLE_TYPE_TRAINER);
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
EXPECT(IsMonShiny(&testParty[0]));
|
||||
EXPECT(!IsMonShiny(&testParty[1]));
|
||||
|
||||
|
|
@ -94,8 +110,9 @@ TEST("CreateNPCTrainerPartyForTrainer generates customized Pokémon")
|
|||
|
||||
TEST("CreateNPCTrainerPartyForTrainer generates different personalities for different mons")
|
||||
{
|
||||
enum DifficultyLevel difficulty = GetTrainerDifficultyLevelTest(0);
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[0], TRUE, BATTLE_TYPE_TRAINER);
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[difficulty][0], TRUE, BATTLE_TYPE_TRAINER);
|
||||
EXPECT(testParty[0].box.personality != testParty[1].box.personality);
|
||||
Free(testParty);
|
||||
}
|
||||
|
|
@ -160,3 +177,46 @@ TEST("Trainer Class Balls apply to the entire party")
|
|||
}
|
||||
Free(testParty);
|
||||
}
|
||||
|
||||
TEST("Difficulty default to Normal is the trainer doesn't have a member for the current diffuculty")
|
||||
{
|
||||
SetCurrentDifficultyLevel(DIFFICULTY_EASY);
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 1;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_MEWTWO);
|
||||
Free(testParty);
|
||||
}
|
||||
|
||||
TEST("Difficulty changes which party if used for NPCs if defined for the difficulty (EASY)")
|
||||
{
|
||||
SetCurrentDifficultyLevel(DIFFICULTY_EASY);
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 2;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_METAPOD);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 1);
|
||||
Free(testParty);
|
||||
}
|
||||
|
||||
TEST("Difficulty changes which party if used for NPCs if defined for the difficulty (HARD)")
|
||||
{
|
||||
SetCurrentDifficultyLevel(DIFFICULTY_HARD);
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 2;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_ARCEUS);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 99);
|
||||
Free(testParty);
|
||||
}
|
||||
|
||||
TEST("Difficulty changes which party if used for NPCs if defined for the difficulty (NORMAL)")
|
||||
{
|
||||
SetCurrentDifficultyLevel(DIFFICULTY_NORMAL);
|
||||
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
|
||||
u32 currTrainer = 2;
|
||||
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainers[GetTrainerDifficultyLevelTest(currTrainer)][currTrainer], TRUE, BATTLE_TYPE_TRAINER);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES) == SPECIES_MEWTWO);
|
||||
EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL) == 50);
|
||||
Free(testParty);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
#line 1 "test/battle/trainer_control.party"
|
||||
|
||||
#line 1
|
||||
[0] =
|
||||
[DIFFICULTY_NORMAL][0] =
|
||||
{
|
||||
#line 2
|
||||
.trainerName = _("Test1"),
|
||||
|
|
@ -87,3 +87,158 @@
|
|||
},
|
||||
},
|
||||
},
|
||||
#line 33
|
||||
#line 40
|
||||
[DIFFICULTY_NORMAL][1] =
|
||||
{
|
||||
#line 34
|
||||
.trainerName = _("Test2"),
|
||||
#line 35
|
||||
.trainerClass = TRAINER_CLASS_PKMN_TRAINER_1,
|
||||
#line 36
|
||||
.trainerPic = TRAINER_PIC_RED,
|
||||
.encounterMusic_gender =
|
||||
#line 38
|
||||
TRAINER_ENCOUNTER_MUSIC_MALE,
|
||||
#line 39
|
||||
.doubleBattle = FALSE,
|
||||
.partySize = 1,
|
||||
.party = (const struct TrainerMon[])
|
||||
{
|
||||
{
|
||||
#line 42
|
||||
.species = SPECIES_MEWTWO,
|
||||
.gender = TRAINER_MON_RANDOM_GENDER,
|
||||
#line 44
|
||||
.iv = TRAINER_PARTY_IVS(31, 31, 31, 31, 31, 31),
|
||||
#line 43
|
||||
.lvl = 5,
|
||||
.nature = NATURE_HARDY,
|
||||
.dynamaxLevel = MAX_DYNAMAX_LEVEL,
|
||||
},
|
||||
},
|
||||
},
|
||||
#line 45
|
||||
#line 52
|
||||
[DIFFICULTY_HARD][1] =
|
||||
{
|
||||
#line 46
|
||||
.trainerName = _("Test2"),
|
||||
#line 47
|
||||
.trainerClass = TRAINER_CLASS_PKMN_TRAINER_1,
|
||||
#line 48
|
||||
.trainerPic = TRAINER_PIC_RED,
|
||||
.encounterMusic_gender =
|
||||
#line 50
|
||||
TRAINER_ENCOUNTER_MUSIC_MALE,
|
||||
#line 51
|
||||
.doubleBattle = FALSE,
|
||||
.partySize = 1,
|
||||
.party = (const struct TrainerMon[])
|
||||
{
|
||||
{
|
||||
#line 54
|
||||
.species = SPECIES_YVELTAL,
|
||||
.gender = TRAINER_MON_RANDOM_GENDER,
|
||||
#line 56
|
||||
.iv = TRAINER_PARTY_IVS(31, 31, 31, 31, 31, 31),
|
||||
#line 55
|
||||
.lvl = 99,
|
||||
.nature = NATURE_HARDY,
|
||||
.dynamaxLevel = MAX_DYNAMAX_LEVEL,
|
||||
},
|
||||
},
|
||||
},
|
||||
#line 57
|
||||
#line 64
|
||||
[DIFFICULTY_NORMAL][2] =
|
||||
{
|
||||
#line 58
|
||||
.trainerName = _("Test2"),
|
||||
#line 59
|
||||
.trainerClass = TRAINER_CLASS_PKMN_TRAINER_1,
|
||||
#line 60
|
||||
.trainerPic = TRAINER_PIC_RED,
|
||||
.encounterMusic_gender =
|
||||
#line 62
|
||||
TRAINER_ENCOUNTER_MUSIC_MALE,
|
||||
#line 63
|
||||
.doubleBattle = FALSE,
|
||||
.partySize = 1,
|
||||
.party = (const struct TrainerMon[])
|
||||
{
|
||||
{
|
||||
#line 66
|
||||
.species = SPECIES_MEWTWO,
|
||||
.gender = TRAINER_MON_RANDOM_GENDER,
|
||||
#line 68
|
||||
.iv = TRAINER_PARTY_IVS(31, 31, 31, 31, 31, 31),
|
||||
#line 67
|
||||
.lvl = 50,
|
||||
.nature = NATURE_HARDY,
|
||||
.dynamaxLevel = MAX_DYNAMAX_LEVEL,
|
||||
},
|
||||
},
|
||||
},
|
||||
#line 69
|
||||
#line 76
|
||||
[DIFFICULTY_EASY][2] =
|
||||
{
|
||||
#line 70
|
||||
.trainerName = _("Test2"),
|
||||
#line 71
|
||||
.trainerClass = TRAINER_CLASS_PKMN_TRAINER_1,
|
||||
#line 72
|
||||
.trainerPic = TRAINER_PIC_RED,
|
||||
.encounterMusic_gender =
|
||||
#line 74
|
||||
TRAINER_ENCOUNTER_MUSIC_MALE,
|
||||
#line 75
|
||||
.doubleBattle = FALSE,
|
||||
.partySize = 1,
|
||||
.party = (const struct TrainerMon[])
|
||||
{
|
||||
{
|
||||
#line 78
|
||||
.species = SPECIES_METAPOD,
|
||||
.gender = TRAINER_MON_RANDOM_GENDER,
|
||||
#line 80
|
||||
.iv = TRAINER_PARTY_IVS(31, 31, 31, 31, 31, 31),
|
||||
#line 79
|
||||
.lvl = 1,
|
||||
.nature = NATURE_HARDY,
|
||||
.dynamaxLevel = MAX_DYNAMAX_LEVEL,
|
||||
},
|
||||
},
|
||||
},
|
||||
#line 81
|
||||
#line 88
|
||||
[DIFFICULTY_HARD][2] =
|
||||
{
|
||||
#line 82
|
||||
.trainerName = _("Test2"),
|
||||
#line 83
|
||||
.trainerClass = TRAINER_CLASS_PKMN_TRAINER_1,
|
||||
#line 84
|
||||
.trainerPic = TRAINER_PIC_RED,
|
||||
.encounterMusic_gender =
|
||||
#line 86
|
||||
TRAINER_ENCOUNTER_MUSIC_MALE,
|
||||
#line 87
|
||||
.doubleBattle = FALSE,
|
||||
.partySize = 1,
|
||||
.party = (const struct TrainerMon[])
|
||||
{
|
||||
{
|
||||
#line 90
|
||||
.species = SPECIES_ARCEUS,
|
||||
.gender = TRAINER_MON_RANDOM_GENDER,
|
||||
#line 92
|
||||
.iv = TRAINER_PARTY_IVS(31, 31, 31, 31, 31, 31),
|
||||
#line 91
|
||||
.lvl = 99,
|
||||
.nature = NATURE_HARDY,
|
||||
.dynamaxLevel = MAX_DYNAMAX_LEVEL,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -29,3 +29,63 @@ IVs: 0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe
|
|||
Wynaut
|
||||
Level: 5
|
||||
IVs: 0 HP / 0 Atk / 0 Def / 0 SpA / 0 SpD / 0 Spe
|
||||
|
||||
=== 1 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Normal
|
||||
|
||||
Mewtwo
|
||||
Level: 5
|
||||
|
||||
=== 1 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: HARD
|
||||
|
||||
Yveltal
|
||||
Level: 99
|
||||
|
||||
=== 2 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Normal
|
||||
|
||||
Mewtwo
|
||||
Level: 50
|
||||
|
||||
=== 2 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Easy
|
||||
|
||||
Metapod
|
||||
Level: 1
|
||||
|
||||
=== 2 ===
|
||||
Name: Test2
|
||||
Class: Pkmn Trainer 1
|
||||
Pic: Red
|
||||
Gender: Male
|
||||
Music: Male
|
||||
Double Battle: No
|
||||
Difficulty: Hard
|
||||
|
||||
Arceus
|
||||
Level: 99
|
||||
|
|
|
|||
|
|
@ -123,6 +123,9 @@ struct Trainer
|
|||
|
||||
struct String starting_status;
|
||||
int starting_status_line;
|
||||
|
||||
struct String difficulty;
|
||||
int difficulty_line;
|
||||
};
|
||||
|
||||
static bool is_empty_string(struct String s)
|
||||
|
|
@ -1195,9 +1198,16 @@ static bool parse_trainer(struct Parser *p, const struct Parsed *parsed, struct
|
|||
trainer->starting_status_line = value.location.line;
|
||||
trainer->starting_status = token_string(&value);
|
||||
}
|
||||
else if (is_literal_token(&key, "Difficulty"))
|
||||
{
|
||||
if (trainer->difficulty_line)
|
||||
any_error = !set_show_parse_error(p, key.location, "duplicate 'Difficulty'");
|
||||
trainer->difficulty_line = value.location.line;
|
||||
trainer->difficulty = token_string(&value);
|
||||
}
|
||||
else
|
||||
{
|
||||
any_error = !set_show_parse_error(p, key.location, "expected one of 'Name', 'Class', 'Pic', 'Gender', 'Music', 'Items', 'Double Battle', or 'AI'");
|
||||
any_error = !set_show_parse_error(p, key.location, "expected one of 'Name', 'Class', 'Pic', 'Gender', 'Music', 'Items', 'Double Battle', 'Difficulty', or 'AI'");
|
||||
}
|
||||
}
|
||||
if (!trainer->pic_line)
|
||||
|
|
@ -1618,7 +1628,14 @@ static void fprint_trainers(const char *output_path, FILE *f, struct Parsed *par
|
|||
{
|
||||
struct Trainer *trainer = &parsed->trainers[i];
|
||||
fprintf(f, "#line %d\n", trainer->id_line);
|
||||
fprintf(f, " [");
|
||||
if (is_empty_string(trainer->difficulty))
|
||||
trainer->difficulty = literal_string("Normal");
|
||||
else
|
||||
fprintf(f, "#line %d\n", trainer->difficulty_line);
|
||||
fprint_constant(f, " [DIFFICULTY",trainer->difficulty);
|
||||
fprintf(f, "]");
|
||||
|
||||
fprintf(f, "[");
|
||||
fprint_string(f, trainer->id);
|
||||
fprintf(f, "] =\n");
|
||||
fprintf(f, " {\n");
|
||||
|
|
@ -1741,17 +1758,17 @@ static void fprint_trainers(const char *output_path, FILE *f, struct Parsed *par
|
|||
|
||||
switch (pokemon->gender)
|
||||
{
|
||||
case GENDER_ANY:
|
||||
fprintf(f, " .gender = TRAINER_MON_RANDOM_GENDER,\n");
|
||||
break;
|
||||
case GENDER_MALE:
|
||||
fprintf(f, "#line %d\n", pokemon->header_line);
|
||||
fprintf(f, " .gender = TRAINER_MON_MALE,\n");
|
||||
break;
|
||||
case GENDER_FEMALE:
|
||||
fprintf(f, "#line %d\n", pokemon->header_line);
|
||||
fprintf(f, " .gender = TRAINER_MON_FEMALE,\n");
|
||||
break;
|
||||
case GENDER_ANY:
|
||||
fprintf(f, " .gender = TRAINER_MON_RANDOM_GENDER,\n");
|
||||
break;
|
||||
case GENDER_MALE:
|
||||
fprintf(f, "#line %d\n", pokemon->header_line);
|
||||
fprintf(f, " .gender = TRAINER_MON_MALE,\n");
|
||||
break;
|
||||
case GENDER_FEMALE:
|
||||
fprintf(f, "#line %d\n", pokemon->header_line);
|
||||
fprintf(f, " .gender = TRAINER_MON_FEMALE,\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!is_empty_string(pokemon->item))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user