This commit is contained in:
AgustinGDLV 2023-03-27 16:22:11 -07:00
commit 504ec36b2b
82 changed files with 2197 additions and 230 deletions

View File

@ -420,17 +420,34 @@ gBattleScriptsForMoveEffects::
.4byte BattleScript_EffectShellTrap @ EFFECT_SHELL_TRAP
.4byte BattleScript_EffectHit @ EFFECT_PSYBLADE
.4byte BattleScript_EffectHit @ EFFECT_HYDRO_STEAM
.4byte BattleScript_EffectHitSetEntryHazard @ EFFECT_HIT_SET_ENTRY_HAZARD
.4byte BattleScript_EffectDireClaw @ EFFECT_DIRE_CLAW
.4byte BattleScript_EffectBarbBarrage @ EFFECT_BARB_BARRAGE
.4byte BattleScript_EffectMaxMove @ EFFECT_MAX_MOVE
BattleScript_StealthRockActivates::
setstealthrock BattleScript_MoveEnd
printstring STRINGID_POINTEDSTONESFLOAT
printfromtable gDmgHazardsStringIds
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_EffectDireClaw::
setmoveeffect MOVE_EFFECT_DIRE_CLAW
goto BattleScript_EffectHit
BattleScript_EffectHitSetEntryHazard::
argumenttomoveeffect
goto BattleScript_EffectHit
BattleScript_SpikesActivates::
trysetspikes BattleScript_MoveEnd
printfromtable gDmgHazardsStringIds
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
BattleScript_SteelsurgeActivates::
setsteelsurge BattleScript_MoveEnd
printstring STRINGID_SHARPSTEELFLOATS
printfromtable gDmgHazardsStringIds
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd
@ -3390,6 +3407,7 @@ BattleScript_CantMakeAsleep::
orhalfword gMoveResultFlags, MOVE_RESULT_FAILED
goto BattleScript_MoveEnd
BattleScript_EffectBarbBarrage:
BattleScript_EffectPoisonHit:
setmoveeffect MOVE_EFFECT_POISON
goto BattleScript_EffectHit
@ -8664,6 +8682,7 @@ BattleScript_IntimidateActivates::
BattleScript_IntimidateLoop:
jumpifbyteequal gBattlerTarget, gBattlerAttacker, BattleScript_IntimidateLoopIncrement
jumpiftargetally BattleScript_IntimidateLoopIncrement
jumpifabsent BS_TARGET, BattleScript_IntimidateLoopIncrement
jumpifstatus2 BS_TARGET, STATUS2_SUBSTITUTE, BattleScript_IntimidateLoopIncrement
jumpifholdeffect BS_TARGET, HOLD_EFFECT_CLEAR_AMULET, BattleScript_IntimidatePrevented_Item
jumpifability BS_TARGET, ABILITY_CLEAR_BODY, BattleScript_IntimidatePrevented

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
255 255 255
248 200 240
224 176 232
200 144 224
240 224 248
176 120 216
77 146 186
105 179 221
238 246 246
222 222 222
197 197 197
161 161 161
48 48 48
255 255 255
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
255 255 255
184 208 248
168 200 248
81 123 173
128 168 216
200 232 248
224 248 248
248 248 248
104 104 104
48 48 48
255 255 255
0 0 0
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
255 255 255
160 144 32
192 176 56
224 208 88
128 112 32
72 56 24
224 80 80
176 88 88
120 72 72
48 48 48
255 255 255
0 0 0
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
0 0 0
189 202 71
121 168 43
120 167 42
163 126 74
116 101 78
79 66 46
115 77 43
180 133 94
233 176 96
241 241 193
183 170 147
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
111 45 22
0 0 0
190 91 13
255 139 1
255 255 255
255 231 10
251 42 6
154 157 151
193 161 19
234 238 234
122 111 115
74 67 68
90 185 248
78 86 255
111 52 255

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
0 0 0
54 52 72
101 120 143
103 139 163
84 105 130
74 75 101
90 108 136
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
180 124 35
115 66 13
255 249 234
224 159 27
255 226 121
255 200 59
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
255 255 255
206 181 41
222 198 57
247 231 140
156 132 33
189 156 41
123 99 33
49 49 49
255 255 255
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
0 0 0
188 143 70
131 85 43
186 181 176
80 74 71
239 185 78
138 128 128
220 217 215
250 225 159
246 205 93
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
48 52 78
127 216 17
0 0 0
192 240 140
128 217 18
90 137 46
129 218 19
88 135 48
107 182 17
128 217 18
93 144 44
89 136 47
255 255 255
127 216 19
48 38 64

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
255 255 255
248 216 232
198 159 217
210 171 229
224 192 240
210 192 240
160 192 232
144 200 232
160 216 240
128 216 224
208 240 240
248 240 240
248 248 248
80 80 80
48 48 48

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
255 255 255
66 66 99
90 90 132
115 115 156
90 115 230
132 140 181
125 147 246
48 48 48
255 255 255
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
0 0 0
39 194 168
124 228 211
19 101 84
187 228 77
238 250 169
234 244 124
24 152 108
126 106 28
173 171 15
43 138 128
127 175 55
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
255 255 255
255 212 0
200 56 32
248 64 48
232 232 232
48 48 48
255 255 255
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
0 0 0
130 116 116
86 86 86
54 41 49
104 78 86
56 56 56
141 105 41
223 191 65
242 241 242
184 172 179
186 140 57
0 0 0
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
0 0 0
118 109 109
143 130 127
101 77 83
73 68 68
122 108 104
141 105 41
223 191 65
242 241 242
184 172 179
186 140 57
102 78 84
0 0 0
0 0 0
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
0 0 0
81 41 75
98 61 92
66 72 65
51 4 43
201 185 199
110 86 106
84 73 92
32 41 34
255 255 255
71 50 92
64 71 94
139 165 201
183 191 209
0 0 0

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
0 0 0
0 0 0
111 167 43
179 192 68
107 144 66
84 116 48
68 93 37
124 137 52
168 87 80
168 116 111
241 241 193
168 87 80
183 170 147
121 52 57
0 0 0
0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 735 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 724 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

View File

@ -1,6 +1,9 @@
#ifndef GUARD_BATTLE_MAIN_H
#define GUARD_BATTLE_MAIN_H
#include "pokemon.h"
#include "data.h"
struct TrainerMoney
{
u8 classId;
@ -66,6 +69,7 @@ bool8 TryRunFromBattle(u8 battlerId);
void SpecialStatusesClear(void);
void SetTypeBeforeUsingMove(u16 move, u8 battlerAtk);
bool32 IsWildMonSmart(void);
u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer *trainer, bool32 firstTrainer, u32 battleTypeFlags);
extern struct MultiPartnerMenuPokemon gMultiPartnerParty[MULTI_PARTY_SIZE];

View File

@ -460,6 +460,8 @@ extern const u8 BattleScript_ShellTrapSetUp[];
extern const u8 BattleScript_StealthRockActivates[];
extern const u8 BattleScript_CouldntFullyProtect[];
extern const u8 BattleScript_MoveEffectStockpileWoreOff[];
extern const u8 BattleScript_StealthRockActivates[];
extern const u8 BattleScript_SpikesActivates[];
// zmoves
extern const u8 BattleScript_ZMoveActivateDamaging[];

View File

@ -374,9 +374,12 @@
#define MOVE_EFFECT_TRAP_BOTH 70
#define MOVE_EFFECT_DOUBLE_SHOCK 71
#define MOVE_EFFECT_ROUND 72
#define MOVE_EFFECT_STOCKPILE_WORE_OFF 74
#define MOVE_EFFECT_STOCKPILE_WORE_OFF 73
#define MOVE_EFFECT_DIRE_CLAW 74
#define MOVE_EFFECT_STEALTH_ROCK 75
#define MOVE_EFFECT_SPIKES 76
#define NUM_MOVE_EFFECTS 75
#define NUM_MOVE_EFFECTS 77
#define MOVE_EFFECT_AFFECTS_USER 0x4000
#define MOVE_EFFECT_CERTAIN 0x8000

View File

@ -401,8 +401,11 @@
#define EFFECT_SHELL_TRAP 395
#define EFFECT_PSYBLADE 396
#define EFFECT_HYDRO_STEAM 397
#define EFFECT_MAX_MOVE 398
#define EFFECT_HIT_SET_ENTRY_HAZARD 398
#define EFFECT_DIRE_CLAW 399
#define EFFECT_BARB_BARRAGE 400
#define EFFECT_MAX_MOVE 401
#define NUM_BATTLE_MOVE_EFFECTS 399
#define NUM_BATTLE_MOVE_EFFECTS 402
#endif // GUARD_CONSTANTS_BATTLE_MOVE_EFFECTS_H

View File

@ -946,4 +946,12 @@
#define B_MSG_Z_STAT_UP 5
#define B_MSG_Z_HP_TRAP 6
// gDmgHazardsStringIds
#define B_MSG_PKMNHURTBYSPIKES 0
#define B_MSG_STEALTHROCKDMG 1
#define B_MSG_SHARPSTEELDMG 2
#define B_MSG_POINTEDSTONESFLOAT 3
#define B_MSG_SPIKESSCATTERED 4
#define B_MSG_SHARPSTEELFLOATS 5
#endif // GUARD_CONSTANTS_BATTLE_STRING_IDS_H

View File

@ -159,6 +159,7 @@
#define HOLD_EFFECT_PUNCHING_GLOVE 178
#define HOLD_EFFECT_COVERT_CLOAK 179
#define HOLD_EFFECT_LOADED_DICE 180
#define HOLD_EFFECT_BOOSTER_ENERGY 181 // Not implemented.
#define HOLD_EFFECT_CHOICE(holdEffect)((holdEffect == HOLD_EFFECT_CHOICE_BAND || holdEffect == HOLD_EFFECT_CHOICE_SCARF || holdEffect == HOLD_EFFECT_CHOICE_SPECS))

View File

@ -928,13 +928,48 @@
#define ITEM_RUBY 756
#define ITEM_SAPPHIRE 757
// GEN IX ITEMS
#define ITEM_ABILITY_SHIELD 758
#define ITEM_CLEAR_AMULET 759
#define ITEM_PUNCHING_GLOVE 760
#define ITEM_COVERT_CLOAK 761
#define ITEM_LOADED_DICE 762
#define ITEM_AUSPICIOUS_ARMOR 763
#define ITEM_BOOSTER_ENERGY 764
#define ITEM_BIG_BAMBOO_SHOOT 765
#define ITEM_GIMMIGHOUL_COIN 766
#define ITEM_LEADERS_CREST 767
#define ITEM_MALICIOUS_ARMOR 768
#define ITEM_MIRROR_HERB 769
#define ITEM_SCROLL_OF_DARKNESS 770
#define ITEM_SCROLL_OF_WATERS 771
#define ITEM_TERA_ORB 772
#define ITEM_TINY_BAMBOO_SHOOT 773
#define ITEMS_COUNT 763
#define ITEM_BUG_TERA_SHARD 774
#define ITEM_DARK_TERA_SHARD 775
#define ITEM_DRAGON_TERA_SHARD 776
#define ITEM_ELECTRIC_TERA_SHARD 777
#define ITEM_FAIRY_TERA_SHARD 778
#define ITEM_FIGHTING_TERA_SHARD 779
#define ITEM_FIRE_TERA_SHARD 780
#define ITEM_FLYING_TERA_SHARD 781
#define ITEM_GHOST_TERA_SHARD 782
#define ITEM_GRASS_TERA_SHARD 783
#define ITEM_GROUND_TERA_SHARD 784
#define ITEM_ICE_TERA_SHARD 785
#define ITEM_NORMAL_TERA_SHARD 786
#define ITEM_POISON_TERA_SHARD 787
#define ITEM_PSYCHIC_TERA_SHARD 788
#define ITEM_ROCK_TERA_SHARD 789
#define ITEM_STEEL_TERA_SHARD 790
#define ITEM_WATER_TERA_SHARD 791
#define ITEM_ADAMANT_CRYSTAL 792
#define ITEM_GRISEOUS_CORE 793
#define ITEM_LUSTROUS_GLOBE 794
#define ITEMS_COUNT 795
#define ITEM_FIELD_ARROW ITEMS_COUNT
// A special item id associated with "Cancel"/"Exit" etc. in a list of items or decorations

View File

@ -374,7 +374,12 @@
// All trainer parties specify the IV, level, and species for each Pokémon in the
// party. Some trainer parties also specify held items and custom moves for each
// Pokémon.
#define F_TRAINER_PARTY_CUSTOM_MOVESET (1 << 0)
#define F_TRAINER_PARTY_HELD_ITEM (1 << 1)
#define F_TRAINER_PARTY_CUSTOM_MOVESET (1 << 0)
#define F_TRAINER_PARTY_HELD_ITEM (1 << 1)
#define F_TRAINER_PARTY_EVERYTHING_CUSTOMIZED (1 << 3)
// Trainer party defines
#define TRAINER_MON_MALE 1
#define TRAINER_MON_FEMALE 2
#endif // GUARD_TRAINERS_H

View File

@ -31,6 +31,26 @@ struct MonCoords
#define MON_COORDS_SIZE(width, height)(DIV_ROUND_UP(width, 8) << 4 | DIV_ROUND_UP(height, 8))
#define GET_MON_COORDS_WIDTH(size)((size >> 4) * 8)
#define GET_MON_COORDS_HEIGHT(size)((size & 0xF) * 8)
#define TRAINER_PARTY_IVS(hp, atk, def, speed, spatk, spdef) (hp | (atk << 5) | (def << 10) | (speed << 15) | (spatk << 20) | (spdef << 25))
#define TRAINER_PARTY_EVS(hp, atk, def, speed, spatk, spdef) ((const u8[6]){hp,atk,def,spatk,spdef,speed})
#define TRAINER_PARTY_NATURE(nature) (nature+1)
struct TrainerMonCustomized
{
const u8 *nickname;
const u8 *ev;
u32 iv;
u16 moves[4];
u16 species;
u16 heldItem;
u16 ability;
u8 lvl;
u8 ball;
u8 friendship;
u8 nature : 5;
bool8 gender : 2;
bool8 isShiny : 1;
};
struct TrainerMonNoItemDefaultMoves
{
@ -68,6 +88,7 @@ struct TrainerMonItemCustomMoves
#define NO_ITEM_CUSTOM_MOVES(party) { .NoItemCustomMoves = party }, .partySize = ARRAY_COUNT(party), .partyFlags = F_TRAINER_PARTY_CUSTOM_MOVESET
#define ITEM_DEFAULT_MOVES(party) { .ItemDefaultMoves = party }, .partySize = ARRAY_COUNT(party), .partyFlags = F_TRAINER_PARTY_HELD_ITEM
#define ITEM_CUSTOM_MOVES(party) { .ItemCustomMoves = party }, .partySize = ARRAY_COUNT(party), .partyFlags = F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM
#define EVERYTHING_CUSTOMIZED(party) { .EverythingCustomized = party}, .partySize = ARRAY_COUNT(party), .partyFlags = F_TRAINER_PARTY_EVERYTHING_CUSTOMIZED
union TrainerMonPtr
{
@ -75,20 +96,21 @@ union TrainerMonPtr
const struct TrainerMonNoItemCustomMoves *NoItemCustomMoves;
const struct TrainerMonItemDefaultMoves *ItemDefaultMoves;
const struct TrainerMonItemCustomMoves *ItemCustomMoves;
const struct TrainerMonCustomized *EverythingCustomized;
};
struct Trainer
{
/*0x00*/ u8 partyFlags;
/*0x01*/ u8 trainerClass;
/*0x02*/ u8 encounterMusic_gender; // last bit is gender
/*0x03*/ u8 trainerPic;
/*0x04*/ u8 trainerName[TRAINER_NAME_LENGTH + 1];
/*0x10*/ u16 items[MAX_TRAINER_ITEMS];
/*0x18*/ bool8 doubleBattle;
/*0x1C*/ u32 aiFlags;
/*0x20*/ u8 partySize;
/*0x24*/ union TrainerMonPtr party;
/*0x00*/ u32 aiFlags;
/*0x04*/ union TrainerMonPtr party;
/*0x08*/ u16 items[MAX_TRAINER_ITEMS];
/*0x10*/ u8 trainerClass;
/*0x11*/ u8 encounterMusic_gender; // last bit is gender
/*0x12*/ u8 trainerPic;
/*0x13*/ u8 trainerName[TRAINER_NAME_LENGTH + 1];
/*0x1E*/ bool8 doubleBattle:1;
u8 partyFlags:7;
/*0x1F*/ u8 partySize;
};
#define TRAINER_ENCOUNTER_MUSIC(trainer)((gTrainers[trainer].encounterMusic_gender & 0x7F))

View File

@ -147,6 +147,9 @@
#define CAT(a, b) CAT_(a, b)
#define CAT_(a, b) a ## b
// Converts a string to a compound literal, essentially making it a pointer to const u8
#define COMPOUND_STRING(str) (const u8[]) _(str)
// This produces an error at compile-time if expr is zero.
// It looks like file.c:line: size of array `id' is negative
#define STATIC_ASSERT(expr, id) typedef char id[(expr) ? 1 : -1];

View File

@ -8999,6 +8999,45 @@ extern const u32 gItemIcon_Gem[];
extern const u32 gItemIconPalette_Ruby[];
extern const u32 gItemIconPalette_Sapphire[];
// GEN IX ITEMS
extern const u32 gItemIcon_AbilityShield[];
extern const u32 gItemIconPalette_AbilityShield[];
extern const u32 gItemIcon_AuspiciousArmor[];
extern const u32 gItemIconPalette_AuspiciousArmor[];
extern const u32 gItemIcon_BigBambooShoot[];
extern const u32 gItemIconPalette_BigBambooShoot[];
extern const u32 gItemIcon_BoosterEnergy[];
extern const u32 gItemIconPalette_BoosterEnergy[];
extern const u32 gItemIcon_CovertCloak[];
extern const u32 gItemIconPalette_CovertCloak[];
extern const u32 gItemIcon_GimmighoulCoin[];
extern const u32 gItemIconPalette_GimmighoulCoin[];
extern const u32 gItemIcon_LeadersCrest[];
extern const u32 gItemIconPalette_LeadersCrest[];
extern const u32 gItemIcon_LoadedDice[];
extern const u32 gItemIconPalette_LoadedDice[];
extern const u32 gItemIcon_MaliciousArmor[];
extern const u32 gItemIconPalette_MaliciousArmor[];
extern const u32 gItemIcon_MirrorHerb[];
extern const u32 gItemIconPalette_MirrorHerb[];
extern const u32 gItemIcon_PunchingGlove[];
extern const u32 gItemIconPalette_PunchingGlove[];
extern const u32 gItemIcon_ScrollOfDarkness[];
extern const u32 gItemIconPalette_ScrollOfDarkness[];
extern const u32 gItemIcon_ScrollOfWaters[];
extern const u32 gItemIconPalette_ScrollOfWaters[];
extern const u32 gItemIcon_TeraOrb[];
extern const u32 gItemIconPalette_TeraOrb[];
extern const u32 gItemIcon_TinyBambooShoot[];
extern const u32 gItemIconPalette_TinyBambooShoot[];
extern const u32 gItemIcon_AdamantCrystal[];
extern const u32 gItemIconPalette_AdamantCrystal[];
extern const u32 gItemIcon_GriseousCore[];
extern const u32 gItemIconPalette_GriseousCore[];
extern const u32 gItemIcon_LustrousGlobe[];
extern const u32 gItemIconPalette_LustrousGlobe[];
extern const u32 gItemIcon_ReturnToFieldArrow[];
extern const u32 gItemIconPalette_ReturnToFieldArrow[];

View File

@ -3477,6 +3477,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
break;
case EFFECT_TOXIC:
case EFFECT_POISON:
case EFFECT_BARB_BARRAGE:
IncreasePoisonScore(battlerAtk, battlerDef, move, &score);
break;
case EFFECT_LIGHT_SCREEN:
@ -3868,6 +3869,7 @@ static s16 AI_CheckViability(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
break;
case EFFECT_SPIKES:
case EFFECT_HIT_SET_ENTRY_HAZARD:
case EFFECT_STEALTH_ROCK:
case EFFECT_STICKY_WEB:
case EFFECT_TOXIC_SPIKES:
@ -4902,6 +4904,7 @@ static s16 AI_SetupFirstTurn(u8 battlerAtk, u8 battlerDef, u16 move, s16 score)
case EFFECT_HAIL:
case EFFECT_GEOMANCY:
case EFFECT_VICTORY_DANCE:
case EFFECT_HIT_SET_ENTRY_HAZARD:
score += 2;
break;
default:

View File

@ -440,22 +440,24 @@ static u8 GetBattleAnimMoveTargets(u8 battlerArgIndex, u8 *targets)
case MOVE_TARGET_BOTH:
targets[0] = gBattleAnimArgs[battlerArgIndex];
numTargets = 1;
if (IsBattlerAlive(targets[0] ^ BIT_FLANK)) {
targets[1] = targets[0] ^ BIT_FLANK;
numTargets++;
if (IsBattlerAlive(BATTLE_PARTNER(targets[0])))
{
targets[1] = BATTLE_PARTNER(targets[0]);
numTargets = 2;
}
break;
case MOVE_TARGET_FOES_AND_ALLY:
targets[0] = gBattleAnimArgs[battlerArgIndex];
numTargets = 1;
if (IsBattlerAlive(targets[0] ^ BIT_FLANK)) {
targets[1] = targets[0] ^ BIT_FLANK;
if (IsBattlerAlive(BATTLE_PARTNER(targets[0])))
{
targets[1] = BATTLE_PARTNER(targets[0]);
numTargets++;
}
if (IsBattlerAlive(gBattleAnimAttacker ^ BIT_FLANK)) {
targets[2] = gBattleAnimAttacker ^ BIT_FLANK;
if (IsBattlerAlive(BATTLE_PARTNER(BATTLE_OPPOSITE(targets[0]))))
{
targets[2] = BATTLE_PARTNER(BATTLE_OPPOSITE(targets[0]));
numTargets++;
}
break;

View File

@ -703,6 +703,7 @@ u16 SetMaxMoveEffect(u16 move)
case MAX_EFFECT_STEALTH_ROCK:
if (!(gSideStatuses[GetBattlerSide(gBattlerTarget)] & SIDE_STATUS_STEALTH_ROCK))
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_POINTEDSTONESFLOAT;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_StealthRockActivates;
effect++;
@ -711,6 +712,7 @@ u16 SetMaxMoveEffect(u16 move)
case MAX_EFFECT_STEELSURGE:
if (!(gSideStatuses[GetBattlerSide(gBattlerTarget)] & SIDE_STATUS_STEELSURGE))
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SHARPSTEELFLOATS;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_SteelsurgeActivates;
effect++;

View File

@ -118,6 +118,10 @@ static void HandleEndTurn_FinishBattle(void);
static void SpriteCB_UnusedBattleInit(struct Sprite *sprite);
static void SpriteCB_UnusedBattleInit_Main(struct Sprite *sprite);
static void TrySpecialEvolution(void);
static u32 Crc32B (const u8 *data, u32 size);
static u32 GeneratePartyHash(const struct Trainer *trainer, u32 i);
static void ModifyPersonalityForNature(u32 *personality, u32 newNature);
static u32 GeneratePersonalityForGender(u32 gender, u32 species);
EWRAM_DATA u16 gBattle_BG0_X = 0;
EWRAM_DATA u16 gBattle_BG0_Y = 0;
@ -1857,72 +1861,129 @@ static void SpriteCB_UnusedBattleInit_Main(struct Sprite *sprite)
}
}
static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 firstTrainer)
static u32 Crc32B (const u8 *data, u32 size)
{
s32 i, j;
u32 byte, crc, mask;
i = 0;
crc = 0xFFFFFFFF;
for (i = 0; i < size; ++i)
{
byte = data[i];
crc = crc ^ byte;
for (j = 7; j >= 0; --j)
{
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
}
return ~crc;
}
static u32 GeneratePartyHash(const struct Trainer *trainer, u32 i)
{
const u8 *buffer;
u32 n;
if (trainer->partyFlags == 0)
{
buffer = (const u8 *) &trainer->party.NoItemDefaultMoves[i];
n = sizeof(*trainer->party.NoItemDefaultMoves);
}
else if (trainer->partyFlags == F_TRAINER_PARTY_CUSTOM_MOVESET)
{
buffer = (const u8 *) &trainer->party.NoItemCustomMoves[i];
n = sizeof(*trainer->party.NoItemCustomMoves);
}
else if (trainer->partyFlags == F_TRAINER_PARTY_HELD_ITEM)
{
buffer = (const u8 *) &trainer->party.ItemDefaultMoves[i];
n = sizeof(*trainer->party.ItemDefaultMoves);
}
else if (trainer->partyFlags == (F_TRAINER_PARTY_HELD_ITEM | F_TRAINER_PARTY_CUSTOM_MOVESET))
{
buffer = (const u8 *) &trainer->party.ItemCustomMoves[i];
n = sizeof(*trainer->party.ItemCustomMoves);
}
else if (trainer->partyFlags == F_TRAINER_PARTY_EVERYTHING_CUSTOMIZED)
{
buffer = (const u8 *) &trainer->party.EverythingCustomized[i];
n = sizeof(*trainer->party.EverythingCustomized);
}
return Crc32B(buffer, n);
}
static void ModifyPersonalityForNature(u32 *personality, u32 newNature)
{
u32 nature = GetNatureFromPersonality(*personality);
s32 diff = abs(nature - newNature);
s32 sign = (nature > newNature) ? 1 : -1;
if (diff > NUM_NATURES / 2)
{
diff = NUM_NATURES - diff;
sign *= -1;
}
*personality -= (diff * sign);
}
static u32 GeneratePersonalityForGender(u32 gender, u32 species)
{
const struct SpeciesInfo *speciesInfo = &gSpeciesInfo[species];
if (gender == MON_MALE)
return ((255 - speciesInfo->genderRatio) / 2) + speciesInfo->genderRatio;
else
return speciesInfo->genderRatio / 2;
}
u8 CreateNPCTrainerPartyFromTrainer(struct Pokemon *party, const struct Trainer *trainer, bool32 firstTrainer, u32 battleTypeFlags)
{
u32 nameHash = 0;
u32 personalityValue;
u8 fixedIV;
s32 i, j;
u8 monsCount;
u16 ball;
if (trainerNum == TRAINER_SECRET_BASE)
return 0;
if (gBattleTypeFlags & BATTLE_TYPE_TRAINER && !(gBattleTypeFlags & (BATTLE_TYPE_FRONTIER
s32 ball = -1;
if (battleTypeFlags & BATTLE_TYPE_TRAINER && !(battleTypeFlags & (BATTLE_TYPE_FRONTIER
| BATTLE_TYPE_EREADER_TRAINER
| BATTLE_TYPE_TRAINER_HILL)))
{
if (firstTrainer == TRUE)
ZeroEnemyPartyMons();
if (gBattleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
if (battleTypeFlags & BATTLE_TYPE_TWO_OPPONENTS)
{
if (gTrainers[trainerNum].partySize > PARTY_SIZE / 2)
if (trainer->partySize > PARTY_SIZE / 2)
monsCount = PARTY_SIZE / 2;
else
monsCount = gTrainers[trainerNum].partySize;
monsCount = trainer->partySize;
}
else
{
monsCount = gTrainers[trainerNum].partySize;
monsCount = trainer->partySize;
}
for (i = 0; i < monsCount; i++)
{
if (gTrainers[trainerNum].doubleBattle == TRUE)
u32 personalityHash = GeneratePartyHash(trainer, i);
if (trainer->doubleBattle == TRUE)
personalityValue = 0x80;
else if (gTrainers[trainerNum].encounterMusic_gender & F_TRAINER_FEMALE)
else if (trainer->encounterMusic_gender & F_TRAINER_FEMALE)
personalityValue = 0x78; // Use personality more likely to result in a female Pokémon
else
personalityValue = 0x88; // Use personality more likely to result in a male Pokémon
for (j = 0; gTrainers[trainerNum].trainerName[j] != EOS; j++)
nameHash += gTrainers[trainerNum].trainerName[j];
switch (gTrainers[trainerNum].partyFlags)
personalityValue += personalityHash << 8;
switch (trainer->partyFlags)
{
case 0:
{
const struct TrainerMonNoItemDefaultMoves *partyData = gTrainers[trainerNum].party.NoItemDefaultMoves;
for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
nameHash += gSpeciesNames[partyData[i].species][j];
personalityValue += nameHash << 8;
const struct TrainerMonNoItemDefaultMoves *partyData = trainer->party.NoItemDefaultMoves;
fixedIV = partyData[i].iv * MAX_PER_STAT_IVS / 255;
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, OT_ID_RANDOM_NO_SHINY, 0);
break;
}
case F_TRAINER_PARTY_CUSTOM_MOVESET:
{
const struct TrainerMonNoItemCustomMoves *partyData = gTrainers[trainerNum].party.NoItemCustomMoves;
for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
nameHash += gSpeciesNames[partyData[i].species][j];
personalityValue += nameHash << 8;
const struct TrainerMonNoItemCustomMoves *partyData = trainer->party.NoItemCustomMoves;
fixedIV = partyData[i].iv * MAX_PER_STAT_IVS / 255;
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, OT_ID_RANDOM_NO_SHINY, 0);
@ -1935,12 +1996,7 @@ static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 fir
}
case F_TRAINER_PARTY_HELD_ITEM:
{
const struct TrainerMonItemDefaultMoves *partyData = gTrainers[trainerNum].party.ItemDefaultMoves;
for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
nameHash += gSpeciesNames[partyData[i].species][j];
personalityValue += nameHash << 8;
const struct TrainerMonItemDefaultMoves *partyData = trainer->party.ItemDefaultMoves;
fixedIV = partyData[i].iv * MAX_PER_STAT_IVS / 255;
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, OT_ID_RANDOM_NO_SHINY, 0);
@ -1949,12 +2005,7 @@ static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 fir
}
case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM:
{
const struct TrainerMonItemCustomMoves *partyData = gTrainers[trainerNum].party.ItemCustomMoves;
for (j = 0; gSpeciesNames[partyData[i].species][j] != EOS; j++)
nameHash += gSpeciesNames[partyData[i].species][j];
personalityValue += nameHash << 8;
const struct TrainerMonItemCustomMoves *partyData = trainer->party.ItemCustomMoves;
fixedIV = partyData[i].iv * MAX_PER_STAT_IVS / 255;
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, fixedIV, TRUE, personalityValue, OT_ID_RANDOM_NO_SHINY, 0);
@ -1967,18 +2018,88 @@ static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 fir
}
break;
}
case F_TRAINER_PARTY_EVERYTHING_CUSTOMIZED:
{
const struct TrainerMonCustomized *partyData = trainer->party.EverythingCustomized;
u32 otIdType = OT_ID_RANDOM_NO_SHINY;
u32 fixedOtId = 0;
if (partyData[i].gender == TRAINER_MON_MALE)
personalityValue = (personalityValue & 0xFFFFFF00) | GeneratePersonalityForGender(MON_MALE, partyData[i].species);
else if (partyData[i].gender == TRAINER_MON_FEMALE)
personalityValue = (personalityValue & 0xFFFFFF00) | GeneratePersonalityForGender(MON_FEMALE, partyData[i].species);
if (partyData[i].nature != 0)
ModifyPersonalityForNature(&personalityValue, partyData[i].nature - 1);
if (partyData[i].isShiny)
{
otIdType = OT_ID_PRESET;
fixedOtId = HIHALF(personalityValue) ^ LOHALF(personalityValue);
}
CreateMon(&party[i], partyData[i].species, partyData[i].lvl, 0, TRUE, personalityValue, otIdType, fixedOtId);
SetMonData(&party[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem);
// TODO: Figure out a default strategy when moves are not set, to generate a good moveset
for (j = 0; j < MAX_MON_MOVES; ++j)
{
SetMonData(&party[i], MON_DATA_MOVE1 + j, &partyData[i].moves[j]);
SetMonData(&party[i], MON_DATA_PP1 + j, &gBattleMoves[partyData[i].moves[j]].pp);
}
SetMonData(&party[i], MON_DATA_IVS, &(partyData[i].iv));
if (partyData[i].ev != NULL)
{
SetMonData(&party[i], MON_DATA_HP_EV, &(partyData[i].ev[0]));
SetMonData(&party[i], MON_DATA_ATK_EV, &(partyData[i].ev[1]));
SetMonData(&party[i], MON_DATA_DEF_EV, &(partyData[i].ev[2]));
SetMonData(&party[i], MON_DATA_SPATK_EV, &(partyData[i].ev[3]));
SetMonData(&party[i], MON_DATA_SPDEF_EV, &(partyData[i].ev[4]));
SetMonData(&party[i], MON_DATA_SPEED_EV, &(partyData[i].ev[5]));
}
if (partyData[i].ability != ABILITY_NONE)
{
const struct SpeciesInfo *speciesInfo = &gSpeciesInfo[partyData[i].species];
u32 maxAbilities = ARRAY_COUNT(speciesInfo->abilities);
for (j = 0; j < maxAbilities; ++j)
{
if (speciesInfo->abilities[j] == partyData[i].ability)
break;
}
if (j < maxAbilities)
SetMonData(&party[i], MON_DATA_ABILITY_NUM, &j);
}
SetMonData(&party[i], MON_DATA_FRIENDSHIP, &(partyData[i].friendship));
if (partyData[i].ball != ITEM_NONE)
{
ball = partyData[i].ball;
SetMonData(&party[i], MON_DATA_POKEBALL, &ball);
}
if (partyData[i].nickname != NULL)
{
SetMonData(&party[i], MON_DATA_NICKNAME, partyData[i].nickname);
}
CalculateMonStats(&party[i]);
}
}
#if B_TRAINER_CLASS_POKE_BALLS >= GEN_7
ball = (sTrainerBallTable[gTrainers[trainerNum].trainerClass]) ? sTrainerBallTable[gTrainers[trainerNum].trainerClass] : ITEM_POKE_BALL;
SetMonData(&party[i], MON_DATA_POKEBALL, &ball);
if (ball == -1)
{
ball = (sTrainerBallTable[trainer->trainerClass]) ? sTrainerBallTable[trainer->trainerClass] : ITEM_POKE_BALL;
SetMonData(&party[i], MON_DATA_POKEBALL, &ball);
}
#endif
}
gBattleTypeFlags |= gTrainers[trainerNum].doubleBattle;
}
return gTrainers[trainerNum].partySize;
return trainer->partySize;
}
static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 firstTrainer)
{
u8 retVal;
if (trainerNum == TRAINER_SECRET_BASE)
return 0;
retVal = CreateNPCTrainerPartyFromTrainer(party, &gTrainers[trainerNum], firstTrainer, gBattleTypeFlags);
gBattleTypeFlags |= gTrainers[trainerNum].doubleBattle;
}
void VBlankCB_Battle(void)

View File

@ -209,7 +209,7 @@ static const u8 sText_PkmnFellIntoNightmare[] = _("{B_DEF_NAME_WITH_PREFIX} fell
static const u8 sText_PkmnLockedInNightmare[] = _("{B_ATK_NAME_WITH_PREFIX} is locked\nin a NIGHTMARE!");
static const u8 sText_PkmnLaidCurse[] = _("{B_ATK_NAME_WITH_PREFIX} cut its own HP and\nlaid a CURSE on {B_DEF_NAME_WITH_PREFIX}!");
static const u8 sText_PkmnAfflictedByCurse[] = _("{B_ATK_NAME_WITH_PREFIX} is afflicted\nby the CURSE!");
static const u8 sText_SpikesScattered[] = _("Spikes were scattered all around\nthe opponent's side!");
static const u8 sText_SpikesScattered[] = _("Spikes were scattered all around\n{B_DEF_TEAM2} team!");
static const u8 sText_PkmnHurtBySpikes[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX} is hurt\nby spikes!");
static const u8 sText_PkmnIdentified[] = _("{B_ATK_NAME_WITH_PREFIX} identified\n{B_DEF_NAME_WITH_PREFIX}!");
static const u8 sText_PkmnPerishCountFell[] = _("{B_ATK_NAME_WITH_PREFIX}'s PERISH count\nfell to {B_BUFF1}!");
@ -1501,7 +1501,12 @@ const u16 gHealingWishStringIds[] =
const u16 gDmgHazardsStringIds[] =
{
STRINGID_PKMNHURTBYSPIKES, STRINGID_STEALTHROCKDMG, STRINGID_SHARPSTEELDMG
[B_MSG_PKMNHURTBYSPIKES] = STRINGID_PKMNHURTBYSPIKES,
[B_MSG_STEALTHROCKDMG] = STRINGID_STEALTHROCKDMG,
[B_MSG_SHARPSTEELDMG] = STRINGID_SHARPSTEELDMG,
[B_MSG_POINTEDSTONESFLOAT] = STRINGID_POINTEDSTONESFLOAT,
[B_MSG_SPIKESSCATTERED] = STRINGID_SPIKESSCATTERED,
[B_MSG_SHARPSTEELFLOATS] = STRINGID_SHARPSTEELFLOATS,
};
const u16 gSwitchInAbilityStringIds[] =

View File

@ -2904,6 +2904,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
bool32 mirrorArmorReflected = (GetBattlerAbility(gBattlerTarget) == ABILITY_MIRROR_ARMOR);
u32 flags = 0;
u16 battlerAbility;
bool8 activateAfterFaint = FALSE;
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_1ST_HIT
&& gBattleMons[gBattlerTarget].hp != 0
@ -2922,6 +2923,13 @@ void SetMoveEffect(bool32 primary, u32 certain)
gBattleStruct->moveEffect2 = gBattleScripting.moveEffect;
gBattlescriptCurrInstr++;
return;
case MOVE_EFFECT_STEALTH_ROCK:
case MOVE_EFFECT_SPIKES:
case MOVE_EFFECT_PAYDAY:
case MOVE_EFFECT_STEAL_ITEM:
case MOVE_EFFECT_BUG_BITE:
activateAfterFaint = TRUE;
break;
}
if (gBattleScripting.moveEffect & MOVE_EFFECT_AFFECTS_USER)
@ -2962,10 +2970,7 @@ void SetMoveEffect(bool32 primary, u32 certain)
if (TestSheerForceFlag(gBattlerAttacker, gCurrentMove) && affectsUser != MOVE_EFFECT_AFFECTS_USER)
INCREMENT_RESET_RETURN
if (gBattleMons[gEffectBattler].hp == 0
&& gBattleScripting.moveEffect != MOVE_EFFECT_PAYDAY
&& gBattleScripting.moveEffect != MOVE_EFFECT_STEAL_ITEM
&& gBattleScripting.moveEffect != MOVE_EFFECT_BUG_BITE)
if (gBattleMons[gEffectBattler].hp == 0 && !activateAfterFaint)
INCREMENT_RESET_RETURN
if (DoesSubstituteBlockMove(gBattlerAttacker, gEffectBattler, gCurrentMove) && affectsUser != MOVE_EFFECT_AFFECTS_USER)
@ -3774,6 +3779,30 @@ void SetMoveEffect(bool32 primary, u32 certain)
TryUpdateRoundTurnOrder(); // If another Pokémon uses Round before the user this turn, the user will use Round directly after it
gBattlescriptCurrInstr++;
break;
case MOVE_EFFECT_DIRE_CLAW:
if (!gBattleMons[gEffectBattler].status1)
{
static const u8 sDireClawEffects[] = { MOVE_EFFECT_POISON, MOVE_EFFECT_PARALYSIS, MOVE_EFFECT_SLEEP };
gBattleScripting.moveEffect = sDireClawEffects[Random() % ARRAY_COUNT(sDireClawEffects)];
SetMoveEffect(TRUE, 0);
}
break;
case MOVE_EFFECT_STEALTH_ROCK:
if (!(gSideStatuses[GetBattlerSide(gEffectBattler)] & SIDE_STATUS_STEALTH_ROCK))
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_POINTEDSTONESFLOAT;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_StealthRockActivates;
}
break;
case MOVE_EFFECT_SPIKES:
if (gSideTimers[GetBattlerSide(gEffectBattler)].spikesAmount < 3)
{
gBattleCommunication[MULTISTRING_CHOOSER] = B_MSG_SPIKESSCATTERED;
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_SpikesActivates;
}
break;
}
}
}
@ -5339,7 +5368,8 @@ static bool32 TryKnockOffBattleScript(u32 battlerDef)
gLastUsedItem = gBattleMons[battlerDef].item;
gBattleMons[battlerDef].item = 0;
gBattleStruct->choicedMove[battlerDef] = 0;
if (gBattleMons[battlerDef].ability != ABILITY_GORILLA_TACTICS)
gBattleStruct->choicedMove[battlerDef] = 0;
gWishFutureKnock.knockedOffMons[side] |= gBitTable[gBattlerPartyIndexes[battlerDef]];
CheckSetUnburden(battlerDef);
@ -6984,9 +7014,9 @@ bool32 ShouldPostponeSwitchInAbilities(u32 battlerId)
// Checks for double battle, so abilities like Intimidate wait until all battlers are switched-in before activating.
if (IsDoubleBattle())
{
if (aliveOpposing1 && !aliveOpposing2 && !HasNoMonsToSwitch(BATTLE_OPPOSITE(battlerId), PARTY_SIZE, PARTY_SIZE))
if (aliveOpposing1 && !aliveOpposing2 && !HasNoMonsToSwitch(BATTLE_PARTNER(BATTLE_OPPOSITE(battlerId)), PARTY_SIZE, PARTY_SIZE))
return TRUE;
if (!aliveOpposing1 && aliveOpposing2 && !HasNoMonsToSwitch(BATTLE_PARTNER(BATTLE_OPPOSITE(battlerId)), PARTY_SIZE, PARTY_SIZE))
if (!aliveOpposing1 && aliveOpposing2 && !HasNoMonsToSwitch(BATTLE_OPPOSITE(battlerId), PARTY_SIZE, PARTY_SIZE))
return TRUE;
}
@ -7047,7 +7077,7 @@ static void Cmd_switchineffects(void)
gBattleMoveDamage = 1;
gSideStatuses[GetBattlerSide(gActiveBattler)] |= SIDE_STATUS_SPIKES_DAMAGED;
SetDmgHazardsBattlescript(gActiveBattler, 0);
SetDmgHazardsBattlescript(gActiveBattler, B_MSG_PKMNHURTBYSPIKES);
}
else if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_STEALTH_ROCK_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_STEALTH_ROCK)
@ -7058,7 +7088,7 @@ static void Cmd_switchineffects(void)
gBattleMoveDamage = GetStealthHazardDamage(gBattleMoves[MOVE_STEALTH_ROCK].type, gActiveBattler);
if (gBattleMoveDamage != 0)
SetDmgHazardsBattlescript(gActiveBattler, 1);
SetDmgHazardsBattlescript(gActiveBattler, B_MSG_STEALTHROCKDMG);
}
else if (!(gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_TOXIC_SPIKES_DAMAGED)
&& (gSideStatuses[GetBattlerSide(gActiveBattler)] & SIDE_STATUS_TOXIC_SPIKES)
@ -7115,7 +7145,7 @@ static void Cmd_switchineffects(void)
gBattleMoveDamage = GetStealthHazardDamage(gBattleMoves[MOVE_G_MAX_STEELSURGE].type, gActiveBattler);
if (gBattleMoveDamage != 0)
SetDmgHazardsBattlescript(gActiveBattler, 2);
SetDmgHazardsBattlescript(gActiveBattler, B_MSG_SHARPSTEELDMG);
}
else if (gBattleMons[gActiveBattler].hp != gBattleMons[gActiveBattler].maxHP && gBattleStruct->zmove.healReplacement)
{
@ -7514,6 +7544,12 @@ static u32 GetTrainerMoneyToGive(u16 trainerId)
lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl;
}
break;
case F_TRAINER_PARTY_EVERYTHING_CUSTOMIZED:
{
const struct TrainerMonCustomized *party = gTrainers[trainerId].party.EverythingCustomized;
lastMonLevel = party[gTrainers[trainerId].partySize - 1].lvl;
}
break;
}
for (; gTrainerMoneyTable[i].classId != 0xFF; i++)

View File

@ -795,6 +795,14 @@ static u8 GetSumOfEnemyPartyLevel(u16 opponentId, u8 numMons)
sum += party[i].lvl;
}
break;
case F_TRAINER_PARTY_EVERYTHING_CUSTOMIZED:
{
const struct TrainerMonCustomized *party;
party = gTrainers[opponentId].party.EverythingCustomized;
for (i = 0; i < count; i++)
sum += party[i].lvl;
}
break;
}
return sum;

View File

@ -23,6 +23,7 @@
#include "field_message_box.h"
#include "tv.h"
#include "battle_factory.h"
#include "constants/abilities.h"
#include "constants/apprentice.h"
#include "constants/battle_dome.h"
#include "constants/battle_frontier.h"
@ -3007,6 +3008,7 @@ static void FillPartnerParty(u16 trainerId)
u16 monId;
u32 otID;
u8 trainerName[(PLAYER_NAME_LENGTH * 3) + 1];
s32 ball = -1;
SetFacilityPtrsGetLevel();
if (trainerId == TRAINER_STEVEN_PARTNER)
@ -3098,6 +3100,53 @@ static void FillPartnerParty(u16 trainerId)
}
break;
}
case F_TRAINER_PARTY_EVERYTHING_CUSTOMIZED:
{
const struct TrainerMonCustomized *partyData = gTrainers[trainerId - TRAINER_CUSTOM_PARTNER].party.EverythingCustomized;
CreateMon(&gPlayerParty[i], partyData[i].species, partyData[i].lvl, 0, TRUE, j, TRUE, otID);
SetMonData(&gPlayerParty[i], MON_DATA_HELD_ITEM, &partyData[i].heldItem);
// TODO: Figure out a default strategy when moves are not set, to generate a good moveset
for (j = 0; j < MAX_MON_MOVES; ++j)
{
SetMonData(&gPlayerParty[i], MON_DATA_MOVE1 + j, &partyData[i].moves[j]);
SetMonData(&gPlayerParty[i], MON_DATA_PP1 + j, &gBattleMoves[partyData[i].moves[j]].pp);
}
SetMonData(&gPlayerParty[i], MON_DATA_IVS, &(partyData[i].iv));
if (partyData[i].ev != NULL)
{
SetMonData(&gPlayerParty[i], MON_DATA_HP_EV, &(partyData[i].ev[0]));
SetMonData(&gPlayerParty[i], MON_DATA_ATK_EV, &(partyData[i].ev[1]));
SetMonData(&gPlayerParty[i], MON_DATA_DEF_EV, &(partyData[i].ev[2]));
SetMonData(&gPlayerParty[i], MON_DATA_SPATK_EV, &(partyData[i].ev[3]));
SetMonData(&gPlayerParty[i], MON_DATA_SPDEF_EV, &(partyData[i].ev[4]));
SetMonData(&gPlayerParty[i], MON_DATA_SPEED_EV, &(partyData[i].ev[5]));
}
if (partyData[i].ability != ABILITY_NONE)
{
const struct SpeciesInfo *speciesInfo = &gSpeciesInfo[partyData[i].species];
u32 maxAbilities = ARRAY_COUNT(speciesInfo->abilities);
for (j = 0; j < maxAbilities; ++j)
{
if (speciesInfo->abilities[j] == partyData[i].ability)
break;
}
if (j < maxAbilities)
SetMonData(&gPlayerParty[i], MON_DATA_ABILITY_NUM, &j);
}
SetMonData(&gPlayerParty[i], MON_DATA_FRIENDSHIP, &(partyData[i].friendship));
if (partyData[i].ball != ITEM_NONE)
{
ball = partyData[i].ball;
SetMonData(&gPlayerParty[i], MON_DATA_POKEBALL, &ball);
}
if (partyData[i].nickname != NULL)
{
SetMonData(&gPlayerParty[i], MON_DATA_NICKNAME, partyData[i].nickname);
}
CalculateMonStats(&gPlayerParty[i]);
}
}
StringCopy(trainerName, gTrainers[trainerId - TRAINER_CUSTOM_PARTNER].trainerName);

View File

@ -2145,15 +2145,22 @@ enum
ENDTURN_FIELD_COUNT,
};
static bool32 TryEndTerrain(u32 terrainFlag, u32 stringTableId)
static bool32 EndTurnTerrain(u32 terrainFlag, u32 stringTableId)
{
if (gFieldStatuses & terrainFlag
&& (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0))
if (gFieldStatuses & terrainFlag)
{
gFieldStatuses &= ~terrainFlag;
TryToRevertMimicry();
gBattleCommunication[MULTISTRING_CHOOSER] = stringTableId;
BattleScriptExecute(BattleScript_TerrainEnds);
if (!(gFieldStatuses & STATUS_FIELD_TERRAIN_PERMANENT) && --gFieldTimers.terrainTimer == 0)
{
gFieldStatuses &= ~terrainFlag;
TryToRevertMimicry();
if (!(terrainFlag & STATUS_FIELD_GRASSY_TERRAIN))
{
gBattleCommunication[MULTISTRING_CHOOSER] = stringTableId;
BattleScriptExecute(BattleScript_TerrainEnds);
}
}
if (terrainFlag & STATUS_FIELD_GRASSY_TERRAIN)
BattleScriptExecute(BattleScript_GrassyTerrainHeals);
return TRUE;
}
return FALSE;
@ -2538,19 +2545,19 @@ u8 DoFieldEndTurnEffects(void)
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_ELECTRIC_TERRAIN:
effect = TryEndTerrain(STATUS_FIELD_ELECTRIC_TERRAIN, B_MSG_TERRAINENDS_ELECTRIC);
effect = EndTurnTerrain(STATUS_FIELD_ELECTRIC_TERRAIN, B_MSG_TERRAINENDS_ELECTRIC);
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_MISTY_TERRAIN:
effect = TryEndTerrain(STATUS_FIELD_MISTY_TERRAIN, B_MSG_TERRAINENDS_MISTY);
effect = EndTurnTerrain(STATUS_FIELD_MISTY_TERRAIN, B_MSG_TERRAINENDS_MISTY);
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_GRASSY_TERRAIN:
effect = TryEndTerrain(STATUS_FIELD_GRASSY_TERRAIN, B_MSG_TERRAINENDS_GRASS);
effect = EndTurnTerrain(STATUS_FIELD_GRASSY_TERRAIN, B_MSG_TERRAINENDS_GRASS);
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_PSYCHIC_TERRAIN:
effect = TryEndTerrain(STATUS_FIELD_PSYCHIC_TERRAIN, B_MSG_TERRAINENDS_PSYCHIC);
effect = EndTurnTerrain(STATUS_FIELD_PSYCHIC_TERRAIN, B_MSG_TERRAINENDS_PSYCHIC);
gBattleStruct->turnCountersTracker++;
break;
case ENDTURN_WATER_SPORT:
@ -9134,6 +9141,7 @@ static u32 CalcMoveBasePowerAfterModifiers(u16 move, u8 battlerAtk, u8 battlerDe
if (gBattleMons[battlerDef].hp <= (gBattleMons[battlerDef].maxHP / 2))
MulModifier(&modifier, UQ_4_12(2.0));
break;
case EFFECT_BARB_BARRAGE:
case EFFECT_VENOSHOCK:
if (gBattleMons[battlerDef].status1 & STATUS1_PSN_ANY)
MulModifier(&modifier, UQ_4_12(2.0));

View File

@ -3,6 +3,7 @@
#include "battle.h"
#include "data.h"
#include "graphics.h"
#include "constants/abilities.h"
#include "constants/items.h"
#include "constants/moves.h"
#include "constants/trainers.h"

View File

@ -12452,11 +12452,11 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
#else
.power = 60,
#endif
.effect = EFFECT_PLACEHOLDER, // EFFECT_DIRE_CLAW,
.effect = EFFECT_DIRE_CLAW,
.type = TYPE_POISON,
.accuracy = 100,
.pp = 15,
.secondaryEffectChance = 0,
.secondaryEffectChance = 50,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST,
@ -12496,17 +12496,18 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
[MOVE_STONE_AXE] =
{
.effect = EFFECT_PLACEHOLDER, // EFFECT_STONE_AXE,
.effect = EFFECT_HIT_SET_ENTRY_HAZARD,
.power = 65,
.type = TYPE_ROCK,
.accuracy = 90,
.pp = 15,
.secondaryEffectChance = 0,
.target = MOVE_TARGET_USER,
.secondaryEffectChance = 100,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_SLICING_MOVE,
.split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE,
.argument = MOVE_EFFECT_STEALTH_ROCK,
},
[MOVE_SPRINGTIDE_STORM] =
@ -12651,12 +12652,16 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
[MOVE_BARB_BARRAGE] =
{
.effect = EFFECT_PLACEHOLDER, // EFFECT_BARB_BARRAGE,
.effect = EFFECT_BARB_BARRAGE,
.power = 60,
.type = TYPE_POISON,
.accuracy = 100,
.pp = 15,
.secondaryEffectChance = 0,
#if B_UPDATED_MOVE_DATA >= GEN_9
.pp = 10,
#else
.pp = 15,
#endif
.secondaryEffectChance = 50,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.flags = FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST,
@ -12753,17 +12758,18 @@ const struct BattleMove gBattleMoves[MOVES_COUNT_DYNAMAX] =
[MOVE_CEASELESS_EDGE] =
{
.effect = EFFECT_PLACEHOLDER, // EFFECT_CEASELESS_EDGE,
.effect = EFFECT_HIT_SET_ENTRY_HAZARD,
.power = 65,
.type = TYPE_DARK,
.accuracy = 90,
.pp = 15,
.secondaryEffectChance = 0,
.secondaryEffectChance = 100,
.target = MOVE_TARGET_SELECTED,
.priority = 0,
.flags = FLAG_MAKES_CONTACT | FLAG_PROTECT_AFFECTED | FLAG_MIRROR_MOVE_AFFECTED | FLAG_KINGS_ROCK_AFFECTED | FLAG_SHEER_FORCE_BOOST | FLAG_SLICING_MOVE,
.split = SPLIT_PHYSICAL,
.zMoveEffect = Z_EFFECT_NONE,
.argument = MOVE_EFFECT_SPIKES,
},
[MOVE_BLEAKWIND_STORM] =

View File

@ -1931,17 +1931,61 @@ const u32 gItemIconPalette_Ruby[] = INCBIN_U32("graphics/items/icon_palettes/rub
const u32 gItemIconPalette_Sapphire[] = INCBIN_U32("graphics/items/icon_palettes/sapphire.gbapal.lz");
//const u32 gItemIcon_AbilityShield[] = INCBIN_U32("graphics/items/icons/ability_shield.4bpp.lz");
//const u32 gItemIconPalette_AbilityShield[] = INCBIN_U32("graphics/items/icon_palettes/ability_shield.gbapal.lz");
const u32 gItemIcon_AbilityShield[] = INCBIN_U32("graphics/items/icons/ability_shield.4bpp.lz");
const u32 gItemIconPalette_AbilityShield[] = INCBIN_U32("graphics/items/icon_palettes/ability_shield.gbapal.lz");
//const u32 gItemIcon_ClearAmulet[] = INCBIN_U32("graphics/items/icons/clear_amulet.4bpp.lz");
//const u32 gItemIconPalette_ClearAmulet[] = INCBIN_U32("graphics/items/icon_palettes/clear_amulet.gbapal.lz");
//const u32 gItemIcon_PunchingGlove[] = INCBIN_U32("graphics/items/icons/punching_glove.4bpp.lz");
//const u32 gItemIconPalette_PunchingGlove[] = INCBIN_U32("graphics/items/icon_palettes/punching_glove.gbapal.lz");
const u32 gItemIcon_PunchingGlove[] = INCBIN_U32("graphics/items/icons/punching_glove.4bpp.lz");
const u32 gItemIconPalette_PunchingGlove[] = INCBIN_U32("graphics/items/icon_palettes/punching_glove.gbapal.lz");
//const u32 gItemIcon_CovertCloak[] = INCBIN_U32("graphics/items/icons/covert_cloak.4bpp.lz");
//const u32 gItemIconPalette_CovertCloak[] = INCBIN_U32("graphics/items/icon_palettes/covert_cloak.gbapal.lz");
const u32 gItemIcon_CovertCloak[] = INCBIN_U32("graphics/items/icons/covert_cloak.4bpp.lz");
const u32 gItemIconPalette_CovertCloak[] = INCBIN_U32("graphics/items/icon_palettes/covert_cloak.gbapal.lz");
//const u32 gItemIcon_LoadedDice[] = INCBIN_U32("graphics/items/icons/loaded_dice.4bpp.lz");
//const u32 gItemIconPalette_LoadedDice[] = INCBIN_U32("graphics/items/icon_palettes/loaded_dice.gbapal.lz");
const u32 gItemIcon_LoadedDice[] = INCBIN_U32("graphics/items/icons/loaded_dice.4bpp.lz");
const u32 gItemIconPalette_LoadedDice[] = INCBIN_U32("graphics/items/icon_palettes/loaded_dice.gbapal.lz");
const u32 gItemIcon_AuspiciousArmor[] = INCBIN_U32("graphics/items/icons/auspicious_armor.4bpp.lz");
const u32 gItemIconPalette_AuspiciousArmor[] = INCBIN_U32("graphics/items/icon_palettes/auspicious_armor.gbapal.lz");
const u32 gItemIcon_BigBambooShoot[] = INCBIN_U32("graphics/items/icons/big_bamboo_shoot.4bpp.lz");
const u32 gItemIconPalette_BigBambooShoot[] = INCBIN_U32("graphics/items/icon_palettes/big_bamboo_shoot.gbapal.lz");
const u32 gItemIcon_BoosterEnergy[] = INCBIN_U32("graphics/items/icons/booster_energy.4bpp.lz");
const u32 gItemIconPalette_BoosterEnergy[] = INCBIN_U32("graphics/items/icon_palettes/booster_energy.gbapal.lz");
const u32 gItemIcon_GimmighoulCoin[] = INCBIN_U32("graphics/items/icons/gimmighoul_coin.4bpp.lz");
const u32 gItemIconPalette_GimmighoulCoin[] = INCBIN_U32("graphics/items/icon_palettes/gimmighoul_coin.gbapal.lz");
const u32 gItemIcon_LeadersCrest[] = INCBIN_U32("graphics/items/icons/leaders_crest.4bpp.lz");
const u32 gItemIconPalette_LeadersCrest[] = INCBIN_U32("graphics/items/icon_palettes/leaders_crest.gbapal.lz");
const u32 gItemIcon_MaliciousArmor[] = INCBIN_U32("graphics/items/icons/malicious_armor.4bpp.lz");
const u32 gItemIconPalette_MaliciousArmor[] = INCBIN_U32("graphics/items/icon_palettes/malicious_armor.gbapal.lz");
const u32 gItemIcon_MirrorHerb[] = INCBIN_U32("graphics/items/icons/mirror_herb.4bpp.lz");
const u32 gItemIconPalette_MirrorHerb[] = INCBIN_U32("graphics/items/icon_palettes/mirror_herb.gbapal.lz");
const u32 gItemIcon_ScrollOfDarkness[] = INCBIN_U32("graphics/items/icons/scroll_of_darkness.4bpp.lz");
const u32 gItemIconPalette_ScrollOfDarkness[] = INCBIN_U32("graphics/items/icon_palettes/scroll_of_darkness.gbapal.lz");
const u32 gItemIcon_ScrollOfWaters[] = INCBIN_U32("graphics/items/icons/scroll_of_waters.4bpp.lz");
const u32 gItemIconPalette_ScrollOfWaters[] = INCBIN_U32("graphics/items/icon_palettes/scroll_of_waters.gbapal.lz");
const u32 gItemIcon_TeraOrb[] = INCBIN_U32("graphics/items/icons/tera_orb.4bpp.lz");
const u32 gItemIconPalette_TeraOrb[] = INCBIN_U32("graphics/items/icon_palettes/tera_orb.gbapal.lz");
const u32 gItemIcon_TinyBambooShoot[] = INCBIN_U32("graphics/items/icons/tiny_bamboo_shoot.4bpp.lz");
const u32 gItemIconPalette_TinyBambooShoot[] = INCBIN_U32("graphics/items/icon_palettes/tiny_bamboo_shoot.gbapal.lz");
// Tera Shards here
const u32 gItemIcon_AdamantCrystal[] = INCBIN_U32("graphics/items/icons/adamant_crystal.4bpp.lz");
const u32 gItemIconPalette_AdamantCrystal[] = INCBIN_U32("graphics/items/icon_palettes/adamant_crystal.gbapal.lz");
const u32 gItemIcon_GriseousCore[] = INCBIN_U32("graphics/items/icons/griseous_core.4bpp.lz");
const u32 gItemIconPalette_GriseousCore[] = INCBIN_U32("graphics/items/icon_palettes/griseous_core.gbapal.lz");
const u32 gItemIcon_LustrousGlobe[] = INCBIN_U32("graphics/items/icons/lustrous_globe.4bpp.lz");
const u32 gItemIconPalette_LustrousGlobe[] = INCBIN_U32("graphics/items/icon_palettes/lustrous_globe.gbapal.lz");

View File

@ -803,11 +803,43 @@ const u32 *const gItemIconTable[ITEMS_COUNT + 1][2] =
[ITEM_TEA] = {gItemIcon_Tea, gItemIconPalette_Tea},
[ITEM_RUBY] = {gItemIcon_Gem, gItemIconPalette_Ruby},
[ITEM_SAPPHIRE] = {gItemIcon_Gem, gItemIconPalette_Sapphire},
[ITEM_ABILITY_SHIELD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_AbilityShield, gItemIconPalette_AbilityShield},
[ITEM_ABILITY_SHIELD] = {gItemIcon_AbilityShield, gItemIconPalette_AbilityShield},
[ITEM_CLEAR_AMULET] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_ClearAmulet, gItemIconPalette_ClearAmulet},
[ITEM_PUNCHING_GLOVE] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_PunchingGlove, gItemIconPalette_PunchingGlove},
[ITEM_COVERT_CLOAK] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_CovertCloak, gItemIconPalette_CovertCloak},
[ITEM_LOADED_DICE] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_LoadedDice, gItemIconPalette_LoadedDice},
[ITEM_PUNCHING_GLOVE] = {gItemIcon_PunchingGlove, gItemIconPalette_PunchingGlove},
[ITEM_COVERT_CLOAK] = {gItemIcon_CovertCloak, gItemIconPalette_CovertCloak},
[ITEM_LOADED_DICE] = {gItemIcon_LoadedDice, gItemIconPalette_LoadedDice},
[ITEM_AUSPICIOUS_ARMOR] = {gItemIcon_AuspiciousArmor, gItemIconPalette_AuspiciousArmor},
[ITEM_BOOSTER_ENERGY] = {gItemIcon_BoosterEnergy, gItemIconPalette_BoosterEnergy},
[ITEM_BIG_BAMBOO_SHOOT] = {gItemIcon_BigBambooShoot, gItemIconPalette_BigBambooShoot},
[ITEM_GIMMIGHOUL_COIN] = {gItemIcon_GimmighoulCoin, gItemIconPalette_GimmighoulCoin},
[ITEM_LEADERS_CREST] = {gItemIcon_LeadersCrest, gItemIconPalette_LeadersCrest},
[ITEM_MALICIOUS_ARMOR] = {gItemIcon_MaliciousArmor, gItemIconPalette_MaliciousArmor},
[ITEM_MIRROR_HERB] = {gItemIcon_MirrorHerb, gItemIconPalette_MirrorHerb},
[ITEM_SCROLL_OF_DARKNESS] = {gItemIcon_ScrollOfDarkness, gItemIconPalette_ScrollOfDarkness},
[ITEM_SCROLL_OF_WATERS] = {gItemIcon_ScrollOfWaters, gItemIconPalette_ScrollOfWaters},
[ITEM_TERA_ORB] = {gItemIcon_TeraOrb, gItemIconPalette_TeraOrb},
[ITEM_TINY_BAMBOO_SHOOT] = {gItemIcon_TinyBambooShoot, gItemIconPalette_TinyBambooShoot},
[ITEM_BUG_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_BugTeraShard, gItemIconPalette_BugTeraShard},
[ITEM_DARK_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_DarkTeraShard, gItemIconPalette_DarkTeraShard},
[ITEM_DRAGON_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_DragonTeraShard, gItemIconPalette_DragonTeraShard},
[ITEM_ELECTRIC_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_ElectricTeraShard, gItemIconPalette_ElectricTeraShard},
[ITEM_FAIRY_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_FairyTeraShard, gItemIconPalette_FairyTeraShard},
[ITEM_FIGHTING_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_FightingTeraShard, gItemIconPalette_FightingTeraShard},
[ITEM_FIRE_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_FireTeraShard, gItemIconPalette_FireTeraShard},
[ITEM_FLYING_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_FlyingTeraShard, gItemIconPalette_FlyingTeraShard},
[ITEM_GHOST_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_GhostTeraShard, gItemIconPalette_GhostTeraShard},
[ITEM_GRASS_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_GrassTeraShard, gItemIconPalette_GrassTeraShard},
[ITEM_GROUND_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_GroundTeraShard, gItemIconPalette_GroundTeraShard},
[ITEM_ICE_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_IceTeraShard, gItemIconPalette_IceTeraShard},
[ITEM_NORMAL_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_NormalTeraShard, gItemIconPalette_NormalTeraShard},
[ITEM_POISON_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_PoisonTeraShard, gItemIconPalette_PoisonTeraShard},
[ITEM_PSYCHIC_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_PsychicTeraShard, gItemIconPalette_PsychicTeraShard},
[ITEM_ROCK_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_RockTeraShard, gItemIconPalette_RockTeraShard},
[ITEM_STEEL_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_SteelTeraShard, gItemIconPalette_SteelTeraShard},
[ITEM_WATER_TERA_SHARD] = {gItemIcon_QuestionMark, gItemIconPalette_QuestionMark}, // {gItemIcon_WaterTeraShard, gItemIconPalette_WaterTeraShard},
[ITEM_ADAMANT_CRYSTAL] = {gItemIcon_AdamantCrystal, gItemIconPalette_AdamantCrystal},
[ITEM_GRISEOUS_CORE] = {gItemIcon_GriseousCore, gItemIconPalette_GriseousCore},
[ITEM_LUSTROUS_GLOBE] = {gItemIcon_LustrousGlobe, gItemIconPalette_LustrousGlobe},
// Return to field arrow
[ITEMS_COUNT] = {gItemIcon_ReturnToFieldArrow, gItemIconPalette_ReturnToFieldArrow},
};

View File

@ -9896,7 +9896,6 @@ const struct Item gItems[] =
[ITEM_LOADED_DICE] =
{
//YellwApricorn
.name = _("Loaded Dice"),
.itemId = ITEM_LOADED_DICE,
.price = 20000,
@ -9907,4 +9906,370 @@ const struct Item gItems[] =
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.flingPower = 30,
},
[ITEM_AUSPICIOUS_ARMOR] =
{
.name = _("AuspciousArmr"),
.itemId = ITEM_AUSPICIOUS_ARMOR,
.price = 3000,
.description = sAuspiciousArmorDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_EvolutionStone,
.flingPower = 30,
},
[ITEM_BOOSTER_ENERGY] =
{
.name = _("BoosterEnergy"),
.itemId = ITEM_BOOSTER_ENERGY,
.price = 0,
.holdEffect = HOLD_EFFECT_BOOSTER_ENERGY,
.description = sBoosterEnergyDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.flingPower = 30,
},
[ITEM_BIG_BAMBOO_SHOOT] =
{
.name = _("BigBmbooShoot"),
.itemId = ITEM_BIG_BAMBOO_SHOOT,
.price = 3000,
.description = sBigBambooShootDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.flingPower = 30,
},
[ITEM_GIMMIGHOUL_COIN] =
{
.name = _("GimighoulCoin"),
.itemId = ITEM_GIMMIGHOUL_COIN,
.price = 400,
.description = sGimmighoulCoinDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_LEADERS_CREST] =
{
.name = _("Leader'sCrest"),
.itemId = ITEM_LEADERS_CREST,
.price = 3000,
.description = sLeadersCrestDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_MALICIOUS_ARMOR] =
{
.name = _("MaliciousArmr"),
.itemId = ITEM_MALICIOUS_ARMOR,
.price = 3000,
.description = sMaliciousArmorDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_EvolutionStone,
.flingPower = 30,
},
[ITEM_MIRROR_HERB] =
{
.name = _("Mirror Herb"),
.itemId = ITEM_MIRROR_HERB,
.price = 30000,
.holdEffect = HOLD_EFFECT_MIRROR_HERB,
.description = sMirrorHerbDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.flingPower = 30,
},
[ITEM_SCROLL_OF_DARKNESS] =
{
.name = _("ScrllOfDrknss"),
.itemId = ITEM_SCROLL_OF_DARKNESS,
.price = 0,
.description = sScrollOfDarknessDesc,
.importance = 1,
.pocket = POCKET_KEY_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_EvolutionStone,
},
[ITEM_SCROLL_OF_WATERS] =
{
.name = _("ScrollOfWatrs"),
.itemId = ITEM_SCROLL_OF_WATERS,
.price = 0,
.description = sScrollOfWatersDesc,
.importance = 1,
.pocket = POCKET_KEY_ITEMS,
.type = ITEM_USE_PARTY_MENU,
.fieldUseFunc = ItemUseOutOfBattle_EvolutionStone,
},
[ITEM_TERA_ORB] =
{
.name = _("Tera Orb"),
.itemId = ITEM_TERA_ORB,
.price = 0,
.description = sTeraOrbDesc,
.importance = 1,
.pocket = POCKET_KEY_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_TINY_BAMBOO_SHOOT] =
{
.name = _("TinyBmbooShot"),
.itemId = ITEM_TINY_BAMBOO_SHOOT,
.price = 750,
.description = sTinyBambooShootDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.flingPower = 30,
},
[ITEM_BUG_TERA_SHARD] =
{
.name = _("Bug TeraShard"),
.itemId = ITEM_BUG_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_DARK_TERA_SHARD] =
{
.name = _("DarkTeraShard"),
.itemId = ITEM_DARK_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_DRAGON_TERA_SHARD] =
{
.name = _("DragnTeraShrd"),
.itemId = ITEM_DRAGON_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_ELECTRIC_TERA_SHARD] =
{
.name = _("EltrcTeraShrd"),
.itemId = ITEM_ELECTRIC_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_FAIRY_TERA_SHARD] =
{
.name = _("FairyTeraShrd"),
.itemId = ITEM_FAIRY_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_FIGHTING_TERA_SHARD] =
{
.name = _("FghtngTerShrd"),
.itemId = ITEM_FIGHTING_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_FIRE_TERA_SHARD] =
{
.name = _("FireTeraShard"),
.itemId = ITEM_FIRE_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_FLYING_TERA_SHARD] =
{
.name = _("FlyngTeraShrd"),
.itemId = ITEM_FLYING_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_GHOST_TERA_SHARD] =
{
.name = _("GhostTeraShrd"),
.itemId = ITEM_GHOST_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_GRASS_TERA_SHARD] =
{
.name = _("GrassTeraShrd"),
.itemId = ITEM_GRASS_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_GROUND_TERA_SHARD] =
{
.name = _("GrondTeraShrd"),
.itemId = ITEM_GROUND_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_ICE_TERA_SHARD] =
{
.name = _("Ice TeraShard"),
.itemId = ITEM_ICE_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_NORMAL_TERA_SHARD] =
{
.name = _("NormlTeraShrd"),
.itemId = ITEM_NORMAL_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_POISON_TERA_SHARD] =
{
.name = _("PoisnTeraShrd"),
.itemId = ITEM_POISON_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_PSYCHIC_TERA_SHARD] =
{
.name = _("PschcTeraShrd"),
.itemId = ITEM_PSYCHIC_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_ROCK_TERA_SHARD] =
{
.name = _("RockTeraShard"),
.itemId = ITEM_ROCK_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_STEEL_TERA_SHARD] =
{
.name = _("SteelTeraShrd"),
.itemId = ITEM_STEEL_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_WATER_TERA_SHARD] =
{
.name = _("WaterTeraShrd"),
.itemId = ITEM_WATER_TERA_SHARD,
.price = 0,
.description = sTeraShardDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
},
[ITEM_ADAMANT_CRYSTAL] =
{
.name = _("AdamantCrystl"),
.itemId = ITEM_ADAMANT_CRYSTAL,
.price = 0,
.description = sAdamantCrystalDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.flingPower = 60,
},
[ITEM_GRISEOUS_CORE] =
{
.name = _("Griseous Core"),
.itemId = ITEM_GRISEOUS_CORE,
.price = 0,
.description = sGriseousCoreDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.flingPower = 60,
},
[ITEM_LUSTROUS_GLOBE] =
{
.name = _("LustrousGlobe"),
.itemId = ITEM_LUSTROUS_GLOBE,
.price = 0,
.description = sLustrousGlobeDesc,
.pocket = POCKET_ITEMS,
.type = ITEM_USE_BAG_MENU,
.fieldUseFunc = ItemUseOutOfBattle_CannotUse,
.flingPower = 60,
},
};

View File

@ -491,7 +491,9 @@ const struct Evolution gEvolutionTable[NUM_SPECIES][EVOS_PER_MON] =
[SPECIES_DREEPY] = {{EVO_LEVEL, 50, SPECIES_DRAKLOAK}},
[SPECIES_DRAKLOAK] = {{EVO_LEVEL, 60, SPECIES_DRAGAPULT}},
[SPECIES_KUBFU] = {{EVO_DARK_SCROLL, 0, SPECIES_URSHIFU},
{EVO_WATER_SCROLL, 0, SPECIES_URSHIFU_RAPID_STRIKE_STYLE}},
{EVO_ITEM, ITEM_SCROLL_OF_DARKNESS, SPECIES_URSHIFU},
{EVO_WATER_SCROLL, 0, SPECIES_URSHIFU_RAPID_STRIKE_STYLE},
{EVO_ITEM, ITEM_SCROLL_OF_WATERS, SPECIES_URSHIFU_RAPID_STRIKE_STYLE}},
#endif
[SPECIES_RATTATA_ALOLAN] = {{EVO_LEVEL_NIGHT, 20, SPECIES_RATICATE_ALOLAN}},
[SPECIES_SANDSHREW_ALOLAN] = {{EVO_ITEM, ITEM_ICE_STONE, SPECIES_SANDSLASH_ALOLAN}},

View File

@ -118,6 +118,10 @@ const struct FormChange *const gFormChangeTablePointers[NUM_SPECIES] =
[SPECIES_ABOMASNOW_MEGA] = sAbomasnowFormChangeTable,
[SPECIES_GALLADE] = sGalladeFormChangeTable,
[SPECIES_GALLADE_MEGA] = sGalladeFormChangeTable,
[SPECIES_DIALGA] = sDialgaFormChangeTable,
[SPECIES_DIALGA_ORIGIN] = sDialgaFormChangeTable,
[SPECIES_PALKIA] = sPalkiaFormChangeTable,
[SPECIES_PALKIA_ORIGIN] = sPalkiaFormChangeTable,
[SPECIES_GIRATINA] = sGiratinaFormChangeTable,
[SPECIES_GIRATINA_ORIGIN] = sGiratinaFormChangeTable,
[SPECIES_SHAYMIN] = sShayminFormChangeTable,

View File

@ -247,6 +247,19 @@ static const struct FormChange sGalladeFormChangeTable[] = {
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sDialgaFormChangeTable[] = {
{FORM_CHANGE_ITEM_HOLD, SPECIES_DIALGA, ITEM_NONE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_DIALGA_ORIGIN, ITEM_ADAMANT_CRYSTAL},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sPalkiaFormChangeTable[] = {
{FORM_CHANGE_ITEM_HOLD, SPECIES_PALKIA, ITEM_NONE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_PALKIA_ORIGIN, ITEM_LUSTROUS_GLOBE},
{FORM_CHANGE_TERMINATOR},
};
static const struct FormChange sGiratinaFormChangeTable[] = {
{FORM_CHANGE_ITEM_HOLD, SPECIES_GIRATINA, ITEM_NONE},
{FORM_CHANGE_ITEM_HOLD, SPECIES_GIRATINA_ORIGIN, ITEM_GRISEOUS_ORB},

View File

@ -450,125 +450,129 @@ const u8 gItemEffect_TamatoBerry[10] = {
const u8 *const gItemEffectTable[ITEMS_COUNT] =
{
// Medicine
[ITEM_POTION] = gItemEffect_Potion,
[ITEM_SUPER_POTION] = gItemEffect_SuperPotion,
[ITEM_HYPER_POTION] = gItemEffect_HyperPotion,
[ITEM_MAX_POTION] = gItemEffect_MaxPotion,
[ITEM_FULL_RESTORE] = gItemEffect_FullRestore,
[ITEM_REVIVE] = gItemEffect_Revive,
[ITEM_MAX_REVIVE] = gItemEffect_MaxRevive,
[ITEM_FRESH_WATER] = gItemEffect_FreshWater,
[ITEM_SODA_POP] = gItemEffect_SodaPop,
[ITEM_LEMONADE] = gItemEffect_Lemonade,
[ITEM_MOOMOO_MILK] = gItemEffect_MoomooMilk,
[ITEM_ENERGY_POWDER] = gItemEffect_EnergyPowder,
[ITEM_ENERGY_ROOT] = gItemEffect_EnergyRoot,
[ITEM_HEAL_POWDER] = gItemEffect_HealPowder,
[ITEM_REVIVAL_HERB] = gItemEffect_RevivalHerb,
[ITEM_ANTIDOTE] = gItemEffect_Antidote,
[ITEM_PARALYZE_HEAL] = gItemEffect_ParalyzeHeal,
[ITEM_BURN_HEAL] = gItemEffect_BurnHeal,
[ITEM_ICE_HEAL] = gItemEffect_IceHeal,
[ITEM_AWAKENING] = gItemEffect_Awakening,
[ITEM_FULL_HEAL] = gItemEffect_FullHeal,
[ITEM_ETHER] = gItemEffect_Ether,
[ITEM_MAX_ETHER] = gItemEffect_MaxEther,
[ITEM_ELIXIR] = gItemEffect_Elixir,
[ITEM_MAX_ELIXIR] = gItemEffect_MaxElixir,
[ITEM_BERRY_JUICE] = gItemEffect_BerryJuice,
[ITEM_SACRED_ASH] = gItemEffect_SacredAsh,
[ITEM_SWEET_HEART] = gItemEffect_Potion,
[ITEM_MAX_HONEY] = gItemEffect_MaxRevive,
[ITEM_POTION] = gItemEffect_Potion,
[ITEM_SUPER_POTION] = gItemEffect_SuperPotion,
[ITEM_HYPER_POTION] = gItemEffect_HyperPotion,
[ITEM_MAX_POTION] = gItemEffect_MaxPotion,
[ITEM_FULL_RESTORE] = gItemEffect_FullRestore,
[ITEM_REVIVE] = gItemEffect_Revive,
[ITEM_MAX_REVIVE] = gItemEffect_MaxRevive,
[ITEM_FRESH_WATER] = gItemEffect_FreshWater,
[ITEM_SODA_POP] = gItemEffect_SodaPop,
[ITEM_LEMONADE] = gItemEffect_Lemonade,
[ITEM_MOOMOO_MILK] = gItemEffect_MoomooMilk,
[ITEM_ENERGY_POWDER] = gItemEffect_EnergyPowder,
[ITEM_ENERGY_ROOT] = gItemEffect_EnergyRoot,
[ITEM_HEAL_POWDER] = gItemEffect_HealPowder,
[ITEM_REVIVAL_HERB] = gItemEffect_RevivalHerb,
[ITEM_ANTIDOTE] = gItemEffect_Antidote,
[ITEM_PARALYZE_HEAL] = gItemEffect_ParalyzeHeal,
[ITEM_BURN_HEAL] = gItemEffect_BurnHeal,
[ITEM_ICE_HEAL] = gItemEffect_IceHeal,
[ITEM_AWAKENING] = gItemEffect_Awakening,
[ITEM_FULL_HEAL] = gItemEffect_FullHeal,
[ITEM_ETHER] = gItemEffect_Ether,
[ITEM_MAX_ETHER] = gItemEffect_MaxEther,
[ITEM_ELIXIR] = gItemEffect_Elixir,
[ITEM_MAX_ELIXIR] = gItemEffect_MaxElixir,
[ITEM_BERRY_JUICE] = gItemEffect_BerryJuice,
[ITEM_SACRED_ASH] = gItemEffect_SacredAsh,
[ITEM_SWEET_HEART] = gItemEffect_Potion,
[ITEM_MAX_HONEY] = gItemEffect_MaxRevive,
// Regional Specialties
[ITEM_PEWTER_CRUNCHIES] = gItemEffect_FullHeal,
[ITEM_RAGE_CANDY_BAR] = gItemEffect_FullHeal,
[ITEM_LAVA_COOKIE] = gItemEffect_FullHeal,
[ITEM_OLD_GATEAU] = gItemEffect_FullHeal,
[ITEM_CASTELIACONE] = gItemEffect_FullHeal,
[ITEM_LUMIOSE_GALETTE] = gItemEffect_FullHeal,
[ITEM_SHALOUR_SABLE] = gItemEffect_FullHeal,
[ITEM_BIG_MALASADA] = gItemEffect_FullHeal,
[ITEM_PEWTER_CRUNCHIES] = gItemEffect_FullHeal,
[ITEM_RAGE_CANDY_BAR] = gItemEffect_FullHeal,
[ITEM_LAVA_COOKIE] = gItemEffect_FullHeal,
[ITEM_OLD_GATEAU] = gItemEffect_FullHeal,
[ITEM_CASTELIACONE] = gItemEffect_FullHeal,
[ITEM_LUMIOSE_GALETTE] = gItemEffect_FullHeal,
[ITEM_SHALOUR_SABLE] = gItemEffect_FullHeal,
[ITEM_BIG_MALASADA] = gItemEffect_FullHeal,
// Vitamins
[ITEM_HP_UP] = gItemEffect_HPUp,
[ITEM_PROTEIN] = gItemEffect_Protein,
[ITEM_IRON] = gItemEffect_Iron,
[ITEM_CALCIUM] = gItemEffect_Calcium,
[ITEM_ZINC] = gItemEffect_Zinc,
[ITEM_CARBOS] = gItemEffect_Carbos,
[ITEM_PP_UP] = gItemEffect_PPUp,
[ITEM_PP_MAX] = gItemEffect_PPMax,
[ITEM_HP_UP] = gItemEffect_HPUp,
[ITEM_PROTEIN] = gItemEffect_Protein,
[ITEM_IRON] = gItemEffect_Iron,
[ITEM_CALCIUM] = gItemEffect_Calcium,
[ITEM_ZINC] = gItemEffect_Zinc,
[ITEM_CARBOS] = gItemEffect_Carbos,
[ITEM_PP_UP] = gItemEffect_PPUp,
[ITEM_PP_MAX] = gItemEffect_PPMax,
// EV Feathers
[ITEM_HEALTH_FEATHER] = gItemEffect_HpFeather,
[ITEM_MUSCLE_FEATHER] = gItemEffect_AtkFeather,
[ITEM_RESIST_FEATHER] = gItemEffect_DefFeather,
[ITEM_GENIUS_FEATHER] = gItemEffect_SpatkFeather,
[ITEM_CLEVER_FEATHER] = gItemEffect_SpdefFeather,
[ITEM_SWIFT_FEATHER] = gItemEffect_SpeedFeather,
[ITEM_HEALTH_FEATHER] = gItemEffect_HpFeather,
[ITEM_MUSCLE_FEATHER] = gItemEffect_AtkFeather,
[ITEM_RESIST_FEATHER] = gItemEffect_DefFeather,
[ITEM_GENIUS_FEATHER] = gItemEffect_SpatkFeather,
[ITEM_CLEVER_FEATHER] = gItemEffect_SpdefFeather,
[ITEM_SWIFT_FEATHER] = gItemEffect_SpeedFeather,
// Candy
[ITEM_RARE_CANDY] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_XS] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_S] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_M] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_L] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_XL] = gItemEffect_RareCandy,
//[ITEM_DYNAMAX_CANDY] = gItemEffect_DynamaxCandy, // Todo
[ITEM_RARE_CANDY] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_XS] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_S] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_M] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_L] = gItemEffect_RareCandy,
[ITEM_EXP_CANDY_XL] = gItemEffect_RareCandy,
//[ITEM_DYNAMAX_CANDY] = gItemEffect_DynamaxCandy, // Todo
// Medicinal Flutes
[ITEM_BLUE_FLUTE] = gItemEffect_BlueFlute,
[ITEM_YELLOW_FLUTE] = gItemEffect_YellowFlute,
[ITEM_RED_FLUTE] = gItemEffect_RedFlute,
[ITEM_BLUE_FLUTE] = gItemEffect_BlueFlute,
[ITEM_YELLOW_FLUTE] = gItemEffect_YellowFlute,
[ITEM_RED_FLUTE] = gItemEffect_RedFlute,
// X Items
[ITEM_X_ATTACK] = gItemEffect_XAttack,
[ITEM_X_DEFENSE] = gItemEffect_XDefense,
[ITEM_X_SPEED] = gItemEffect_XSpeed,
[ITEM_X_ACCURACY] = gItemEffect_XAccuracy,
[ITEM_X_SP_ATK] = gItemEffect_XSpecialAttack,
[ITEM_X_SP_DEF] = gItemEffect_XSpecialDefense,
[ITEM_X_ATTACK] = gItemEffect_XAttack,
[ITEM_X_DEFENSE] = gItemEffect_XDefense,
[ITEM_X_SPEED] = gItemEffect_XSpeed,
[ITEM_X_ACCURACY] = gItemEffect_XAccuracy,
[ITEM_X_SP_ATK] = gItemEffect_XSpecialAttack,
[ITEM_X_SP_DEF] = gItemEffect_XSpecialDefense,
[ITEM_DIRE_HIT] = gItemEffect_DireHit,
[ITEM_GUARD_SPEC] = gItemEffect_GuardSpec,
[ITEM_DIRE_HIT] = gItemEffect_DireHit,
[ITEM_GUARD_SPEC] = gItemEffect_GuardSpec,
//[ITEM_MAX_MUSHROOMS] = gItemEffect_MaxMushrooms, // Todo
//[ITEM_MAX_MUSHROOMS] = gItemEffect_MaxMushrooms, // Todo
// Evolution Items
[ITEM_FIRE_STONE] = gItemEffect_EvoItem,
[ITEM_WATER_STONE] = gItemEffect_EvoItem,
[ITEM_THUNDER_STONE] = gItemEffect_EvoItem,
[ITEM_LEAF_STONE] = gItemEffect_EvoItem,
[ITEM_ICE_STONE] = gItemEffect_EvoItem,
[ITEM_SUN_STONE] = gItemEffect_EvoItem,
[ITEM_MOON_STONE] = gItemEffect_EvoItem,
[ITEM_SHINY_STONE] = gItemEffect_EvoItem,
[ITEM_DUSK_STONE] = gItemEffect_EvoItem,
[ITEM_DAWN_STONE] = gItemEffect_EvoItem,
[ITEM_SWEET_APPLE] = gItemEffect_EvoItem,
[ITEM_TART_APPLE] = gItemEffect_EvoItem,
[ITEM_CRACKED_POT] = gItemEffect_EvoItem,
[ITEM_CHIPPED_POT] = gItemEffect_EvoItem,
[ITEM_GALARICA_CUFF] = gItemEffect_EvoItem,
[ITEM_GALARICA_WREATH] = gItemEffect_EvoItem,
[ITEM_FIRE_STONE] = gItemEffect_EvoItem,
[ITEM_WATER_STONE] = gItemEffect_EvoItem,
[ITEM_THUNDER_STONE] = gItemEffect_EvoItem,
[ITEM_LEAF_STONE] = gItemEffect_EvoItem,
[ITEM_ICE_STONE] = gItemEffect_EvoItem,
[ITEM_SUN_STONE] = gItemEffect_EvoItem,
[ITEM_MOON_STONE] = gItemEffect_EvoItem,
[ITEM_SHINY_STONE] = gItemEffect_EvoItem,
[ITEM_DUSK_STONE] = gItemEffect_EvoItem,
[ITEM_DAWN_STONE] = gItemEffect_EvoItem,
[ITEM_SWEET_APPLE] = gItemEffect_EvoItem,
[ITEM_TART_APPLE] = gItemEffect_EvoItem,
[ITEM_CRACKED_POT] = gItemEffect_EvoItem,
[ITEM_CHIPPED_POT] = gItemEffect_EvoItem,
[ITEM_GALARICA_CUFF] = gItemEffect_EvoItem,
[ITEM_GALARICA_WREATH] = gItemEffect_EvoItem,
[ITEM_AUSPICIOUS_ARMOR] = gItemEffect_EvoItem,
[ITEM_MALICIOUS_ARMOR] = gItemEffect_EvoItem,
[ITEM_SCROLL_OF_DARKNESS] = gItemEffect_EvoItem,
[ITEM_SCROLL_OF_WATERS] = gItemEffect_EvoItem,
// Berries
[ITEM_CHERI_BERRY] = gItemEffect_CheriBerry,
[ITEM_CHESTO_BERRY] = gItemEffect_ChestoBerry,
[ITEM_PECHA_BERRY] = gItemEffect_PechaBerry,
[ITEM_RAWST_BERRY] = gItemEffect_RawstBerry,
[ITEM_ASPEAR_BERRY] = gItemEffect_AspearBerry,
[ITEM_LEPPA_BERRY] = gItemEffect_LeppaBerry,
[ITEM_ORAN_BERRY] = gItemEffect_OranBerry,
[ITEM_PERSIM_BERRY] = gItemEffect_PersimBerry,
[ITEM_LUM_BERRY] = gItemEffect_FullHeal,
[ITEM_SITRUS_BERRY] = gItemEffect_SitrusBerry,
[ITEM_POMEG_BERRY] = gItemEffect_PomegBerry,
[ITEM_KELPSY_BERRY] = gItemEffect_KelpsyBerry,
[ITEM_QUALOT_BERRY] = gItemEffect_QualotBerry,
[ITEM_HONDEW_BERRY] = gItemEffect_HondewBerry,
[ITEM_GREPA_BERRY] = gItemEffect_GrepaBerry,
[ITEM_TAMATO_BERRY] = gItemEffect_TamatoBerry,
[LAST_BERRY_INDEX] = NULL,
[ITEM_CHERI_BERRY] = gItemEffect_CheriBerry,
[ITEM_CHESTO_BERRY] = gItemEffect_ChestoBerry,
[ITEM_PECHA_BERRY] = gItemEffect_PechaBerry,
[ITEM_RAWST_BERRY] = gItemEffect_RawstBerry,
[ITEM_ASPEAR_BERRY] = gItemEffect_AspearBerry,
[ITEM_LEPPA_BERRY] = gItemEffect_LeppaBerry,
[ITEM_ORAN_BERRY] = gItemEffect_OranBerry,
[ITEM_PERSIM_BERRY] = gItemEffect_PersimBerry,
[ITEM_LUM_BERRY] = gItemEffect_FullHeal,
[ITEM_SITRUS_BERRY] = gItemEffect_SitrusBerry,
[ITEM_POMEG_BERRY] = gItemEffect_PomegBerry,
[ITEM_KELPSY_BERRY] = gItemEffect_KelpsyBerry,
[ITEM_QUALOT_BERRY] = gItemEffect_QualotBerry,
[ITEM_HONDEW_BERRY] = gItemEffect_HondewBerry,
[ITEM_GREPA_BERRY] = gItemEffect_GrepaBerry,
[ITEM_TAMATO_BERRY] = gItemEffect_TamatoBerry,
[LAST_BERRY_INDEX] = NULL,
};

View File

@ -3817,3 +3817,78 @@ static const u8 sLoadedDiceDesc[] = _(
"Rolls high numbers.\n"
"Multihit strikes\n"
"hit more times.");
static const u8 sAuspiciousArmorDesc[] = _(
"Armor inhabited by\n"
"auspicious wishes.\n"
"Causes evolution.");
static const u8 sBoosterEnergyDesc[] = _(
"Encapsuled energy\n"
"ups Pokémon with\n"
"certain Abilities.");
static const u8 sBigBambooShootDesc[] = _(
"A large and rare\n"
"bamboo shoot. Best\n"
"sold to gourmands.");
static const u8 sGimmighoulCoinDesc[] = _(
"Gimmighoul hoard\n"
"and treasure these\n"
"curious coins.");
static const u8 sLeadersCrestDesc[] = _(
"A shard of an old\n"
"blade of some sort.\n"
"Held by Bisharp.");
static const u8 sMaliciousArmorDesc[] = _(
"Armor inhabited by\n"
"malicious will.\n"
"Causes evolution.");
static const u8 sMirrorHerbDesc[] = _(
"Mirrors an enemy's\n"
"stat increases\n"
"but only once.");
static const u8 sScrollOfDarknessDesc[] = _(
"A peculiar scroll\n"
"with secrets of\n"
"the dark path.");
static const u8 sScrollOfWatersDesc[] = _(
"A peculiar scroll\n"
"with secrets of\n"
"the water path.");
static const u8 sTeraOrbDesc[] = _(
"Energy charges can\n"
"be used to cause\n"
"Terastallization.");
static const u8 sTinyBambooShootDesc[] = _(
"A small and rare\n"
"bamboo shoot. Best\n"
"sold to gourmands.");
static const u8 sTeraShardDesc[] = _(
"These shards may\n"
"form when a Tera\n"
"Pokémon faints.");
static const u8 sAdamantCrystalDesc[] = _(
"A large, glowing gem\n"
"that lets Dialga\n"
"change form.");
static const u8 sGriseousCoreDesc[] = _(
"A large, glowing gem\n"
"that lets Giratina\n"
"change form.");
static const u8 sLustrousGlobeDesc[] = _(
"A large, glowing gem\n"
"that lets Palkia\n"
"change form.");

View File

@ -1812,6 +1812,9 @@ static void PopulateSpeciesFromTrainerParty(int matchCallId, u8 *destStr)
case F_TRAINER_PARTY_CUSTOM_MOVESET | F_TRAINER_PARTY_HELD_ITEM:
speciesName = gSpeciesNames[party.ItemCustomMoves[monId].species];
break;
case F_TRAINER_PARTY_EVERYTHING_CUSTOMIZED:
speciesName = gSpeciesNames[party.EverythingCustomized[monId].species];
break;
}
StringCopy(destStr, speciesName);

View File

@ -5517,7 +5517,8 @@ void ItemUseCB_EvolutionStone(u8 taskId, TaskFunc task)
}
else
{
RemoveBagItem(gSpecialVar_ItemId, 1);
if (ItemId_GetPocket(gSpecialVar_ItemId) != POCKET_KEY_ITEMS)
RemoveBagItem(gSpecialVar_ItemId, 1);
FreePartyPointers();
}
}

View File

@ -122,3 +122,40 @@ SINGLE_BATTLE_TEST("Intimidate and Eject Button force the opponent to Attack")
}
}
}
DOUBLE_BATTLE_TEST("Intimidate activates on an empty slot")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_CROAGUNK);
PLAYER(SPECIES_WYNAUT);
PLAYER(SPECIES_HITMONTOP) { Ability(ABILITY_INTIMIDATE); };
OPPONENT(SPECIES_RALTS);
OPPONENT(SPECIES_AZURILL);
} WHEN {
TURN {
SWITCH(playerLeft, 2);
MOVE(playerRight, MOVE_GUNK_SHOT, target: opponentLeft);
MOVE(opponentRight, MOVE_SPLASH);
}
TURN {
SWITCH(playerLeft, 3);
MOVE(playerRight, MOVE_SPLASH);
}
} SCENE {
MESSAGE("Wobbuffet, that's enough! Come back!");
MESSAGE("Go! Wynaut!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_GUNK_SHOT, playerRight);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPLASH, opponentRight);
MESSAGE("Wynaut, that's enough! Come back!");
MESSAGE("Go! Hitmontop!");
ABILITY_POPUP(playerLeft, ABILITY_INTIMIDATE);
NONE_OF {
MESSAGE("Hitmontop's Intimidate cuts Foe Ralts's attack!");
}
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
MESSAGE("Hitmontop's Intimidate cuts Foe Azurill's attack!");
}
}

View File

@ -0,0 +1,43 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
//ASSUME(gBattleMoves[MOVE_BARB_BARRAGE].effect == EFFECT_BARB_BARRAGE);
}
SINGLE_BATTLE_TEST("Barb Barrage inflicts poison")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_BARB_BARRAGE); }
TURN {}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_BARB_BARRAGE, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_STATUS, B_ANIM_STATUS_PSN, opponent);
STATUS_ICON(opponent, poison: TRUE);
}
}
SINGLE_BATTLE_TEST("Barb Barrage's power doubles if the target is poisoned/badly poisoned", s16 damage)
{
u32 status1;
PARAMETRIZE { status1 = 0; }
PARAMETRIZE { status1 = STATUS1_POISON; }
PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) {Status1(status1);}
} WHEN {
TURN { MOVE(player, MOVE_BARB_BARRAGE); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_BARB_BARRAGE, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[2].damage);
}
}

View File

@ -0,0 +1,139 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_DIRE_CLAW].effect == EFFECT_DIRE_CLAW);
}
// found by brute-force
#define RNG_SLEEP 0xcb0
#define RNG_POISON 0x2BE
#define RNG_PARALYSIS 5
SINGLE_BATTLE_TEST("Dire Claw can inflict poison, paralysis or sleep")
{
u8 statusAnim;
u32 rng;
KNOWN_FAILING;
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PSN; rng = RNG_POISON; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_SLP; rng = RNG_SLEEP; }
GIVEN {
RNGSeed(rng);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_DIRE_CLAW); }
TURN {}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DIRE_CLAW, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_STATUS, statusAnim, opponent);
if (statusAnim == B_ANIM_STATUS_PRZ) {
STATUS_ICON(opponent, paralysis: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_SLP) {
STATUS_ICON(opponent, sleep: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_PSN) {
STATUS_ICON(opponent, poison: TRUE);
}
}
}
SINGLE_BATTLE_TEST("Dire Claw cannot poison/paralyze poison/electric types respectively")
{
u8 statusAnim;
u16 species;
u32 rng;
#if B_PARALYZE_ELECTRIC >= GEN_6
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; species = SPECIES_RAICHU; }
#endif // B_PARALYZE_ELECTRIC
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PSN; rng = RNG_POISON; species = SPECIES_ARBOK;}
GIVEN {
RNGSeed(rng);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species);
} WHEN {
TURN { MOVE(player, MOVE_DIRE_CLAW); }
TURN {}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DIRE_CLAW, player);
HP_BAR(opponent);
NOT ANIMATION(ANIM_TYPE_STATUS, statusAnim, opponent);
if (statusAnim == B_ANIM_STATUS_PRZ) {
NOT STATUS_ICON(opponent, paralysis: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_PSN) {
NOT STATUS_ICON(opponent, poison: TRUE);
}
}
}
SINGLE_BATTLE_TEST("Dire Claw cannot poison/paralyze/cause to fall asleep pokemon with abilities preventing respective statuses")
{
u8 statusAnim;
u16 species, ability;
u32 rng;
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; species = SPECIES_RAICHU; ability = ABILITY_LIGHTNING_ROD; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; species = SPECIES_JOLTEON; ability = ABILITY_VOLT_ABSORB; }
#if P_GEN_4_POKEMON == TRUE
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; species = SPECIES_ELECTIVIRE; ability = ABILITY_MOTOR_DRIVE; }
#endif // P_GEN_4_POKEMON
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PSN; rng = RNG_POISON; species = SPECIES_ZANGOOSE; ability = ABILITY_IMMUNITY; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_SLP; rng = RNG_SLEEP; species = SPECIES_VIGOROTH; ability = ABILITY_VITAL_SPIRIT; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_SLP; rng = RNG_SLEEP; species = SPECIES_HYPNO; ability = ABILITY_INSOMNIA; }
GIVEN {
RNGSeed(rng);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) {Ability(ability);}
} WHEN {
TURN { MOVE(player, MOVE_DIRE_CLAW); }
TURN {}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DIRE_CLAW, player);
HP_BAR(opponent);
NOT ANIMATION(ANIM_TYPE_STATUS, statusAnim, opponent);
if (statusAnim == B_ANIM_STATUS_PRZ) {
NOT STATUS_ICON(opponent, paralysis: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_SLP) {
NOT STATUS_ICON(opponent, sleep: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_PSN) {
NOT STATUS_ICON(opponent, poison: TRUE);
}
}
}
SINGLE_BATTLE_TEST("Dire Claw cannot poison/paralyze/cause to fall asleep a mon which is already statused")
{
u8 statusAnim;
u32 rng;
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PSN; rng = RNG_POISON; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_SLP; rng = RNG_SLEEP; }
GIVEN {
RNGSeed(rng);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) {Status1(STATUS1_BURN);}
} WHEN {
TURN { MOVE(player, MOVE_DIRE_CLAW); }
TURN {}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_DIRE_CLAW, player);
HP_BAR(opponent);
NOT ANIMATION(ANIM_TYPE_STATUS, statusAnim, opponent);
if (statusAnim == B_ANIM_STATUS_PRZ) {
NOT STATUS_ICON(opponent, paralysis: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_SLP) {
NOT STATUS_ICON(opponent, sleep: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_PSN) {
NOT STATUS_ICON(opponent, poison: TRUE);
}
}
}

View File

@ -0,0 +1,117 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_STONE_AXE].effect == EFFECT_HIT_SET_ENTRY_HAZARD);
ASSUME(gBattleMoves[MOVE_CEASELESS_EDGE].effect == EFFECT_HIT_SET_ENTRY_HAZARD);
}
SINGLE_BATTLE_TEST("Stone Axe / Ceaseless Edge set up hazards after hitting the target")
{
u16 move;
PARAMETRIZE {move = MOVE_STONE_AXE; }
PARAMETRIZE {move = MOVE_CEASELESS_EDGE; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, move); }
TURN { SWITCH(opponent, 1); }
} SCENE {
s32 maxHP = GetMonData(&OPPONENT_PARTY[1], MON_DATA_MAX_HP);
ANIMATION(ANIM_TYPE_MOVE, move, player);
HP_BAR(opponent);
if (move == MOVE_CEASELESS_EDGE) {
MESSAGE("Spikes were scattered all around the opposing team!");
}
else {
MESSAGE("Pointed stones float in the air around the opposing team!");
}
MESSAGE("2 sent out Wobbuffet!");
if (move == MOVE_CEASELESS_EDGE) {
HP_BAR(opponent, damage: maxHP / 8);
MESSAGE("Foe Wobbuffet is hurt by spikes!");
}
else {
HP_BAR(opponent, damage: maxHP / 8);
MESSAGE("Pointed stones dug into Foe Wobbuffet!");
}
}
}
SINGLE_BATTLE_TEST("Ceaseless Edge can set up to 3 layers of Spikes")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { MOVE(player, MOVE_CEASELESS_EDGE); }
TURN { MOVE(player, MOVE_CEASELESS_EDGE); }
TURN { MOVE(player, MOVE_CEASELESS_EDGE); }
TURN { MOVE(player, MOVE_CEASELESS_EDGE); }
TURN { SWITCH(opponent, 1); }
} SCENE {
s32 maxHP = GetMonData(&OPPONENT_PARTY[1], MON_DATA_MAX_HP);
ANIMATION(ANIM_TYPE_MOVE, MOVE_CEASELESS_EDGE, player);
HP_BAR(opponent);
MESSAGE("Spikes were scattered all around the opposing team!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_CEASELESS_EDGE, player);
HP_BAR(opponent);
MESSAGE("Spikes were scattered all around the opposing team!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_CEASELESS_EDGE, player);
HP_BAR(opponent);
MESSAGE("Spikes were scattered all around the opposing team!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_CEASELESS_EDGE, player);
HP_BAR(opponent);
NOT MESSAGE("Spikes were scattered all around the opposing team!");
MESSAGE("2 sent out Wynaut!");
HP_BAR(opponent, damage: maxHP / 4);
MESSAGE("Foe Wynaut is hurt by spikes!");
}
}
SINGLE_BATTLE_TEST("Stone Axe can set up pointed stones only once")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WYNAUT);
} WHEN {
TURN { MOVE(player, MOVE_STONE_AXE); }
TURN { MOVE(player, MOVE_STONE_AXE); }
TURN { MOVE(player, MOVE_STONE_AXE); }
TURN { MOVE(player, MOVE_STONE_AXE); }
TURN { SWITCH(opponent, 1); }
} SCENE {
s32 maxHP = GetMonData(&OPPONENT_PARTY[1], MON_DATA_MAX_HP);
ANIMATION(ANIM_TYPE_MOVE, MOVE_STONE_AXE, player);
HP_BAR(opponent);
MESSAGE("Pointed stones float in the air around the opposing team!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_STONE_AXE, player);
HP_BAR(opponent);
NOT MESSAGE("Pointed stones float in the air around the opposing team!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_STONE_AXE, player);
HP_BAR(opponent);
NOT MESSAGE("Pointed stones float in the air around the opposing team!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_STONE_AXE, player);
HP_BAR(opponent);
NOT MESSAGE("Pointed stones float in the air around the opposing team!");
MESSAGE("2 sent out Wynaut!");
HP_BAR(opponent, damage: maxHP / 8);
MESSAGE("Pointed stones dug into Foe Wynaut!");
}
}

View File

@ -28,7 +28,7 @@ SINGLE_BATTLE_TEST("Spikes damage on switch in")
s32 maxHP = GetMonData(&OPPONENT_PARTY[1], MON_DATA_MAX_HP);
for (count = 0; count < layers; ++count) {
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPIKES, player);
MESSAGE("Spikes were scattered all around the opponent's side!");
MESSAGE("Spikes were scattered all around the opposing team!");
}
MESSAGE("2 sent out Wynaut!");
HP_BAR(opponent, damage: maxHP / divisor);
@ -51,11 +51,11 @@ SINGLE_BATTLE_TEST("Spikes fails after 3 layers")
} SCENE {
s32 maxHP = GetMonData(&OPPONENT_PARTY[1], MON_DATA_MAX_HP);
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPIKES, player);
MESSAGE("Spikes were scattered all around the opponent's side!");
MESSAGE("Spikes were scattered all around the opposing team!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPIKES, player);
MESSAGE("Spikes were scattered all around the opponent's side!");
MESSAGE("Spikes were scattered all around the opposing team!");
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPIKES, player);
MESSAGE("Spikes were scattered all around the opponent's side!");
MESSAGE("Spikes were scattered all around the opposing team!");
MESSAGE("Wobbuffet used Spikes!");
MESSAGE("But it failed!");
MESSAGE("2 sent out Wynaut!");

View File

@ -0,0 +1,145 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_TRI_ATTACK].effect == EFFECT_TRI_ATTACK);
}
// found by brute-force
#define RNG_PARALYSIS 0xcb0
#define RNG_BURN 0x2BE
#define RNG_FREEZE 5
SINGLE_BATTLE_TEST("Tri Attack can inflict paralysis, burn or freeze")
{
u8 statusAnim;
u32 rng;
KNOWN_FAILING;
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_BRN; rng = RNG_BURN; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_FRZ; rng = RNG_FREEZE; }
GIVEN {
RNGSeed(rng);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_TRI_ATTACK); }
TURN {}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRI_ATTACK, player);
HP_BAR(opponent);
ANIMATION(ANIM_TYPE_STATUS, statusAnim, opponent);
if (statusAnim == B_ANIM_STATUS_BRN) {
STATUS_ICON(opponent, burn: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_FRZ) {
STATUS_ICON(opponent, freeze: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_PRZ) {
STATUS_ICON(opponent, paralysis: TRUE);
}
}
}
SINGLE_BATTLE_TEST("Tri Attack cannot paralyze/burn/freeze electric/fire/ice types respectively")
{
u8 statusAnim;
u16 species;
u32 rng;
#if B_PARALYZE_ELECTRIC >= GEN_6
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; species = SPECIES_RAICHU;}
#endif // B_PARALYZE_ELECTRIC
PARAMETRIZE { statusAnim = B_ANIM_STATUS_BRN; rng = RNG_BURN; species = SPECIES_ARCANINE; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_FRZ; rng = RNG_FREEZE; species = SPECIES_GLALIE; }
GIVEN {
RNGSeed(rng);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species);
} WHEN {
TURN { MOVE(player, MOVE_TRI_ATTACK); }
TURN {}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRI_ATTACK, player);
HP_BAR(opponent);
NOT ANIMATION(ANIM_TYPE_STATUS, statusAnim, opponent);
if (statusAnim == B_ANIM_STATUS_BRN) {
NOT STATUS_ICON(opponent, burn: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_FRZ) {
NOT STATUS_ICON(opponent, freeze: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_PRZ) {
NOT STATUS_ICON(opponent, paralysis: TRUE);
}
}
}
SINGLE_BATTLE_TEST("Tri Attack cannot paralyze/burn/freeze pokemon with abilities preventing respective statuses")
{
u8 statusAnim;
u16 species, ability;
u32 rng;
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; species = SPECIES_RAICHU; ability = ABILITY_LIGHTNING_ROD; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; species = SPECIES_JOLTEON; ability = ABILITY_VOLT_ABSORB; }
#if P_GEN_4_POKEMON == TRUE
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; species = SPECIES_ELECTIVIRE; ability = ABILITY_MOTOR_DRIVE; }
#endif // P_GEN_4_POKEMON
#if P_GEN_7_POKEMON == TRUE
PARAMETRIZE { statusAnim = B_ANIM_STATUS_BRN; rng = RNG_BURN; species = SPECIES_DEWPIDER; ability = ABILITY_WATER_BUBBLE; }
#endif // P_GEN_7_POKEMON
PARAMETRIZE { statusAnim = B_ANIM_STATUS_BRN; rng = RNG_BURN; species = SPECIES_SEAKING; ability = ABILITY_WATER_VEIL; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_FRZ; rng = RNG_FREEZE; species = SPECIES_CAMERUPT; ability = ABILITY_MAGMA_ARMOR; }
GIVEN {
RNGSeed(rng);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) {Ability(ability);}
} WHEN {
TURN { MOVE(player, MOVE_TRI_ATTACK); }
TURN {}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRI_ATTACK, player);
HP_BAR(opponent);
NOT ANIMATION(ANIM_TYPE_STATUS, statusAnim, opponent);
if (statusAnim == B_ANIM_STATUS_BRN) {
NOT STATUS_ICON(opponent, burn: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_FRZ) {
NOT STATUS_ICON(opponent, freeze: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_PRZ) {
NOT STATUS_ICON(opponent, paralysis: TRUE);
}
}
}
SINGLE_BATTLE_TEST("Tri Attack cannot paralyze/burn/freeze a mon which is already statused")
{
u8 statusAnim;
u32 rng;
PARAMETRIZE { statusAnim = B_ANIM_STATUS_PRZ; rng = RNG_PARALYSIS; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_BRN; rng = RNG_BURN; }
PARAMETRIZE { statusAnim = B_ANIM_STATUS_FRZ; rng = RNG_FREEZE; }
GIVEN {
RNGSeed(rng);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) {Status1(STATUS1_SLEEP);}
} WHEN {
TURN { MOVE(player, MOVE_TRI_ATTACK); }
TURN {}
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRI_ATTACK, player);
HP_BAR(opponent);
NOT ANIMATION(ANIM_TYPE_STATUS, statusAnim, opponent);
if (statusAnim == B_ANIM_STATUS_BRN) {
NOT STATUS_ICON(opponent, burn: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_FRZ) {
NOT STATUS_ICON(opponent, freeze: TRUE);
}
else if (statusAnim == B_ANIM_STATUS_PRZ) {
NOT STATUS_ICON(opponent, paralysis: TRUE);
}
}
}

View File

@ -0,0 +1,27 @@
#include "global.h"
#include "test_battle.h"
ASSUMPTIONS
{
ASSUME(gBattleMoves[MOVE_VENOSHOCK].effect == EFFECT_VENOSHOCK);
}
SINGLE_BATTLE_TEST("Venoshock's power doubles if the target is poisoned/badly poisoned", s16 damage)
{
u32 status1;
PARAMETRIZE { status1 = 0; }
PARAMETRIZE { status1 = STATUS1_POISON; }
PARAMETRIZE { status1 = STATUS1_TOXIC_POISON; }
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET) {Status1(status1);}
} WHEN {
TURN { MOVE(player, MOVE_VENOSHOCK); }
} SCENE {
ANIMATION(ANIM_TYPE_MOVE, MOVE_VENOSHOCK, player);
HP_BAR(opponent, captureDamage: &results[i].damage);
} FINALLY {
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[1].damage);
EXPECT_MUL_EQ(results[0].damage, Q_4_12(2.0), results[2].damage);
}
}

19
test/terrain_grassy.c Normal file
View File

@ -0,0 +1,19 @@
#include "global.h"
#include "test_battle.h"
SINGLE_BATTLE_TEST("Grassy Terrain recovers 1/16th HP at end of turn")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET) { MaxHP(100); HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_GRASSY_TERRAIN); }
} SCENE {
s32 maxHP = GetMonData(&PLAYER_PARTY[0], MON_DATA_MAX_HP);
MESSAGE("Wobbuffet is healed by the grassy terrain!");
HP_BAR(player, damage: -maxHP / 16);
}
}
TO_DO_BATTLE_TEST("Grassy Terrain increases power of Grass-type moves by 30/50 percent")
TO_DO_BATTLE_TEST("Grassy Terrain decreases power of Earthquake, Magnitude and Bulldoze by 50 percent")

View File

@ -13,6 +13,7 @@ enum TestResult
TEST_RESULT_INVALID,
TEST_RESULT_ERROR,
TEST_RESULT_TIMEOUT,
TEST_RESULT_TODO,
};
struct TestRunner
@ -161,4 +162,10 @@ s32 MgbaPrintf_(const char *fmt, ...);
#define PARAMETRIZE if (gFunctionTestRunnerState->parameters++ == gFunctionTestRunnerState->runParameter)
#define TO_DO \
Test_ExpectedResult(TEST_RESULT_TODO)
#define EXPECT_TO_DO \
Test_ExitWithResult(TEST_RESULT_TODO, "%s:%d: EXPECT_TO_DO", gTestRunnerState.test->filename, __LINE__)
#endif

View File

@ -634,6 +634,15 @@ extern struct BattleTestRunnerState *gBattleTestRunnerState;
/* Test */
#define TO_DO_BATTLE_TEST(_name) \
SINGLE_BATTLE_TEST("TODO: " _name) \
{ \
TO_DO; \
GIVEN { PLAYER(SPECIES_WOBBUFFET); OPPONENT(SPECIES_WOBBUFFET); } \
WHEN { TURN { } } \
THEN { EXPECT_TO_DO; } \
}
#define SINGLE_BATTLE_TEST(_name, ...) \
struct CAT(Result, __LINE__) { MEMBERS(__VA_ARGS__) }; \
static void CAT(Test, __LINE__)(struct CAT(Result, __LINE__) *, u32, struct BattlePokemon *, struct BattlePokemon *); \

View File

@ -195,6 +195,10 @@ void CB2_TestRunner(void)
result = "ASSUMPTION_FAIL";
color = "\e[33m";
break;
case TEST_RESULT_TODO:
result = "TO_DO";
color = "\e[33m";
break;
case TEST_RESULT_INVALID:
result = "INVALID";
break;
@ -213,6 +217,8 @@ void CB2_TestRunner(void)
MgbaPrintf_(":P%s%s\e[0m", color, result);
else if (gTestRunnerState.result == TEST_RESULT_ASSUMPTION_FAIL)
MgbaPrintf_(":A%s%s\e[0m", color, result);
else if (gTestRunnerState.result == TEST_RESULT_TODO)
MgbaPrintf_(":T%s%s\e[0m", color, result);
else if (gTestRunnerState.expectedResult == gTestRunnerState.result)
MgbaPrintf_(":K%s%s\e[0m", color, result);
else

140
test/trainer_control.c Normal file
View File

@ -0,0 +1,140 @@
#include "global.h"
#include "test.h"
#include "battle.h"
#include "battle_main.h"
#include "data.h"
#include "malloc.h"
#include "string_util.h"
#include "constants/item.h"
#include "constants/abilities.h"
#include "constants/trainers.h"
#include "constants/battle.h"
static const struct TrainerMonCustomized sTestParty1[] =
{
{
.species = SPECIES_WOBBUFFET,
.ball = ITEM_MASTER_BALL,
.ability = ABILITY_TELEPATHY,
.friendship = 42,
.gender = TRAINER_MON_FEMALE,
.heldItem = ITEM_ASSAULT_VEST,
.isShiny = TRUE,
.iv = TRAINER_PARTY_IVS(25,26,27,28,29,30),
.ev = TRAINER_PARTY_EVS(252, 0, 0, 252, 4, 0),
.lvl = 67,
.moves = {MOVE_AIR_SLASH, MOVE_BARRIER, MOVE_SOLAR_BEAM, MOVE_EXPLOSION},
.nature = TRAINER_PARTY_NATURE(NATURE_HASTY),
.nickname = COMPOUND_STRING("Bubbles")
},
{
.species = SPECIES_WOBBUFFET,
.ability = ABILITY_SHADOW_TAG,
.lvl = 5,
},
};
static const struct TrainerMonNoItemDefaultMoves sTestParty2[] =
{
{
.species = SPECIES_WOBBUFFET,
.lvl = 5,
},
{
.species = SPECIES_WOBBUFFET,
.lvl = 6,
}
};
static const struct Trainer sTestTrainer1 =
{
.trainerName = _("Test1"),
.party = EVERYTHING_CUSTOMIZED(sTestParty1),
};
static const struct Trainer sTestTrainer2 =
{
.trainerName = _("Test2"),
.party = NO_ITEM_DEFAULT_MOVES(sTestParty2),
};
TEST("CreateNPCTrainerPartyForTrainer generates customized Pokémon")
{
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
u8 nickBuffer[20];
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainer1, TRUE, BATTLE_TYPE_TRAINER);
EXPECT(IsMonShiny(&testParty[0]));
EXPECT(!IsMonShiny(&testParty[1]));
EXPECT(GetMonData(&testParty[0], MON_DATA_POKEBALL, 0) == ITEM_MASTER_BALL);
EXPECT(GetMonData(&testParty[1], MON_DATA_POKEBALL, 0) == ITEM_POKE_BALL);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPECIES, 0) == SPECIES_WOBBUFFET);
EXPECT(GetMonData(&testParty[1], MON_DATA_SPECIES, 0) == SPECIES_WOBBUFFET);
EXPECT(GetMonAbility(&testParty[0]) == ABILITY_TELEPATHY);
EXPECT(GetMonAbility(&testParty[1]) == ABILITY_SHADOW_TAG);
EXPECT(GetMonData(&testParty[0], MON_DATA_FRIENDSHIP, 0) == 42);
EXPECT(GetMonData(&testParty[1], MON_DATA_FRIENDSHIP, 0) == 0);
EXPECT(GetMonData(&testParty[0], MON_DATA_HELD_ITEM, 0) == ITEM_ASSAULT_VEST);
EXPECT(GetMonData(&testParty[1], MON_DATA_HELD_ITEM, 0) == ITEM_NONE);
EXPECT(GetMonData(&testParty[0], MON_DATA_HP_IV, 0) == 25);
EXPECT(GetMonData(&testParty[0], MON_DATA_ATK_IV, 0) == 26);
EXPECT(GetMonData(&testParty[0], MON_DATA_DEF_IV, 0) == 27);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPEED_IV, 0) == 28);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPATK_IV, 0) == 29);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPDEF_IV, 0) == 30);
EXPECT(GetMonData(&testParty[1], MON_DATA_HP_IV, 0) == 0);
EXPECT(GetMonData(&testParty[1], MON_DATA_ATK_IV, 0) == 0);
EXPECT(GetMonData(&testParty[1], MON_DATA_DEF_IV, 0) == 0);
EXPECT(GetMonData(&testParty[1], MON_DATA_SPEED_IV, 0) == 0);
EXPECT(GetMonData(&testParty[1], MON_DATA_SPATK_IV, 0) == 0);
EXPECT(GetMonData(&testParty[1], MON_DATA_SPDEF_IV, 0) == 0);
EXPECT(GetMonData(&testParty[0], MON_DATA_HP_EV, 0) == 252);
EXPECT(GetMonData(&testParty[0], MON_DATA_ATK_EV, 0) == 0);
EXPECT(GetMonData(&testParty[0], MON_DATA_DEF_EV, 0) == 0);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPEED_EV, 0) == 252);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPATK_EV, 0) == 4);
EXPECT(GetMonData(&testParty[0], MON_DATA_SPDEF_EV, 0) == 0);
EXPECT(GetMonData(&testParty[1], MON_DATA_HP_EV, 0) == 0);
EXPECT(GetMonData(&testParty[1], MON_DATA_ATK_EV, 0) == 0);
EXPECT(GetMonData(&testParty[1], MON_DATA_DEF_EV, 0) == 0);
EXPECT(GetMonData(&testParty[1], MON_DATA_SPEED_EV, 0) == 0);
EXPECT(GetMonData(&testParty[1], MON_DATA_SPATK_EV, 0) == 0);
EXPECT(GetMonData(&testParty[1], MON_DATA_SPDEF_EV, 0) == 0);
EXPECT(GetMonData(&testParty[0], MON_DATA_LEVEL, 0) == 67);
EXPECT(GetMonData(&testParty[1], MON_DATA_LEVEL, 0) == 5);
EXPECT(GetMonData(&testParty[0], MON_DATA_MOVE1, 0) == MOVE_AIR_SLASH);
EXPECT(GetMonData(&testParty[0], MON_DATA_MOVE2, 0) == MOVE_BARRIER);
EXPECT(GetMonData(&testParty[0], MON_DATA_MOVE3, 0) == MOVE_SOLAR_BEAM);
EXPECT(GetMonData(&testParty[0], MON_DATA_MOVE4, 0) == MOVE_EXPLOSION);
GetMonData(&testParty[0], MON_DATA_NICKNAME, nickBuffer);
EXPECT(StringCompare(nickBuffer, COMPOUND_STRING("Bubbles")) == 0);
GetMonData(&testParty[1], MON_DATA_NICKNAME, nickBuffer);
EXPECT(StringCompare(nickBuffer, COMPOUND_STRING("Wobbuffet")) == 0);
EXPECT(GetGenderFromSpeciesAndPersonality(GetMonData(&testParty[0], MON_DATA_SPECIES, 0), testParty[0].box.personality) == MON_FEMALE);
EXPECT(GetNature(&testParty[0]) == NATURE_HASTY);
Free(testParty);
}
TEST("CreateNPCTrainerPartyForTrainer generates different personalities for different mons")
{
struct Pokemon *testParty = Alloc(6 * sizeof(struct Pokemon));
CreateNPCTrainerPartyFromTrainer(testParty, &sTestTrainer2, TRUE, BATTLE_TYPE_TRAINER);
EXPECT(testParty[0].box.personality != testParty[1].box.personality);
Free(testParty);
}

View File

@ -44,6 +44,7 @@ struct Runner
char *output_buffer;
int passes;
int knownFails;
int todos;
int assumptionFails;
int fails;
int results;
@ -87,6 +88,9 @@ static void handle_read(struct Runner *runner)
case 'K':
runner->knownFails++;
goto add_to_results;
case 'T':
runner->todos++;
goto add_to_results;
case 'A':
runner->assumptionFails++;
goto add_to_results;
@ -427,6 +431,7 @@ int main(int argc, char *argv[])
int exit_code = 0;
int passes = 0;
int knownFails = 0;
int todos = 0;
int assumptionFails = 0;
int fails = 0;
int results = 0;
@ -444,6 +449,7 @@ int main(int argc, char *argv[])
exit_code = WEXITSTATUS(wstatus);
passes += runners[i].passes;
knownFails += runners[i].knownFails;
todos += runners[i].todos;
assumptionFails += runners[i].assumptionFails;
fails += runners[i].fails;
results += runners[i].results;
@ -459,6 +465,8 @@ int main(int argc, char *argv[])
fprintf(stdout, "- Tests \e[32mPASSED\e[0m: %d\n", passes);
if (knownFails > 0)
fprintf(stdout, "- Tests \e[33mKNOWN_FAILING\e[0m: %d\n", knownFails);
if (todos > 0)
fprintf(stdout, "- Tests \e[33mTO_DO\e[0m: %d\n", todos);
if (fails > 0)
fprintf(stdout, "- Tests \e[31mFAILED\e[0m : %d\n", fails);
if (assumptionFails > 0)