Merge branch 'upcoming' into stairWarps
This commit is contained in:
commit
6dd78cfdb9
@ -1757,6 +1757,8 @@ BattleScript_EffectInstruct::
|
||||
tryinstruct BattleScript_ButItFailed
|
||||
attackanimation
|
||||
waitanimation
|
||||
copybyte gBattlerAttacker, gBattlerTarget
|
||||
copybyte gBattlerTarget, gEffectBattler
|
||||
printstring STRINGID_USEDINSTRUCTEDMOVE
|
||||
waitmessage B_WAIT_TIME_LONG
|
||||
setbyte sB_ANIM_TURN, 0
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
To run all the tests use:
|
||||
`make check -j`
|
||||
To run specific tests, e.g. Spikes ones, use:
|
||||
`make check TESTS='Spikes'`
|
||||
`make check TESTS="Spikes"`
|
||||
To build a ROM (pokemerald-test.elf) that can be opened in mgba to view specific tests, e.g. Spikes ones, use:
|
||||
`make pokeemerald-test.elf TESTS='Spikes'`
|
||||
`make pokeemerald-test.elf TESTS="Spikes"`
|
||||
|
||||
## How to Write Tests
|
||||
Manually testing a battle mechanic often follows this pattern:
|
||||
@ -54,7 +54,7 @@ The `ASSUMPTIONS` block documents that Stun Spore has `EFFECT_PARALYZE`.
|
||||
If Stun Spore did not have that effect it would cause the tests in the file to be skipped. We write our tests like this so that hackers can change the effects of moves without causing tests to fail.
|
||||
|
||||
`SINGLE_BATTLE_TEST` defines the name of the test. Related tests should start with the same prefix, e.g. Stun Spore tests should start with "Stun Spore", this allows just the Stun Spore-related tests to be run with:
|
||||
`make check TESTS='Stun Spore'`
|
||||
`make check TESTS="Stun Spore"`
|
||||
|
||||
`GIVEN` initializes the parties, `PLAYER` and `OPPONENT` add a Pokémon to their respective parties. They can both accept a block which further customizes the Pokémon's stats, moves, item, ability, etc.
|
||||
|
||||
|
||||
BIN
graphics/pokemon/clodsire/overworld.png
Normal file
BIN
graphics/pokemon/clodsire/overworld.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 856 B |
19
graphics/pokemon/clodsire/overworld_normal.pal
Normal file
19
graphics/pokemon/clodsire/overworld_normal.pal
Normal file
@ -0,0 +1,19 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
152 208 160
|
||||
64 60 48
|
||||
128 108 96
|
||||
96 80 72
|
||||
48 40 32
|
||||
16 16 16
|
||||
184 160 160
|
||||
208 208 208
|
||||
40 36 32
|
||||
152 120 120
|
||||
80 68 72
|
||||
104 52 56
|
||||
176 88 104
|
||||
248 140 160
|
||||
0 0 0
|
||||
0 0 0
|
||||
19
graphics/pokemon/clodsire/overworld_shiny.pal
Normal file
19
graphics/pokemon/clodsire/overworld_shiny.pal
Normal file
@ -0,0 +1,19 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
152 208 160
|
||||
74 67 90
|
||||
127 116 143
|
||||
96 87 115
|
||||
46 40 44
|
||||
16 16 16
|
||||
160 158 197
|
||||
205 180 170
|
||||
40 36 32
|
||||
117 117 158
|
||||
77 63 72
|
||||
104 52 56
|
||||
176 88 104
|
||||
248 140 160
|
||||
0 0 0
|
||||
0 0 0
|
||||
BIN
graphics/pokemon/wooper/wooper_paldean/overworld.png
Normal file
BIN
graphics/pokemon/wooper/wooper_paldean/overworld.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 503 B |
19
graphics/pokemon/wooper/wooper_paldean/overworld_normal.pal
Normal file
19
graphics/pokemon/wooper/wooper_paldean/overworld_normal.pal
Normal file
@ -0,0 +1,19 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
153 211 165
|
||||
99 73 120
|
||||
201 177 219
|
||||
85 67 66
|
||||
104 82 81
|
||||
16 16 16
|
||||
169 147 146
|
||||
130 103 102
|
||||
158 129 179
|
||||
255 255 255
|
||||
46 36 35
|
||||
180 65 65
|
||||
255 106 115
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
19
graphics/pokemon/wooper/wooper_paldean/overworld_shiny.pal
Normal file
19
graphics/pokemon/wooper/wooper_paldean/overworld_shiny.pal
Normal file
@ -0,0 +1,19 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
16
|
||||
153 211 165
|
||||
120 80 48
|
||||
230 186 149
|
||||
102 96 146
|
||||
140 133 186
|
||||
16 16 16
|
||||
204 202 219
|
||||
171 167 198
|
||||
200 144 97
|
||||
255 255 255
|
||||
35 36 46
|
||||
180 65 65
|
||||
255 106 115
|
||||
0 0 0
|
||||
0 0 0
|
||||
0 0 0
|
||||
@ -115,17 +115,15 @@ struct DisableStruct
|
||||
u8 disableTimer:4;
|
||||
u8 encoreTimer:4;
|
||||
u8 perishSongTimer:4;
|
||||
u8 furyCutterCounter;
|
||||
u8 rolloutTimer:4;
|
||||
u8 rolloutTimerStartValue:4;
|
||||
u8 chargeTimer:4;
|
||||
u8 tauntTimer:4;
|
||||
u8 furyCutterCounter;
|
||||
u8 battlerPreventingEscape;
|
||||
u8 battlerWithSureHit;
|
||||
u8 isFirstTurn;
|
||||
u8 truantCounter:1;
|
||||
u8 truantSwitchInHack:1;
|
||||
u8 mimickedMoves:4;
|
||||
u8 chargeTimer:4;
|
||||
u8 rechargeTimer;
|
||||
u8 autotomizeCount;
|
||||
u8 slowStartTimer;
|
||||
@ -138,6 +136,8 @@ struct DisableStruct
|
||||
u8 wrapTurns;
|
||||
u8 tormentTimer:4; // used for G-Max Meltdown
|
||||
u8 usedMoves:4;
|
||||
u8 truantCounter:1;
|
||||
u8 truantSwitchInHack:1;
|
||||
u8 noRetreat:1;
|
||||
u8 tarShot:1;
|
||||
u8 octolock:1;
|
||||
@ -221,7 +221,7 @@ struct SpecialStatus
|
||||
u8 faintedHasReplacement:1;
|
||||
u8 focusBanded:1;
|
||||
u8 focusSashed:1;
|
||||
u8 unused:1;
|
||||
u8 unused:2;
|
||||
// End of byte
|
||||
u8 sturdied:1;
|
||||
u8 stormDrainRedirected:1;
|
||||
@ -818,6 +818,7 @@ struct BattleStruct
|
||||
u8 categoryOverride; // for Z-Moves and Max Moves
|
||||
u32 stellarBoostFlags[NUM_BATTLE_SIDES]; // stored as a bitfield of flags for all types for each side
|
||||
u8 fickleBeamBoosted:1;
|
||||
u8 obedienceResult:3;
|
||||
};
|
||||
|
||||
// The palaceFlags member of struct BattleStruct contains 1 flag per move to indicate which moves the AI should consider,
|
||||
|
||||
@ -205,5 +205,6 @@ bool32 AI_ShouldCopyStatChanges(u32 battlerAtk, u32 battlerDef);
|
||||
bool32 AI_ShouldSetUpHazards(u32 battlerAtk, u32 battlerDef, struct AiLogicData *aiData);
|
||||
void IncreaseTidyUpScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
bool32 AI_ShouldSpicyExtract(u32 battlerAtk, u32 battlerAtkPartner, u32 move, struct AiLogicData *aiData);
|
||||
void IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score);
|
||||
|
||||
#endif //GUARD_BATTLE_AI_UTIL_H
|
||||
|
||||
@ -263,7 +263,6 @@ extern const u8 BattleScript_EmbargoEndTurn[];
|
||||
extern const u8 BattleScript_TelekinesisEndTurn[];
|
||||
extern const u8 BattleScript_BufferEndTurn[];
|
||||
extern const u8 BattleScript_AquaRingHeal[];
|
||||
extern const u8 BattleScript_AuroraVeilEnds[];
|
||||
extern const u8 BattleScript_LuckyChantEnds[];
|
||||
extern const u8 BattleScript_TailwindEnds[];
|
||||
extern const u8 BattleScript_TrickRoomEnds[];
|
||||
@ -469,7 +468,6 @@ extern const u8 BattleScript_AngerShellActivates[];
|
||||
extern const u8 BattleScript_WellBakedBodyActivates[];
|
||||
extern const u8 BattleScript_WindRiderActivatesMoveEnd[];
|
||||
extern const u8 BattleScript_WindPowerActivates[];
|
||||
extern const u8 BattleScript_WindPowerActivatesEnd2[];
|
||||
extern const u8 BattleScript_ProtosynthesisActivates[];
|
||||
extern const u8 BattleScript_QuarkDriveActivates[];
|
||||
extern const u8 BattleScript_GoodAsGoldActivates[];
|
||||
|
||||
@ -106,6 +106,15 @@ enum
|
||||
CANCELLER_END2,
|
||||
};
|
||||
|
||||
enum {
|
||||
OBEYS,
|
||||
DISOBEYS_LOAFS,
|
||||
DISOBEYS_HITS_SELF,
|
||||
DISOBEYS_FALL_ASLEEP,
|
||||
DISOBEYS_WHILE_ASLEEP,
|
||||
DISOBEYS_RANDOM_MOVE,
|
||||
};
|
||||
|
||||
extern const struct TypePower gNaturalGiftTable[];
|
||||
|
||||
void HandleAction_ThrowBall(void);
|
||||
@ -171,7 +180,7 @@ void ClearVariousBattlerFlags(u32 battler);
|
||||
void HandleAction_RunBattleScript(void);
|
||||
u32 SetRandomTarget(u32 battler);
|
||||
u32 GetMoveTarget(u16 move, u8 setTarget);
|
||||
u8 IsMonDisobedient(void);
|
||||
u8 GetAttackerObedienceForAction();
|
||||
u32 GetBattlerHoldEffect(u32 battler, bool32 checkNegating);
|
||||
u32 GetBattlerHoldEffectIgnoreAbility(u32 battler, bool32 checkNegating);
|
||||
u32 GetBattlerHoldEffectInternal(u32 battler, bool32 checkNegating, bool32 checkAbility);
|
||||
|
||||
@ -121,6 +121,7 @@
|
||||
#define B_SKETCH_BANS GEN_LATEST // In Gen9+, Sketch is unable to copy more moves than in previous generations.
|
||||
#define B_KNOCK_OFF_REMOVAL GEN_LATEST // In Gen5+, Knock Off removes the foe's item instead of rendering it unusable.
|
||||
#define B_HEAL_BELL_SOUNDPROOF GEN_LATEST // In Gen5, Heal Bell affects all mons with Soundproof. In Gen6-8 it affects inactive mons, but not battlers. In Gen9 it always affects the user.
|
||||
#define B_CHARGE GEN_LATEST // In Gen8-, Charge status is lost regardless of the typing of the next move.
|
||||
|
||||
// Ability settings
|
||||
#define B_EXPANDED_ABILITY_NAMES TRUE // If TRUE, ability names are increased from 12 characters to 16 characters.
|
||||
|
||||
@ -444,277 +444,276 @@
|
||||
#define STRINGID_WATERSPORTENDS 442
|
||||
#define STRINGID_GRAVITYENDS 443
|
||||
#define STRINGID_AQUARINGHEAL 444
|
||||
#define STRINGID_AURORAVEILENDS 445
|
||||
#define STRINGID_ELECTRICTERRAINENDS 446
|
||||
#define STRINGID_MISTYTERRAINENDS 447
|
||||
#define STRINGID_PSYCHICTERRAINENDS 448
|
||||
#define STRINGID_GRASSYTERRAINENDS 449
|
||||
#define STRINGID_TARGETABILITYSTATRAISE 450
|
||||
#define STRINGID_TARGETSSTATWASMAXEDOUT 451
|
||||
#define STRINGID_ATTACKERABILITYSTATRAISE 452
|
||||
#define STRINGID_POISONHEALHPUP 453
|
||||
#define STRINGID_BADDREAMSDMG 454
|
||||
#define STRINGID_MOLDBREAKERENTERS 455
|
||||
#define STRINGID_TERAVOLTENTERS 456
|
||||
#define STRINGID_TURBOBLAZEENTERS 457
|
||||
#define STRINGID_SLOWSTARTENTERS 458
|
||||
#define STRINGID_SLOWSTARTEND 459
|
||||
#define STRINGID_SOLARPOWERHPDROP 460
|
||||
#define STRINGID_AFTERMATHDMG 461
|
||||
#define STRINGID_ANTICIPATIONACTIVATES 462
|
||||
#define STRINGID_FOREWARNACTIVATES 463
|
||||
#define STRINGID_ICEBODYHPGAIN 464
|
||||
#define STRINGID_SNOWWARNINGHAIL 465
|
||||
#define STRINGID_FRISKACTIVATES 466
|
||||
#define STRINGID_UNNERVEENTERS 467
|
||||
#define STRINGID_HARVESTBERRY 468
|
||||
#define STRINGID_LASTABILITYRAISEDSTAT 469
|
||||
#define STRINGID_MAGICBOUNCEACTIVATES 470
|
||||
#define STRINGID_PROTEANTYPECHANGE 471
|
||||
#define STRINGID_SYMBIOSISITEMPASS 472
|
||||
#define STRINGID_STEALTHROCKDMG 473
|
||||
#define STRINGID_TOXICSPIKESABSORBED 474
|
||||
#define STRINGID_TOXICSPIKESPOISONED 475
|
||||
#define STRINGID_STICKYWEBSWITCHIN 476
|
||||
#define STRINGID_HEALINGWISHCAMETRUE 477
|
||||
#define STRINGID_HEALINGWISHHEALED 478
|
||||
#define STRINGID_LUNARDANCECAMETRUE 479
|
||||
#define STRINGID_CUSEDBODYDISABLED 480
|
||||
#define STRINGID_ATTACKERACQUIREDABILITY 481
|
||||
#define STRINGID_TARGETABILITYSTATLOWER 482
|
||||
#define STRINGID_TARGETSTATWONTGOHIGHER 483
|
||||
#define STRINGID_PKMNMOVEBOUNCEDABILITY 484
|
||||
#define STRINGID_IMPOSTERTRANSFORM 485
|
||||
#define STRINGID_ASSAULTVESTDOESNTALLOW 486
|
||||
#define STRINGID_GRAVITYPREVENTSUSAGE 487
|
||||
#define STRINGID_HEALBLOCKPREVENTSUSAGE 488
|
||||
#define STRINGID_NOTDONEYET 489
|
||||
#define STRINGID_STICKYWEBUSED 490
|
||||
#define STRINGID_QUASHSUCCESS 491
|
||||
#define STRINGID_PKMNBLEWAWAYTOXICSPIKES 492
|
||||
#define STRINGID_PKMNBLEWAWAYSTICKYWEB 493
|
||||
#define STRINGID_PKMNBLEWAWAYSTEALTHROCK 494
|
||||
#define STRINGID_IONDELUGEON 495
|
||||
#define STRINGID_TOPSYTURVYSWITCHEDSTATS 496
|
||||
#define STRINGID_TERRAINBECOMESMISTY 497
|
||||
#define STRINGID_TERRAINBECOMESGRASSY 498
|
||||
#define STRINGID_TERRAINBECOMESELECTRIC 499
|
||||
#define STRINGID_TERRAINBECOMESPSYCHIC 500
|
||||
#define STRINGID_TARGETELECTRIFIED 501
|
||||
#define STRINGID_MEGAEVOREACTING 502
|
||||
#define STRINGID_MEGAEVOEVOLVED 503
|
||||
#define STRINGID_DRASTICALLY 504
|
||||
#define STRINGID_SEVERELY 505
|
||||
#define STRINGID_INFESTATION 506
|
||||
#define STRINGID_NOEFFECTONTARGET 507
|
||||
#define STRINGID_BURSTINGFLAMESHIT 508
|
||||
#define STRINGID_BESTOWITEMGIVING 509
|
||||
#define STRINGID_THIRDTYPEADDED 510
|
||||
#define STRINGID_FELLFORFEINT 511
|
||||
#define STRINGID_POKEMONCANNOTUSEMOVE 512
|
||||
#define STRINGID_COVEREDINPOWDER 513
|
||||
#define STRINGID_POWDEREXPLODES 514
|
||||
#define STRINGID_BELCHCANTSELECT 515
|
||||
#define STRINGID_SPECTRALTHIEFSTEAL 516
|
||||
#define STRINGID_GRAVITYGROUNDING 517
|
||||
#define STRINGID_MISTYTERRAINPREVENTS 518
|
||||
#define STRINGID_GRASSYTERRAINHEALS 519
|
||||
#define STRINGID_ELECTRICTERRAINPREVENTS 520
|
||||
#define STRINGID_PSYCHICTERRAINPREVENTS 521
|
||||
#define STRINGID_SAFETYGOGGLESPROTECTED 522
|
||||
#define STRINGID_FLOWERVEILPROTECTED 523
|
||||
#define STRINGID_SWEETVEILPROTECTED 524
|
||||
#define STRINGID_AROMAVEILPROTECTED 525
|
||||
#define STRINGID_CELEBRATEMESSAGE 526
|
||||
#define STRINGID_USEDINSTRUCTEDMOVE 527
|
||||
#define STRINGID_THROATCHOPENDS 528
|
||||
#define STRINGID_PKMNCANTUSEMOVETHROATCHOP 529
|
||||
#define STRINGID_LASERFOCUS 530
|
||||
#define STRINGID_GEMACTIVATES 531
|
||||
#define STRINGID_BERRYDMGREDUCES 532
|
||||
#define STRINGID_TARGETATEITEM 533
|
||||
#define STRINGID_AIRBALLOONFLOAT 534
|
||||
#define STRINGID_AIRBALLOONPOP 535
|
||||
#define STRINGID_INCINERATEBURN 536
|
||||
#define STRINGID_BUGBITE 537
|
||||
#define STRINGID_ILLUSIONWOREOFF 538
|
||||
#define STRINGID_ATTACKERCUREDTARGETSTATUS 539
|
||||
#define STRINGID_ATTACKERLOSTFIRETYPE 540
|
||||
#define STRINGID_HEALERCURE 541
|
||||
#define STRINGID_SCRIPTINGABILITYSTATRAISE 542
|
||||
#define STRINGID_RECEIVERABILITYTAKEOVER 543
|
||||
#define STRINGID_PKNMABSORBINGPOWER 544
|
||||
#define STRINGID_NOONEWILLBEABLETORUNAWAY 545
|
||||
#define STRINGID_DESTINYKNOTACTIVATES 546
|
||||
#define STRINGID_CLOAKEDINAFREEZINGLIGHT 547
|
||||
#define STRINGID_CLEARAMULETWONTLOWERSTATS 548
|
||||
#define STRINGID_FERVENTWISHREACHED 549
|
||||
#define STRINGID_AIRLOCKACTIVATES 550
|
||||
#define STRINGID_PRESSUREENTERS 551
|
||||
#define STRINGID_DARKAURAENTERS 552
|
||||
#define STRINGID_FAIRYAURAENTERS 553
|
||||
#define STRINGID_AURABREAKENTERS 554
|
||||
#define STRINGID_COMATOSEENTERS 555
|
||||
#define STRINGID_SCREENCLEANERENTERS 556
|
||||
#define STRINGID_FETCHEDPOKEBALL 557
|
||||
#define STRINGID_BATTLERABILITYRAISEDSTAT 558
|
||||
#define STRINGID_ASANDSTORMKICKEDUP 559
|
||||
#define STRINGID_PKMNSWILLPERISHIN3TURNS 560
|
||||
#define STRINGID_ABILITYRAISEDSTATDRASTICALLY 561
|
||||
#define STRINGID_AURAFLAREDTOLIFE 562
|
||||
#define STRINGID_ASONEENTERS 563
|
||||
#define STRINGID_CURIOUSMEDICINEENTERS 564
|
||||
#define STRINGID_CANACTFASTERTHANKSTO 565
|
||||
#define STRINGID_MICLEBERRYACTIVATES 566
|
||||
#define STRINGID_PKMNSHOOKOFFTHETAUNT 567
|
||||
#define STRINGID_PKMNGOTOVERITSINFATUATION 568
|
||||
#define STRINGID_ITEMCANNOTBEREMOVED 569
|
||||
#define STRINGID_STICKYBARBTRANSFER 570
|
||||
#define STRINGID_PKMNBURNHEALED 571
|
||||
#define STRINGID_REDCARDACTIVATE 572
|
||||
#define STRINGID_EJECTBUTTONACTIVATE 573
|
||||
#define STRINGID_ATKGOTOVERINFATUATION 574
|
||||
#define STRINGID_TORMENTEDNOMORE 575
|
||||
#define STRINGID_HEALBLOCKEDNOMORE 576
|
||||
#define STRINGID_ATTACKERBECAMEFULLYCHARGED 577
|
||||
#define STRINGID_ATTACKERBECAMEASHSPECIES 578
|
||||
#define STRINGID_EXTREMELYHARSHSUNLIGHT 579
|
||||
#define STRINGID_EXTREMESUNLIGHTFADED 580
|
||||
#define STRINGID_MOVEEVAPORATEDINTHEHARSHSUNLIGHT 581
|
||||
#define STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED 582
|
||||
#define STRINGID_HEAVYRAIN 583
|
||||
#define STRINGID_HEAVYRAINLIFTED 584
|
||||
#define STRINGID_MOVEFIZZLEDOUTINTHEHEAVYRAIN 585
|
||||
#define STRINGID_NORELIEFROMHEAVYRAIN 586
|
||||
#define STRINGID_MYSTERIOUSAIRCURRENT 587
|
||||
#define STRINGID_STRONGWINDSDISSIPATED 588
|
||||
#define STRINGID_MYSTERIOUSAIRCURRENTBLOWSON 589
|
||||
#define STRINGID_ATTACKWEAKENEDBSTRONGWINDS 590
|
||||
#define STRINGID_STUFFCHEEKSCANTSELECT 591
|
||||
#define STRINGID_PKMNREVERTEDTOPRIMAL 592
|
||||
#define STRINGID_BUTPOKEMONCANTUSETHEMOVE 593
|
||||
#define STRINGID_BUTHOOPACANTUSEIT 594
|
||||
#define STRINGID_BROKETHROUGHPROTECTION 595
|
||||
#define STRINGID_ABILITYALLOWSONLYMOVE 596
|
||||
#define STRINGID_SWAPPEDABILITIES 597
|
||||
#define STRINGID_PASTELVEILPROTECTED 598
|
||||
#define STRINGID_PASTELVEILENTERS 599
|
||||
#define STRINGID_BATTLERTYPECHANGEDTO 600
|
||||
#define STRINGID_BOTHCANNOLONGERESCAPE 601
|
||||
#define STRINGID_CANTESCAPEDUETOUSEDMOVE 602
|
||||
#define STRINGID_PKMNBECAMEWEAKERTOFIRE 603
|
||||
#define STRINGID_ABOUTTOUSEPOLTERGEIST 604
|
||||
#define STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE 605
|
||||
#define STRINGID_NEUTRALIZINGGASENTERS 606
|
||||
#define STRINGID_NEUTRALIZINGGASOVER 607
|
||||
#define STRINGID_TARGETTOOHEAVY 608
|
||||
#define STRINGID_PKMNTOOKTARGETHIGH 609
|
||||
#define STRINGID_PKMNINSNAPTRAP 610
|
||||
#define STRINGID_METEORBEAMCHARGING 611
|
||||
#define STRINGID_HEATUPBEAK 612
|
||||
#define STRINGID_COURTCHANGE 613
|
||||
#define STRINGID_PLAYERLOSTTOENEMYTRAINER 614
|
||||
#define STRINGID_PLAYERPAIDPRIZEMONEY 615
|
||||
#define STRINGID_ZPOWERSURROUNDS 616
|
||||
#define STRINGID_ZMOVEUNLEASHED 617
|
||||
#define STRINGID_ZMOVERESETSSTATS 618
|
||||
#define STRINGID_ZMOVEALLSTATSUP 619
|
||||
#define STRINGID_ZMOVEZBOOSTCRIT 620
|
||||
#define STRINGID_ZMOVERESTOREHP 621
|
||||
#define STRINGID_ZMOVESTATUP 622
|
||||
#define STRINGID_ZMOVEHPTRAP 623
|
||||
#define STRINGID_ATTACKEREXPELLEDTHEPOISON 624
|
||||
#define STRINGID_ATTACKERSHOOKITSELFAWAKE 625
|
||||
#define STRINGID_ATTACKERBROKETHROUGHPARALYSIS 626
|
||||
#define STRINGID_ATTACKERHEALEDITSBURN 627
|
||||
#define STRINGID_ATTACKERMELTEDTHEICE 628
|
||||
#define STRINGID_TARGETTOUGHEDITOUT 629
|
||||
#define STRINGID_ATTACKERLOSTELECTRICTYPE 630
|
||||
#define STRINGID_ATTACKERSWITCHEDSTATWITHTARGET 631
|
||||
#define STRINGID_BEINGHITCHARGEDPKMNWITHPOWER 632
|
||||
#define STRINGID_SUNLIGHTACTIVATEDABILITY 633
|
||||
#define STRINGID_STATWASHEIGHTENED 634
|
||||
#define STRINGID_ELECTRICTERRAINACTIVATEDABILITY 635
|
||||
#define STRINGID_ABILITYWEAKENEDSURROUNDINGMONSSTAT 636
|
||||
#define STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN 637
|
||||
#define STRINGID_PKMNSABILITYPREVENTSABILITY 638
|
||||
#define STRINGID_PREPARESHELLTRAP 639
|
||||
#define STRINGID_SHELLTRAPDIDNTWORK 640
|
||||
#define STRINGID_SPIKESDISAPPEAREDFROMTEAM 641
|
||||
#define STRINGID_TOXICSPIKESDISAPPEAREDFROMTEAM 642
|
||||
#define STRINGID_STICKYWEBDISAPPEAREDFROMTEAM 643
|
||||
#define STRINGID_STEALTHROCKDISAPPEAREDFROMTEAM 644
|
||||
#define STRINGID_COULDNTFULLYPROTECT 645
|
||||
#define STRINGID_STOCKPILEDEFFECTWOREOFF 646
|
||||
#define STRINGID_PKMNREVIVEDREADYTOFIGHT 647
|
||||
#define STRINGID_ITEMRESTOREDSPECIESHEALTH 648
|
||||
#define STRINGID_ITEMCUREDSPECIESSTATUS 649
|
||||
#define STRINGID_ITEMRESTOREDSPECIESPP 650
|
||||
#define STRINGID_THUNDERCAGETRAPPED 651
|
||||
#define STRINGID_PKMNHURTBYFROSTBITE 652
|
||||
#define STRINGID_PKMNGOTFROSTBITE 653
|
||||
#define STRINGID_PKMNSITEMHEALEDFROSTBITE 654
|
||||
#define STRINGID_ATTACKERHEALEDITSFROSTBITE 655
|
||||
#define STRINGID_PKMNFROSTBITEHEALED 656
|
||||
#define STRINGID_PKMNFROSTBITEHEALED2 657
|
||||
#define STRINGID_PKMNFROSTBITEHEALEDBY 658
|
||||
#define STRINGID_MIRRORHERBCOPIED 659
|
||||
#define STRINGID_STARTEDSNOW 660
|
||||
#define STRINGID_SNOWCONTINUES 661
|
||||
#define STRINGID_SNOWSTOPPED 662
|
||||
#define STRINGID_SNOWWARNINGSNOW 663
|
||||
#define STRINGID_PKMNITEMMELTED 664
|
||||
#define STRINGID_ULTRABURSTREACTING 665
|
||||
#define STRINGID_ULTRABURSTCOMPLETED 666
|
||||
#define STRINGID_TEAMGAINEDEXP 667
|
||||
#define STRINGID_CURRENTMOVECANTSELECT 668
|
||||
#define STRINGID_TARGETISBEINGSALTCURED 669
|
||||
#define STRINGID_TARGETISHURTBYSALTCURE 670
|
||||
#define STRINGID_TARGETCOVEREDINSTICKYCANDYSYRUP 671
|
||||
#define STRINGID_SHARPSTEELFLOATS 672
|
||||
#define STRINGID_SHARPSTEELDMG 673
|
||||
#define STRINGID_PKMNBLEWAWAYSHARPSTEEL 674
|
||||
#define STRINGID_SHARPSTEELDISAPPEAREDFROMTEAM 675
|
||||
#define STRINGID_TEAMTRAPPEDWITHVINES 676
|
||||
#define STRINGID_PKMNHURTBYVINES 677
|
||||
#define STRINGID_TEAMCAUGHTINVORTEX 678
|
||||
#define STRINGID_PKMNHURTBYVORTEX 679
|
||||
#define STRINGID_TEAMSURROUNDEDBYFIRE 680
|
||||
#define STRINGID_PKMNBURNINGUP 681
|
||||
#define STRINGID_TEAMSURROUNDEDBYROCKS 682
|
||||
#define STRINGID_PKMNHURTBYROCKSTHROWN 683
|
||||
#define STRINGID_MOVEBLOCKEDBYDYNAMAX 684
|
||||
#define STRINGID_ZEROTOHEROTRANSFORMATION 685
|
||||
#define STRINGID_THETWOMOVESBECOMEONE 686
|
||||
#define STRINGID_ARAINBOWAPPEAREDONSIDE 687
|
||||
#define STRINGID_THERAINBOWDISAPPEARED 688
|
||||
#define STRINGID_WAITINGFORPARTNERSMOVE 689
|
||||
#define STRINGID_SEAOFFIREENVELOPEDSIDE 690
|
||||
#define STRINGID_HURTBYTHESEAOFFIRE 691
|
||||
#define STRINGID_THESEAOFFIREDISAPPEARED 692
|
||||
#define STRINGID_SWAMPENVELOPEDSIDE 693
|
||||
#define STRINGID_THESWAMPDISAPPEARED 694
|
||||
#define STRINGID_PKMNTELLCHILLINGRECEPTIONJOKE 695
|
||||
#define STRINGID_HOSPITALITYRESTORATION 696
|
||||
#define STRINGID_ELECTROSHOTCHARGING 697
|
||||
#define STRINGID_ITEMWASUSEDUP 698
|
||||
#define STRINGID_ATTACKERLOSTITSTYPE 699
|
||||
#define STRINGID_SHEDITSTAIL 700
|
||||
#define STRINGID_CLOAKEDINAHARSHLIGHT 701
|
||||
#define STRINGID_SUPERSWEETAROMAWAFTS 702
|
||||
#define STRINGID_DIMENSIONSWERETWISTED 703
|
||||
#define STRINGID_BIZARREARENACREATED 704
|
||||
#define STRINGID_BIZARREAREACREATED 705
|
||||
#define STRINGID_TIDYINGUPCOMPLETE 706
|
||||
#define STRINGID_PKMNTERASTALLIZEDINTO 707
|
||||
#define STRINGID_BOOSTERENERGYACTIVATES 708
|
||||
#define STRINGID_FOGCREPTUP 709
|
||||
#define STRINGID_FOGISDEEP 710
|
||||
#define STRINGID_FOGLIFTED 711
|
||||
#define STRINGID_PKMNMADESHELLGLEAM 712
|
||||
#define STRINGID_FICKLEBEAMDOUBLED 713
|
||||
#define STRINGID_ELECTRICTERRAINENDS 445
|
||||
#define STRINGID_MISTYTERRAINENDS 446
|
||||
#define STRINGID_PSYCHICTERRAINENDS 447
|
||||
#define STRINGID_GRASSYTERRAINENDS 448
|
||||
#define STRINGID_TARGETABILITYSTATRAISE 449
|
||||
#define STRINGID_TARGETSSTATWASMAXEDOUT 450
|
||||
#define STRINGID_ATTACKERABILITYSTATRAISE 451
|
||||
#define STRINGID_POISONHEALHPUP 452
|
||||
#define STRINGID_BADDREAMSDMG 453
|
||||
#define STRINGID_MOLDBREAKERENTERS 454
|
||||
#define STRINGID_TERAVOLTENTERS 455
|
||||
#define STRINGID_TURBOBLAZEENTERS 456
|
||||
#define STRINGID_SLOWSTARTENTERS 457
|
||||
#define STRINGID_SLOWSTARTEND 458
|
||||
#define STRINGID_SOLARPOWERHPDROP 459
|
||||
#define STRINGID_AFTERMATHDMG 460
|
||||
#define STRINGID_ANTICIPATIONACTIVATES 461
|
||||
#define STRINGID_FOREWARNACTIVATES 462
|
||||
#define STRINGID_ICEBODYHPGAIN 463
|
||||
#define STRINGID_SNOWWARNINGHAIL 464
|
||||
#define STRINGID_FRISKACTIVATES 465
|
||||
#define STRINGID_UNNERVEENTERS 466
|
||||
#define STRINGID_HARVESTBERRY 467
|
||||
#define STRINGID_LASTABILITYRAISEDSTAT 468
|
||||
#define STRINGID_MAGICBOUNCEACTIVATES 469
|
||||
#define STRINGID_PROTEANTYPECHANGE 470
|
||||
#define STRINGID_SYMBIOSISITEMPASS 471
|
||||
#define STRINGID_STEALTHROCKDMG 472
|
||||
#define STRINGID_TOXICSPIKESABSORBED 473
|
||||
#define STRINGID_TOXICSPIKESPOISONED 474
|
||||
#define STRINGID_STICKYWEBSWITCHIN 475
|
||||
#define STRINGID_HEALINGWISHCAMETRUE 476
|
||||
#define STRINGID_HEALINGWISHHEALED 477
|
||||
#define STRINGID_LUNARDANCECAMETRUE 478
|
||||
#define STRINGID_CUSEDBODYDISABLED 479
|
||||
#define STRINGID_ATTACKERACQUIREDABILITY 480
|
||||
#define STRINGID_TARGETABILITYSTATLOWER 481
|
||||
#define STRINGID_TARGETSTATWONTGOHIGHER 482
|
||||
#define STRINGID_PKMNMOVEBOUNCEDABILITY 483
|
||||
#define STRINGID_IMPOSTERTRANSFORM 484
|
||||
#define STRINGID_ASSAULTVESTDOESNTALLOW 485
|
||||
#define STRINGID_GRAVITYPREVENTSUSAGE 486
|
||||
#define STRINGID_HEALBLOCKPREVENTSUSAGE 487
|
||||
#define STRINGID_NOTDONEYET 488
|
||||
#define STRINGID_STICKYWEBUSED 489
|
||||
#define STRINGID_QUASHSUCCESS 490
|
||||
#define STRINGID_PKMNBLEWAWAYTOXICSPIKES 491
|
||||
#define STRINGID_PKMNBLEWAWAYSTICKYWEB 492
|
||||
#define STRINGID_PKMNBLEWAWAYSTEALTHROCK 493
|
||||
#define STRINGID_IONDELUGEON 494
|
||||
#define STRINGID_TOPSYTURVYSWITCHEDSTATS 495
|
||||
#define STRINGID_TERRAINBECOMESMISTY 496
|
||||
#define STRINGID_TERRAINBECOMESGRASSY 497
|
||||
#define STRINGID_TERRAINBECOMESELECTRIC 498
|
||||
#define STRINGID_TERRAINBECOMESPSYCHIC 499
|
||||
#define STRINGID_TARGETELECTRIFIED 500
|
||||
#define STRINGID_MEGAEVOREACTING 501
|
||||
#define STRINGID_MEGAEVOEVOLVED 502
|
||||
#define STRINGID_DRASTICALLY 503
|
||||
#define STRINGID_SEVERELY 504
|
||||
#define STRINGID_INFESTATION 505
|
||||
#define STRINGID_NOEFFECTONTARGET 506
|
||||
#define STRINGID_BURSTINGFLAMESHIT 507
|
||||
#define STRINGID_BESTOWITEMGIVING 508
|
||||
#define STRINGID_THIRDTYPEADDED 509
|
||||
#define STRINGID_FELLFORFEINT 510
|
||||
#define STRINGID_POKEMONCANNOTUSEMOVE 511
|
||||
#define STRINGID_COVEREDINPOWDER 512
|
||||
#define STRINGID_POWDEREXPLODES 513
|
||||
#define STRINGID_BELCHCANTSELECT 514
|
||||
#define STRINGID_SPECTRALTHIEFSTEAL 515
|
||||
#define STRINGID_GRAVITYGROUNDING 516
|
||||
#define STRINGID_MISTYTERRAINPREVENTS 517
|
||||
#define STRINGID_GRASSYTERRAINHEALS 518
|
||||
#define STRINGID_ELECTRICTERRAINPREVENTS 519
|
||||
#define STRINGID_PSYCHICTERRAINPREVENTS 520
|
||||
#define STRINGID_SAFETYGOGGLESPROTECTED 521
|
||||
#define STRINGID_FLOWERVEILPROTECTED 522
|
||||
#define STRINGID_SWEETVEILPROTECTED 523
|
||||
#define STRINGID_AROMAVEILPROTECTED 524
|
||||
#define STRINGID_CELEBRATEMESSAGE 525
|
||||
#define STRINGID_USEDINSTRUCTEDMOVE 526
|
||||
#define STRINGID_THROATCHOPENDS 527
|
||||
#define STRINGID_PKMNCANTUSEMOVETHROATCHOP 528
|
||||
#define STRINGID_LASERFOCUS 529
|
||||
#define STRINGID_GEMACTIVATES 530
|
||||
#define STRINGID_BERRYDMGREDUCES 531
|
||||
#define STRINGID_TARGETATEITEM 532
|
||||
#define STRINGID_AIRBALLOONFLOAT 533
|
||||
#define STRINGID_AIRBALLOONPOP 534
|
||||
#define STRINGID_INCINERATEBURN 535
|
||||
#define STRINGID_BUGBITE 536
|
||||
#define STRINGID_ILLUSIONWOREOFF 537
|
||||
#define STRINGID_ATTACKERCUREDTARGETSTATUS 538
|
||||
#define STRINGID_ATTACKERLOSTFIRETYPE 539
|
||||
#define STRINGID_HEALERCURE 540
|
||||
#define STRINGID_SCRIPTINGABILITYSTATRAISE 541
|
||||
#define STRINGID_RECEIVERABILITYTAKEOVER 542
|
||||
#define STRINGID_PKNMABSORBINGPOWER 543
|
||||
#define STRINGID_NOONEWILLBEABLETORUNAWAY 544
|
||||
#define STRINGID_DESTINYKNOTACTIVATES 545
|
||||
#define STRINGID_CLOAKEDINAFREEZINGLIGHT 546
|
||||
#define STRINGID_CLEARAMULETWONTLOWERSTATS 547
|
||||
#define STRINGID_FERVENTWISHREACHED 548
|
||||
#define STRINGID_AIRLOCKACTIVATES 549
|
||||
#define STRINGID_PRESSUREENTERS 550
|
||||
#define STRINGID_DARKAURAENTERS 551
|
||||
#define STRINGID_FAIRYAURAENTERS 552
|
||||
#define STRINGID_AURABREAKENTERS 553
|
||||
#define STRINGID_COMATOSEENTERS 554
|
||||
#define STRINGID_SCREENCLEANERENTERS 555
|
||||
#define STRINGID_FETCHEDPOKEBALL 556
|
||||
#define STRINGID_BATTLERABILITYRAISEDSTAT 557
|
||||
#define STRINGID_ASANDSTORMKICKEDUP 558
|
||||
#define STRINGID_PKMNSWILLPERISHIN3TURNS 559
|
||||
#define STRINGID_ABILITYRAISEDSTATDRASTICALLY 560
|
||||
#define STRINGID_AURAFLAREDTOLIFE 561
|
||||
#define STRINGID_ASONEENTERS 562
|
||||
#define STRINGID_CURIOUSMEDICINEENTERS 563
|
||||
#define STRINGID_CANACTFASTERTHANKSTO 564
|
||||
#define STRINGID_MICLEBERRYACTIVATES 565
|
||||
#define STRINGID_PKMNSHOOKOFFTHETAUNT 566
|
||||
#define STRINGID_PKMNGOTOVERITSINFATUATION 567
|
||||
#define STRINGID_ITEMCANNOTBEREMOVED 568
|
||||
#define STRINGID_STICKYBARBTRANSFER 569
|
||||
#define STRINGID_PKMNBURNHEALED 570
|
||||
#define STRINGID_REDCARDACTIVATE 571
|
||||
#define STRINGID_EJECTBUTTONACTIVATE 572
|
||||
#define STRINGID_ATKGOTOVERINFATUATION 573
|
||||
#define STRINGID_TORMENTEDNOMORE 574
|
||||
#define STRINGID_HEALBLOCKEDNOMORE 575
|
||||
#define STRINGID_ATTACKERBECAMEFULLYCHARGED 576
|
||||
#define STRINGID_ATTACKERBECAMEASHSPECIES 577
|
||||
#define STRINGID_EXTREMELYHARSHSUNLIGHT 578
|
||||
#define STRINGID_EXTREMESUNLIGHTFADED 579
|
||||
#define STRINGID_MOVEEVAPORATEDINTHEHARSHSUNLIGHT 580
|
||||
#define STRINGID_EXTREMELYHARSHSUNLIGHTWASNOTLESSENED 581
|
||||
#define STRINGID_HEAVYRAIN 582
|
||||
#define STRINGID_HEAVYRAINLIFTED 583
|
||||
#define STRINGID_MOVEFIZZLEDOUTINTHEHEAVYRAIN 584
|
||||
#define STRINGID_NORELIEFROMHEAVYRAIN 585
|
||||
#define STRINGID_MYSTERIOUSAIRCURRENT 586
|
||||
#define STRINGID_STRONGWINDSDISSIPATED 587
|
||||
#define STRINGID_MYSTERIOUSAIRCURRENTBLOWSON 588
|
||||
#define STRINGID_ATTACKWEAKENEDBSTRONGWINDS 589
|
||||
#define STRINGID_STUFFCHEEKSCANTSELECT 590
|
||||
#define STRINGID_PKMNREVERTEDTOPRIMAL 591
|
||||
#define STRINGID_BUTPOKEMONCANTUSETHEMOVE 592
|
||||
#define STRINGID_BUTHOOPACANTUSEIT 593
|
||||
#define STRINGID_BROKETHROUGHPROTECTION 594
|
||||
#define STRINGID_ABILITYALLOWSONLYMOVE 595
|
||||
#define STRINGID_SWAPPEDABILITIES 596
|
||||
#define STRINGID_PASTELVEILPROTECTED 597
|
||||
#define STRINGID_PASTELVEILENTERS 598
|
||||
#define STRINGID_BATTLERTYPECHANGEDTO 599
|
||||
#define STRINGID_BOTHCANNOLONGERESCAPE 600
|
||||
#define STRINGID_CANTESCAPEDUETOUSEDMOVE 601
|
||||
#define STRINGID_PKMNBECAMEWEAKERTOFIRE 602
|
||||
#define STRINGID_ABOUTTOUSEPOLTERGEIST 603
|
||||
#define STRINGID_CANTESCAPEBECAUSEOFCURRENTMOVE 604
|
||||
#define STRINGID_NEUTRALIZINGGASENTERS 605
|
||||
#define STRINGID_NEUTRALIZINGGASOVER 606
|
||||
#define STRINGID_TARGETTOOHEAVY 607
|
||||
#define STRINGID_PKMNTOOKTARGETHIGH 608
|
||||
#define STRINGID_PKMNINSNAPTRAP 609
|
||||
#define STRINGID_METEORBEAMCHARGING 610
|
||||
#define STRINGID_HEATUPBEAK 611
|
||||
#define STRINGID_COURTCHANGE 612
|
||||
#define STRINGID_PLAYERLOSTTOENEMYTRAINER 613
|
||||
#define STRINGID_PLAYERPAIDPRIZEMONEY 614
|
||||
#define STRINGID_ZPOWERSURROUNDS 615
|
||||
#define STRINGID_ZMOVEUNLEASHED 616
|
||||
#define STRINGID_ZMOVERESETSSTATS 617
|
||||
#define STRINGID_ZMOVEALLSTATSUP 618
|
||||
#define STRINGID_ZMOVEZBOOSTCRIT 619
|
||||
#define STRINGID_ZMOVERESTOREHP 620
|
||||
#define STRINGID_ZMOVESTATUP 621
|
||||
#define STRINGID_ZMOVEHPTRAP 622
|
||||
#define STRINGID_ATTACKEREXPELLEDTHEPOISON 623
|
||||
#define STRINGID_ATTACKERSHOOKITSELFAWAKE 624
|
||||
#define STRINGID_ATTACKERBROKETHROUGHPARALYSIS 625
|
||||
#define STRINGID_ATTACKERHEALEDITSBURN 626
|
||||
#define STRINGID_ATTACKERMELTEDTHEICE 627
|
||||
#define STRINGID_TARGETTOUGHEDITOUT 628
|
||||
#define STRINGID_ATTACKERLOSTELECTRICTYPE 629
|
||||
#define STRINGID_ATTACKERSWITCHEDSTATWITHTARGET 630
|
||||
#define STRINGID_BEINGHITCHARGEDPKMNWITHPOWER 631
|
||||
#define STRINGID_SUNLIGHTACTIVATEDABILITY 632
|
||||
#define STRINGID_STATWASHEIGHTENED 633
|
||||
#define STRINGID_ELECTRICTERRAINACTIVATEDABILITY 634
|
||||
#define STRINGID_ABILITYWEAKENEDSURROUNDINGMONSSTAT 635
|
||||
#define STRINGID_ATTACKERGAINEDSTRENGTHFROMTHEFALLEN 636
|
||||
#define STRINGID_PKMNSABILITYPREVENTSABILITY 637
|
||||
#define STRINGID_PREPARESHELLTRAP 638
|
||||
#define STRINGID_SHELLTRAPDIDNTWORK 639
|
||||
#define STRINGID_SPIKESDISAPPEAREDFROMTEAM 640
|
||||
#define STRINGID_TOXICSPIKESDISAPPEAREDFROMTEAM 641
|
||||
#define STRINGID_STICKYWEBDISAPPEAREDFROMTEAM 642
|
||||
#define STRINGID_STEALTHROCKDISAPPEAREDFROMTEAM 643
|
||||
#define STRINGID_COULDNTFULLYPROTECT 644
|
||||
#define STRINGID_STOCKPILEDEFFECTWOREOFF 645
|
||||
#define STRINGID_PKMNREVIVEDREADYTOFIGHT 646
|
||||
#define STRINGID_ITEMRESTOREDSPECIESHEALTH 647
|
||||
#define STRINGID_ITEMCUREDSPECIESSTATUS 648
|
||||
#define STRINGID_ITEMRESTOREDSPECIESPP 649
|
||||
#define STRINGID_THUNDERCAGETRAPPED 650
|
||||
#define STRINGID_PKMNHURTBYFROSTBITE 651
|
||||
#define STRINGID_PKMNGOTFROSTBITE 652
|
||||
#define STRINGID_PKMNSITEMHEALEDFROSTBITE 653
|
||||
#define STRINGID_ATTACKERHEALEDITSFROSTBITE 654
|
||||
#define STRINGID_PKMNFROSTBITEHEALED 655
|
||||
#define STRINGID_PKMNFROSTBITEHEALED2 656
|
||||
#define STRINGID_PKMNFROSTBITEHEALEDBY 657
|
||||
#define STRINGID_MIRRORHERBCOPIED 658
|
||||
#define STRINGID_STARTEDSNOW 659
|
||||
#define STRINGID_SNOWCONTINUES 660
|
||||
#define STRINGID_SNOWSTOPPED 661
|
||||
#define STRINGID_SNOWWARNINGSNOW 662
|
||||
#define STRINGID_PKMNITEMMELTED 663
|
||||
#define STRINGID_ULTRABURSTREACTING 664
|
||||
#define STRINGID_ULTRABURSTCOMPLETED 665
|
||||
#define STRINGID_TEAMGAINEDEXP 666
|
||||
#define STRINGID_CURRENTMOVECANTSELECT 667
|
||||
#define STRINGID_TARGETISBEINGSALTCURED 668
|
||||
#define STRINGID_TARGETISHURTBYSALTCURE 669
|
||||
#define STRINGID_TARGETCOVEREDINSTICKYCANDYSYRUP 670
|
||||
#define STRINGID_SHARPSTEELFLOATS 671
|
||||
#define STRINGID_SHARPSTEELDMG 672
|
||||
#define STRINGID_PKMNBLEWAWAYSHARPSTEEL 673
|
||||
#define STRINGID_SHARPSTEELDISAPPEAREDFROMTEAM 674
|
||||
#define STRINGID_TEAMTRAPPEDWITHVINES 675
|
||||
#define STRINGID_PKMNHURTBYVINES 676
|
||||
#define STRINGID_TEAMCAUGHTINVORTEX 677
|
||||
#define STRINGID_PKMNHURTBYVORTEX 678
|
||||
#define STRINGID_TEAMSURROUNDEDBYFIRE 679
|
||||
#define STRINGID_PKMNBURNINGUP 680
|
||||
#define STRINGID_TEAMSURROUNDEDBYROCKS 681
|
||||
#define STRINGID_PKMNHURTBYROCKSTHROWN 682
|
||||
#define STRINGID_MOVEBLOCKEDBYDYNAMAX 683
|
||||
#define STRINGID_ZEROTOHEROTRANSFORMATION 684
|
||||
#define STRINGID_THETWOMOVESBECOMEONE 685
|
||||
#define STRINGID_ARAINBOWAPPEAREDONSIDE 686
|
||||
#define STRINGID_THERAINBOWDISAPPEARED 687
|
||||
#define STRINGID_WAITINGFORPARTNERSMOVE 688
|
||||
#define STRINGID_SEAOFFIREENVELOPEDSIDE 689
|
||||
#define STRINGID_HURTBYTHESEAOFFIRE 690
|
||||
#define STRINGID_THESEAOFFIREDISAPPEARED 691
|
||||
#define STRINGID_SWAMPENVELOPEDSIDE 692
|
||||
#define STRINGID_THESWAMPDISAPPEARED 693
|
||||
#define STRINGID_PKMNTELLCHILLINGRECEPTIONJOKE 694
|
||||
#define STRINGID_HOSPITALITYRESTORATION 695
|
||||
#define STRINGID_ELECTROSHOTCHARGING 696
|
||||
#define STRINGID_ITEMWASUSEDUP 697
|
||||
#define STRINGID_ATTACKERLOSTITSTYPE 698
|
||||
#define STRINGID_SHEDITSTAIL 699
|
||||
#define STRINGID_CLOAKEDINAHARSHLIGHT 700
|
||||
#define STRINGID_SUPERSWEETAROMAWAFTS 701
|
||||
#define STRINGID_DIMENSIONSWERETWISTED 702
|
||||
#define STRINGID_BIZARREARENACREATED 703
|
||||
#define STRINGID_BIZARREAREACREATED 704
|
||||
#define STRINGID_TIDYINGUPCOMPLETE 705
|
||||
#define STRINGID_PKMNTERASTALLIZEDINTO 706
|
||||
#define STRINGID_BOOSTERENERGYACTIVATES 707
|
||||
#define STRINGID_FOGCREPTUP 708
|
||||
#define STRINGID_FOGISDEEP 709
|
||||
#define STRINGID_FOGLIFTED 710
|
||||
#define STRINGID_PKMNMADESHELLGLEAM 711
|
||||
#define STRINGID_FICKLEBEAMDOUBLED 712
|
||||
|
||||
#define BATTLESTRINGS_COUNT 714
|
||||
#define BATTLESTRINGS_COUNT 713
|
||||
|
||||
// This is the string id that gBattleStringsTable starts with.
|
||||
// String ids before this (e.g. STRINGID_INTROMSG) are not in the table,
|
||||
|
||||
@ -3,10 +3,10 @@
|
||||
* To run all the tests use:
|
||||
* make check -j
|
||||
* To run specific tests, e.g. Spikes ones, use:
|
||||
* make check TESTS='Spikes'
|
||||
* make check TESTS="Spikes"
|
||||
* To build a ROM (pokemerald-test.elf) that can be opened in mgba to
|
||||
* view specific tests, e.g. Spikes ones, use:
|
||||
* make pokeemerald-test.elf TESTS='Spikes'
|
||||
* make pokeemerald-test.elf TESTS="Spikes"
|
||||
*
|
||||
* Manually testing a battle mechanic often follows this pattern:
|
||||
* 1. Create a party which can activate the mechanic.
|
||||
@ -55,7 +55,7 @@
|
||||
* start with the same prefix, e.g. Stun Spore tests should start with
|
||||
* "Stun Spore", this allows just the Stun Spore-related tests to be run
|
||||
* with:
|
||||
* make check TESTS='Stun Spore'
|
||||
* make check TESTS="Stun Spore"
|
||||
*
|
||||
* GIVEN initializes the parties, PLAYER and OPPONENT add a Pokémon to
|
||||
* their respective parties. They can both accept a block which further
|
||||
|
||||
@ -3996,6 +3996,12 @@ $(POKEMONGFXDIR)/exeggutor/alolan/overworld.4bpp: %.4bpp: %.png
|
||||
$(POKEMONGFXDIR)/marowak/alolan/overworld.4bpp: %.4bpp: %.png
|
||||
$(GFX) $< $@ -mwidth 4 -mheight 4
|
||||
|
||||
$(POKEMONGFXDIR)/wooper/wooper_paldean/overworld.4bpp: %.4bpp: %.png
|
||||
$(GFX) $< $@ -mwidth 4 -mheight 4
|
||||
|
||||
$(POKEMONGFXDIR)/clodsire/overworld.4bpp: %.4bpp: %.png
|
||||
$(GFX) $< $@ -mwidth 4 -mheight 4
|
||||
|
||||
$(MISCGFXDIR)/emotes.4bpp: %.4bpp: %.png
|
||||
$(GFX) $< $@ -mwidth 2 -mheight 2
|
||||
|
||||
|
||||
@ -857,6 +857,8 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
case EFFECT_COUNTER:
|
||||
case EFFECT_MIRROR_COAT:
|
||||
case EFFECT_METAL_BURST:
|
||||
case EFFECT_FINAL_GAMBIT:
|
||||
case EFFECT_GUARDIAN_OF_ALOLA:
|
||||
break;
|
||||
default:
|
||||
RETURN_SCORE_MINUS(10);
|
||||
@ -1531,6 +1533,16 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
else if (HasSubstituteIgnoringMove(battlerDef))
|
||||
ADJUST_SCORE(-8);
|
||||
break;
|
||||
case EFFECT_SHED_TAIL:
|
||||
if (CountUsablePartyMons(battlerAtk) == 0)
|
||||
ADJUST_SCORE(-10);
|
||||
if (gBattleMons[battlerAtk].status2 & STATUS2_SUBSTITUTE || aiData->abilities[battlerDef] == ABILITY_INFILTRATOR)
|
||||
ADJUST_SCORE(-8);
|
||||
else if (aiData->hpPercents[battlerAtk] <= 50)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (HasSubstituteIgnoringMove(battlerDef))
|
||||
ADJUST_SCORE(-8);
|
||||
break;
|
||||
case EFFECT_LEECH_SEED:
|
||||
if (gStatuses3[battlerDef] & STATUS3_LEECHSEED
|
||||
|| IS_BATTLER_OF_TYPE(battlerDef, TYPE_GRASS)
|
||||
@ -1818,6 +1830,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
break;
|
||||
case EFFECT_TRICK:
|
||||
case EFFECT_KNOCK_OFF:
|
||||
case EFFECT_CORROSIVE_GAS:
|
||||
if (aiData->abilities[battlerDef] == ABILITY_STICKY_HOLD)
|
||||
ADJUST_SCORE(-10);
|
||||
break;
|
||||
@ -2166,6 +2179,17 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
else if (IsAbilityOfRating(aiData->abilities[battlerAtk], 5))
|
||||
ADJUST_SCORE(-4);
|
||||
break;
|
||||
case EFFECT_DOODLE: // Same as Role Play, but also check if the partner's ability should be replaced
|
||||
if (aiData->abilities[battlerAtk] == aiData->abilities[battlerDef]
|
||||
|| aiData->abilities[BATTLE_PARTNER(battlerAtk)] == aiData->abilities[battlerDef]
|
||||
|| aiData->abilities[battlerDef] == ABILITY_NONE
|
||||
|| gAbilitiesInfo[aiData->abilities[battlerAtk]].cantBeSuppressed
|
||||
|| gAbilitiesInfo[aiData->abilities[BATTLE_PARTNER(battlerAtk)]].cantBeSuppressed
|
||||
|| gAbilitiesInfo[aiData->abilities[battlerDef]].cantBeCopied)
|
||||
ADJUST_SCORE(-10);
|
||||
else if (IsAbilityOfRating(aiData->abilities[battlerAtk], 5) || IsAbilityOfRating(aiData->abilities[BATTLE_PARTNER(battlerAtk)], 5))
|
||||
ADJUST_SCORE(-4);
|
||||
break;
|
||||
case EFFECT_WISH:
|
||||
if (gWishFutureKnock.wishCounter[battlerAtk] != 0)
|
||||
ADJUST_SCORE(-10);
|
||||
@ -2878,6 +2902,15 @@ static s32 AI_DoubleBattle(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
||||
{
|
||||
switch (atkPartnerAbility)
|
||||
{
|
||||
case ABILITY_ANGER_POINT:
|
||||
if (gMovesInfo[move].alwaysCriticalHit == TRUE
|
||||
&& BattlerStatCanRise(battlerAtkPartner, atkPartnerAbility, STAT_ATK)
|
||||
&& AI_IsFaster(battlerAtk, battlerAtkPartner, move)
|
||||
&& !CanIndexMoveFaintTarget(battlerAtk, battlerAtkPartner, AI_THINKING_STRUCT->movesetIndex, 1))
|
||||
{
|
||||
RETURN_SCORE_PLUS(GOOD_EFFECT);
|
||||
}
|
||||
break;
|
||||
case ABILITY_VOLT_ABSORB:
|
||||
if (!(AI_THINKING_STRUCT->aiFlags[battlerAtk] & AI_FLAG_HP_AWARE))
|
||||
{
|
||||
@ -3479,6 +3512,7 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
break;
|
||||
case EFFECT_MULTI_HIT:
|
||||
case EFFECT_TRIPLE_KICK:
|
||||
case EFFECT_POPULATION_BOMB:
|
||||
if (AI_MoveMakesContact(aiData->abilities[battlerAtk], aiData->holdEffects[battlerAtk], move)
|
||||
&& aiData->abilities[battlerAtk] != ABILITY_MAGIC_GUARD
|
||||
&& aiData->holdEffects[battlerDef] == HOLD_EFFECT_ROCKY_HELMET)
|
||||
@ -3582,28 +3616,8 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
IncreaseParalyzeScore(battlerAtk, battlerDef, move, &score);
|
||||
break;
|
||||
case EFFECT_SUBSTITUTE:
|
||||
if (HasAnyKnownMove(battlerDef) && GetBestDmgFromBattler(battlerDef, battlerAtk) < gBattleMons[battlerAtk].maxHP / 4)
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
if (gStatuses3[battlerDef] & STATUS3_PERISH_SONG)
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_SLEEP)
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
else if (gBattleMons[battlerDef].status1 & (STATUS1_BURN | STATUS1_PSN_ANY | STATUS1_FROSTBITE))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
// TODO:
|
||||
// if (IsPredictedToSwitch(battlerDef, battlerAtk)
|
||||
// ADJUST_SCORE(DECENT_EFFECT);
|
||||
if (HasMoveEffect(battlerDef, EFFECT_SLEEP)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_TOXIC)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_POISON)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_PARALYZE)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_WILL_O_WISP)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_CONFUSE)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_LEECH_SEED))
|
||||
ADJUST_SCORE(GOOD_EFFECT);
|
||||
if (!gBattleMons[battlerDef].status2 & (STATUS2_WRAPPED | STATUS2_ESCAPE_PREVENTION && aiData->hpPercents[battlerAtk] > 70))
|
||||
ADJUST_SCORE(WEAK_EFFECT);
|
||||
break;
|
||||
case EFFECT_SHED_TAIL:
|
||||
IncreaseSubstituteMoveScore(battlerAtk, battlerDef, move, &score);
|
||||
case EFFECT_MIMIC:
|
||||
if (AI_IsFaster(battlerAtk, battlerDef, move))
|
||||
{
|
||||
@ -4099,11 +4113,27 @@ static u32 AI_CalcMoveEffectScore(u32 battlerAtk, u32 battlerDef, u32 move)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EFFECT_CORROSIVE_GAS:
|
||||
if (CanKnockOffItem(battlerDef, aiData->items[battlerDef]))
|
||||
{
|
||||
switch (aiData->holdEffects[battlerDef])
|
||||
{
|
||||
case HOLD_EFFECT_IRON_BALL:
|
||||
if (HasMoveEffect(battlerDef, EFFECT_FLING))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case HOLD_EFFECT_LAGGING_TAIL:
|
||||
case HOLD_EFFECT_STICKY_BARB:
|
||||
break;
|
||||
default:
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EFFECT_ROLE_PLAY:
|
||||
if (!gAbilitiesInfo[aiData->abilities[battlerAtk]].cantBeSuppressed
|
||||
&& !gAbilitiesInfo[aiData->abilities[battlerDef]].cantBeCopied
|
||||
&& !IsAbilityOfRating(aiData->abilities[battlerAtk], 5)
|
||||
&& IsAbilityOfRating(aiData->abilities[battlerDef], 5))
|
||||
case EFFECT_DOODLE:
|
||||
if (IsAbilityOfRating(aiData->abilities[battlerDef], 5))
|
||||
ADJUST_SCORE(DECENT_EFFECT);
|
||||
break;
|
||||
case EFFECT_INGRAIN:
|
||||
|
||||
@ -71,11 +71,11 @@ void GetAIPartyIndexes(u32 battler, s32 *firstId, s32 *lastId)
|
||||
static bool32 HasBadOdds(u32 battler, bool32 emitResult)
|
||||
{
|
||||
//Variable initialization
|
||||
u8 opposingPosition, atkType1, atkType2, defType1, defType2, effectiveness;
|
||||
u8 opposingPosition, atkType1, atkType2, defType1, defType2, effectiveness;
|
||||
s32 i, damageDealt = 0, maxDamageDealt = 0, damageTaken = 0, maxDamageTaken = 0;
|
||||
u32 aiMove, playerMove, aiBestMove = MOVE_NONE, aiAbility = AI_DATA->abilities[battler], opposingBattler, weather = AI_GetWeather(AI_DATA);
|
||||
bool32 getsOneShot = FALSE, hasStatusMove = FALSE, hasSuperEffectiveMove = FALSE;
|
||||
u16 typeEffectiveness = UQ_4_12(1.0), aiMoveEffect; //baseline typing damage
|
||||
u16 typeEffectiveness = UQ_4_12(1.0), aiMoveEffect; //baseline typing damage
|
||||
|
||||
// Only use this if AI_FLAG_SMART_SWITCHING is set for the trainer
|
||||
if (!(AI_THINKING_STRUCT->aiFlags[battler] & AI_FLAG_SMART_SWITCHING))
|
||||
@ -85,14 +85,14 @@ static bool32 HasBadOdds(u32 battler, bool32 emitResult)
|
||||
if (IsDoubleBattle())
|
||||
return FALSE;
|
||||
|
||||
opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(battler));
|
||||
opposingPosition = BATTLE_OPPOSITE(GetBattlerPosition(battler));
|
||||
opposingBattler = GetBattlerAtPosition(opposingPosition);
|
||||
|
||||
// Gets types of player (opposingBattler) and computer (battler)
|
||||
atkType1 = gBattleMons[opposingBattler].types[0];
|
||||
atkType2 = gBattleMons[opposingBattler].types[1];
|
||||
defType1 = gBattleMons[battler].types[0];
|
||||
defType2 = gBattleMons[battler].types[1];
|
||||
atkType1 = gBattleMons[opposingBattler].types[0];
|
||||
atkType2 = gBattleMons[opposingBattler].types[1];
|
||||
defType1 = gBattleMons[battler].types[0];
|
||||
defType2 = gBattleMons[battler].types[1];
|
||||
|
||||
// Check AI moves for damage dealt
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
@ -191,13 +191,13 @@ static bool32 HasBadOdds(u32 battler, bool32 emitResult)
|
||||
}
|
||||
|
||||
// General bad type matchups have more wiggle room
|
||||
if (typeEffectiveness >= UQ_4_12(2.0)) // If the player has at least a 2x type advantage
|
||||
{
|
||||
if (!hasSuperEffectiveMove // If the AI doesn't have a super effective move
|
||||
&& (gBattleMons[battler].hp >= gBattleMons[battler].maxHP / 2 // And the current mon has at least 1/2 their HP, or 1/4 HP and Regenerator
|
||||
if (typeEffectiveness >= UQ_4_12(2.0)) // If the player has at least a 2x type advantage
|
||||
{
|
||||
if (!hasSuperEffectiveMove // If the AI doesn't have a super effective move
|
||||
&& (gBattleMons[battler].hp >= gBattleMons[battler].maxHP / 2 // And the current mon has at least 1/2 their HP, or 1/4 HP and Regenerator
|
||||
|| (aiAbility == ABILITY_REGENERATOR
|
||||
&& gBattleMons[battler].hp >= gBattleMons[battler].maxHP / 4)))
|
||||
{
|
||||
{
|
||||
// Then check if they have an important status move, which is worth using even in a bad matchup
|
||||
if (hasStatusMove)
|
||||
return FALSE;
|
||||
@ -207,13 +207,13 @@ static bool32 HasBadOdds(u32 battler, bool32 emitResult)
|
||||
return FALSE;
|
||||
|
||||
// Switch mon out
|
||||
gBattleStruct->AI_monToSwitchIntoId[battler] = PARTY_SIZE;
|
||||
if (emitResult)
|
||||
gBattleStruct->AI_monToSwitchIntoId[battler] = PARTY_SIZE;
|
||||
if (emitResult)
|
||||
BtlController_EmitTwoReturnValues(battler, 1, B_ACTION_SWITCH, 0);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static bool32 ShouldSwitchIfAllBadMoves(u32 battler, bool32 emitResult)
|
||||
@ -2002,7 +2002,7 @@ static u32 GetBestMonIntegrated(struct Pokemon *party, int firstId, int lastId,
|
||||
}
|
||||
// If ace mon is the last available Pokemon and U-Turn/Volt Switch was used - switch to the mon.
|
||||
if (aceMonId != PARTY_SIZE
|
||||
&& (gMovesInfo[gLastUsedMove].effect == EFFECT_HIT_ESCAPE || gMovesInfo[gLastUsedMove].effect == EFFECT_PARTING_SHOT || gMovesInfo[gLastUsedMove].effect == EFFECT_BATON_PASS || gMovesInfo[gLastUsedMove].effect == EFFECT_CHILLY_RECEPTION))
|
||||
&& (gMovesInfo[gLastUsedMove].effect == EFFECT_HIT_ESCAPE || gMovesInfo[gLastUsedMove].effect == EFFECT_PARTING_SHOT || gMovesInfo[gLastUsedMove].effect == EFFECT_BATON_PASS || gMovesInfo[gLastUsedMove].effect == EFFECT_CHILLY_RECEPTION || gMovesInfo[gLastUsedMove].effect == EFFECT_SHED_TAIL))
|
||||
return aceMonId;
|
||||
|
||||
return PARTY_SIZE;
|
||||
|
||||
@ -2196,7 +2196,7 @@ bool32 IsAttackBoostMoveEffect(u32 effect)
|
||||
switch (effect)
|
||||
{
|
||||
case EFFECT_ATTACK_UP:
|
||||
case EFFECT_ATTACK_UP_2:
|
||||
case EFFECT_ATTACK_UP_2:
|
||||
case EFFECT_ATTACK_ACCURACY_UP:
|
||||
case EFFECT_ATTACK_SPATK_UP:
|
||||
case EFFECT_DRAGON_DANCE:
|
||||
@ -2216,34 +2216,34 @@ bool32 IsStatRaisingEffect(u32 effect)
|
||||
switch (effect)
|
||||
{
|
||||
case EFFECT_ATTACK_UP:
|
||||
case EFFECT_ATTACK_UP_2:
|
||||
case EFFECT_DEFENSE_UP:
|
||||
case EFFECT_DEFENSE_UP_2:
|
||||
case EFFECT_ATTACK_UP_2:
|
||||
case EFFECT_DEFENSE_UP:
|
||||
case EFFECT_DEFENSE_UP_2:
|
||||
case EFFECT_DEFENSE_UP_3:
|
||||
case EFFECT_SPEED_UP:
|
||||
case EFFECT_SPEED_UP_2:
|
||||
case EFFECT_SPECIAL_ATTACK_UP:
|
||||
case EFFECT_SPECIAL_ATTACK_UP_2:
|
||||
case EFFECT_SPEED_UP:
|
||||
case EFFECT_SPEED_UP_2:
|
||||
case EFFECT_SPECIAL_ATTACK_UP:
|
||||
case EFFECT_SPECIAL_ATTACK_UP_2:
|
||||
case EFFECT_SPECIAL_ATTACK_UP_3:
|
||||
case EFFECT_SPECIAL_DEFENSE_UP:
|
||||
case EFFECT_SPECIAL_DEFENSE_UP_2:
|
||||
case EFFECT_SPECIAL_DEFENSE_UP:
|
||||
case EFFECT_SPECIAL_DEFENSE_UP_2:
|
||||
case EFFECT_ACCURACY_UP:
|
||||
case EFFECT_ACCURACY_UP_2:
|
||||
case EFFECT_EVASION_UP:
|
||||
case EFFECT_EVASION_UP_2:
|
||||
case EFFECT_MINIMIZE:
|
||||
case EFFECT_DEFENSE_CURL:
|
||||
case EFFECT_CALM_MIND:
|
||||
case EFFECT_CALM_MIND:
|
||||
case EFFECT_COSMIC_POWER:
|
||||
case EFFECT_DRAGON_DANCE:
|
||||
case EFFECT_ACUPRESSURE:
|
||||
case EFFECT_SHELL_SMASH:
|
||||
case EFFECT_SHIFT_GEAR:
|
||||
case EFFECT_ATTACK_ACCURACY_UP:
|
||||
case EFFECT_ATTACK_SPATK_UP:
|
||||
case EFFECT_GROWTH:
|
||||
case EFFECT_COIL:
|
||||
case EFFECT_QUIVER_DANCE:
|
||||
case EFFECT_DRAGON_DANCE:
|
||||
case EFFECT_ACUPRESSURE:
|
||||
case EFFECT_SHELL_SMASH:
|
||||
case EFFECT_SHIFT_GEAR:
|
||||
case EFFECT_ATTACK_ACCURACY_UP:
|
||||
case EFFECT_ATTACK_SPATK_UP:
|
||||
case EFFECT_GROWTH:
|
||||
case EFFECT_COIL:
|
||||
case EFFECT_QUIVER_DANCE:
|
||||
case EFFECT_BULK_UP:
|
||||
case EFFECT_GEOMANCY:
|
||||
case EFFECT_STOCKPILE:
|
||||
@ -3987,3 +3987,42 @@ bool32 AI_ShouldSpicyExtract(u32 battlerAtk, u32 battlerAtkPartner, u32 move, st
|
||||
&& AI_IsFaster(battlerAtk, battlerAtkPartner, TRUE)
|
||||
&& HasMoveWithCategory(battlerAtkPartner, DAMAGE_CATEGORY_PHYSICAL));
|
||||
}
|
||||
|
||||
void IncreaseSubstituteMoveScore(u32 battlerAtk, u32 battlerDef, u32 move, s32 *score)
|
||||
{
|
||||
if (gMovesInfo[move].effect == EFFECT_SUBSTITUTE) // Substitute specific
|
||||
{
|
||||
if (HasAnyKnownMove(battlerDef) && GetBestDmgFromBattler(battlerDef, battlerAtk) < gBattleMons[battlerAtk].maxHP / 4)
|
||||
ADJUST_SCORE_PTR(GOOD_EFFECT);
|
||||
}
|
||||
else if (gMovesInfo[move].effect == EFFECT_SHED_TAIL) // Shed Tail specific
|
||||
{
|
||||
if ((ShouldPivot(battlerAtk, battlerDef, AI_DATA->abilities[battlerDef], move, AI_THINKING_STRUCT->movesetIndex))
|
||||
&& (HasAnyKnownMove(battlerDef) && (GetBestDmgFromBattler(battlerDef, battlerAtk) < gBattleMons[battlerAtk].maxHP / 2)))
|
||||
ADJUST_SCORE_PTR(BEST_EFFECT);
|
||||
}
|
||||
|
||||
if (gStatuses3[battlerDef] & STATUS3_PERISH_SONG)
|
||||
ADJUST_SCORE_PTR(GOOD_EFFECT);
|
||||
|
||||
if (gBattleMons[battlerDef].status1 & STATUS1_SLEEP)
|
||||
ADJUST_SCORE_PTR(GOOD_EFFECT);
|
||||
else if (gBattleMons[battlerDef].status1 & (STATUS1_BURN | STATUS1_PSN_ANY | STATUS1_FROSTBITE))
|
||||
ADJUST_SCORE_PTR(DECENT_EFFECT);
|
||||
|
||||
// TODO:
|
||||
// if (IsPredictedToSwitch(battlerDef, battlerAtk)
|
||||
// ADJUST_SCORE_PTR(DECENT_EFFECT);
|
||||
|
||||
if (HasMoveEffect(battlerDef, EFFECT_SLEEP)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_TOXIC)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_POISON)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_PARALYZE)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_WILL_O_WISP)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_CONFUSE)
|
||||
|| HasMoveEffect(battlerDef, EFFECT_LEECH_SEED))
|
||||
ADJUST_SCORE_PTR(GOOD_EFFECT);
|
||||
|
||||
if (AI_DATA->hpPercents[battlerAtk] > 70)
|
||||
ADJUST_SCORE_PTR(WEAK_EFFECT);
|
||||
}
|
||||
|
||||
@ -627,36 +627,36 @@ static void AnimOverheatFlame_Step(struct Sprite *sprite)
|
||||
|
||||
void AnimDracoMeteorRock(struct Sprite *sprite)
|
||||
{
|
||||
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
|
||||
{
|
||||
sprite->data[0] = sprite->x - gBattleAnimArgs[0];
|
||||
sprite->data[2] = sprite->x - gBattleAnimArgs[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite->data[0] = sprite->x + gBattleAnimArgs[0];
|
||||
sprite->data[2] = sprite->x + gBattleAnimArgs[2];
|
||||
}
|
||||
if (GetBattlerSide(gBattleAnimTarget) == B_SIDE_PLAYER)
|
||||
{
|
||||
sprite->data[0] = sprite->x - gBattleAnimArgs[0];
|
||||
sprite->data[2] = sprite->x - gBattleAnimArgs[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
sprite->data[0] = sprite->x + gBattleAnimArgs[0];
|
||||
sprite->data[2] = sprite->x + gBattleAnimArgs[2];
|
||||
}
|
||||
|
||||
sprite->data[1] = sprite->y + gBattleAnimArgs[1];
|
||||
sprite->data[3] = sprite->y + gBattleAnimArgs[3];
|
||||
sprite->data[4] = gBattleAnimArgs[4];
|
||||
sprite->data[1] = sprite->y + gBattleAnimArgs[1];
|
||||
sprite->data[3] = sprite->y + gBattleAnimArgs[3];
|
||||
sprite->data[4] = gBattleAnimArgs[4];
|
||||
|
||||
sprite->data[6] = gBattleAnimArgs[2];
|
||||
sprite->data[7] = gBattleAnimArgs[3];
|
||||
sprite->data[6] = gBattleAnimArgs[2];
|
||||
sprite->data[7] = gBattleAnimArgs[3];
|
||||
|
||||
sprite->x = sprite->data[0];
|
||||
sprite->y = sprite->data[1];
|
||||
sprite->callback = AnimDracoMeteorRock_Step;
|
||||
sprite->x = sprite->data[0];
|
||||
sprite->y = sprite->data[1];
|
||||
sprite->callback = AnimDracoMeteorRock_Step;
|
||||
}
|
||||
|
||||
static void AnimDracoMeteorRock_Step(struct Sprite *sprite)
|
||||
{
|
||||
sprite->x2 = ((sprite->data[2] - sprite->data[0]) * sprite->data[5]) / sprite->data[4];
|
||||
sprite->y2 = ((sprite->data[3] - sprite->data[1]) * sprite->data[5]) / sprite->data[4];
|
||||
sprite->x2 = ((sprite->data[2] - sprite->data[0]) * sprite->data[5]) / sprite->data[4];
|
||||
sprite->y2 = ((sprite->data[3] - sprite->data[1]) * sprite->data[5]) / sprite->data[4];
|
||||
|
||||
if (sprite->data[5] == sprite->data[4])
|
||||
DestroyAnimSprite(sprite);
|
||||
if (sprite->data[5] == sprite->data[4])
|
||||
DestroyAnimSprite(sprite);
|
||||
|
||||
sprite->data[5]++;
|
||||
sprite->data[5]++;
|
||||
}
|
||||
|
||||
@ -2535,13 +2535,13 @@ const struct SpriteTemplate gTauntFingerSpriteTemplate =
|
||||
|
||||
const struct SpriteTemplate gPowerOrbs_Float =
|
||||
{
|
||||
.tileTag = ANIM_TAG_RED_ORB,
|
||||
.paletteTag = ANIM_TAG_RED_ORB,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_16x16,
|
||||
.anims = gSporeParticleAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimSporeParticle,
|
||||
.tileTag = ANIM_TAG_RED_ORB,
|
||||
.paletteTag = ANIM_TAG_RED_ORB,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_16x16,
|
||||
.anims = gSporeParticleAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimSporeParticle,
|
||||
};
|
||||
|
||||
const union AnimCmd gRockPolishStreak_AnimCmd[] =
|
||||
@ -7234,42 +7234,42 @@ static void AnimNightSlash(struct Sprite *sprite)
|
||||
|
||||
static const union AffineAnimCmd sCompressTargetHorizontallyAffineAnimCmds[] =
|
||||
{
|
||||
AFFINEANIMCMD_FRAME(64, 0, 0, 16), //Compress
|
||||
AFFINEANIMCMD_FRAME(0, 0, 0, 64),
|
||||
AFFINEANIMCMD_FRAME(-64, 0, 0, 16),
|
||||
AFFINEANIMCMD_END,
|
||||
AFFINEANIMCMD_FRAME(64, 0, 0, 16), //Compress
|
||||
AFFINEANIMCMD_FRAME(0, 0, 0, 64),
|
||||
AFFINEANIMCMD_FRAME(-64, 0, 0, 16),
|
||||
AFFINEANIMCMD_END,
|
||||
};
|
||||
|
||||
static const union AffineAnimCmd sCompressTargetHorizontallyAffineAnimCmdsFast[] =
|
||||
{
|
||||
AFFINEANIMCMD_FRAME(32, 0, 0, 16), //Compress
|
||||
AFFINEANIMCMD_FRAME(0, 0, 0, 32),
|
||||
AFFINEANIMCMD_FRAME(-32, 0, 0, 16),
|
||||
AFFINEANIMCMD_END,
|
||||
AFFINEANIMCMD_FRAME(32, 0, 0, 16), //Compress
|
||||
AFFINEANIMCMD_FRAME(0, 0, 0, 32),
|
||||
AFFINEANIMCMD_FRAME(-32, 0, 0, 16),
|
||||
AFFINEANIMCMD_END,
|
||||
};
|
||||
|
||||
static void AnimTask_CompressTargetStep(u8 taskId)
|
||||
{
|
||||
struct Task* task = &gTasks[taskId];
|
||||
struct Task* task = &gTasks[taskId];
|
||||
|
||||
if (!RunAffineAnimFromTaskData(task))
|
||||
DestroyAnimVisualTask(taskId);
|
||||
if (!RunAffineAnimFromTaskData(task))
|
||||
DestroyAnimVisualTask(taskId);
|
||||
}
|
||||
|
||||
void AnimTask_CompressTargetHorizontally(u8 taskId)
|
||||
{
|
||||
struct Task* task = &gTasks[taskId];
|
||||
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
|
||||
PrepareAffineAnimInTaskData(task, spriteId, sCompressTargetHorizontallyAffineAnimCmds);
|
||||
task->func = AnimTask_CompressTargetStep;
|
||||
struct Task* task = &gTasks[taskId];
|
||||
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
|
||||
PrepareAffineAnimInTaskData(task, spriteId, sCompressTargetHorizontallyAffineAnimCmds);
|
||||
task->func = AnimTask_CompressTargetStep;
|
||||
}
|
||||
|
||||
void AnimTask_CompressTargetHorizontallyFast(u8 taskId)
|
||||
{
|
||||
struct Task* task = &gTasks[taskId];
|
||||
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
|
||||
PrepareAffineAnimInTaskData(task, spriteId, sCompressTargetHorizontallyAffineAnimCmdsFast);
|
||||
task->func = AnimTask_CompressTargetStep;
|
||||
struct Task* task = &gTasks[taskId];
|
||||
u8 spriteId = GetAnimBattlerSpriteId(ANIM_TARGET);
|
||||
PrepareAffineAnimInTaskData(task, spriteId, sCompressTargetHorizontallyAffineAnimCmdsFast);
|
||||
task->func = AnimTask_CompressTargetStep;
|
||||
}
|
||||
|
||||
void AnimTask_CreateSmallSteelBeamOrbs(u8 taskId)
|
||||
|
||||
@ -525,17 +525,17 @@ const struct SpriteTemplate gFlashCannonGrayChargeTemplate =
|
||||
|
||||
static const union AffineAnimCmd sSpriteAffineAnim_JudgmentBall[] =
|
||||
{
|
||||
AFFINEANIMCMD_FRAME(16, 16, 0, 0),
|
||||
AFFINEANIMCMD_FRAME(8, 8, 0, 15), //Half size
|
||||
AFFINEANIMCMD_FRAME(0, 0, 0, 120), //Delay
|
||||
AFFINEANIMCMD_FRAME(24, 24, 0, 5), //Normal size
|
||||
AFFINEANIMCMD_FRAME(0, 0, 0, 10), //Delay
|
||||
AFFINEANIMCMD_FRAME(-16, -16, 0, 15), //Revert to 1 px
|
||||
AFFINEANIMCMD_END,
|
||||
AFFINEANIMCMD_FRAME(16, 16, 0, 0),
|
||||
AFFINEANIMCMD_FRAME(8, 8, 0, 15), //Half size
|
||||
AFFINEANIMCMD_FRAME(0, 0, 0, 120), //Delay
|
||||
AFFINEANIMCMD_FRAME(24, 24, 0, 5), //Normal size
|
||||
AFFINEANIMCMD_FRAME(0, 0, 0, 10), //Delay
|
||||
AFFINEANIMCMD_FRAME(-16, -16, 0, 15), //Revert to 1 px
|
||||
AFFINEANIMCMD_END,
|
||||
};
|
||||
static const union AffineAnimCmd* const sSpriteAffineAnimTable_JudgmentBall[] =
|
||||
{
|
||||
sSpriteAffineAnim_JudgmentBall,
|
||||
sSpriteAffineAnim_JudgmentBall,
|
||||
};
|
||||
const struct SpriteTemplate gJudgmentBlackChargeTemplate =
|
||||
{
|
||||
|
||||
@ -403,24 +403,24 @@ const struct SpriteTemplate gFocusPunchFistSpriteTemplate =
|
||||
|
||||
const struct SpriteTemplate gPalmSpriteTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_PURPLE_HAND_OUTLINE,
|
||||
.paletteTag = ANIM_TAG_PURPLE_HAND_OUTLINE,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_32x32,
|
||||
.anims = gAnims_HandsAndFeet,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimBasicFistOrFoot,
|
||||
.tileTag = ANIM_TAG_PURPLE_HAND_OUTLINE,
|
||||
.paletteTag = ANIM_TAG_PURPLE_HAND_OUTLINE,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_32x32,
|
||||
.anims = gAnims_HandsAndFeet,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimBasicFistOrFoot,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gAuraSphereBlast =
|
||||
{
|
||||
.tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
|
||||
.paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_64x64,
|
||||
.anims = gDummySpriteAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimSuperpowerFireball,
|
||||
.tileTag = ANIM_TAG_CIRCLE_OF_LIGHT,
|
||||
.paletteTag = ANIM_TAG_CIRCLE_OF_LIGHT,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_64x64,
|
||||
.anims = gDummySpriteAnimTable,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimSuperpowerFireball,
|
||||
};
|
||||
|
||||
const union AffineAnimCmd gForcePalmAffineAnimCmd_1[] =
|
||||
|
||||
@ -530,13 +530,13 @@ const struct SpriteTemplate gSpacialRendBladesTemplate2 =
|
||||
// Sea of Fire
|
||||
const struct SpriteTemplate gTwisterEmberSpriteTemplate =
|
||||
{
|
||||
.tileTag = ANIM_TAG_SMALL_EMBER,
|
||||
.paletteTag = ANIM_TAG_SMALL_EMBER,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_32x32,
|
||||
.anims = gAnims_BasicFire,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimMoveTwisterParticle,
|
||||
.tileTag = ANIM_TAG_SMALL_EMBER,
|
||||
.paletteTag = ANIM_TAG_SMALL_EMBER,
|
||||
.oam = &gOamData_AffineOff_ObjNormal_32x32,
|
||||
.anims = gAnims_BasicFire,
|
||||
.images = NULL,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = AnimMoveTwisterParticle,
|
||||
};
|
||||
|
||||
static void AnimLavaPlumeOrbitScatter(struct Sprite *sprite)
|
||||
|
||||
@ -527,7 +527,7 @@ void AnimFlyBallAttack(struct Sprite *sprite)
|
||||
sprite->data[2] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_X_2);
|
||||
sprite->data[3] = sprite->y;
|
||||
sprite->data[4] = GetBattlerSpriteCoord(gBattleAnimTarget, BATTLER_COORD_Y_PIC_OFFSET);
|
||||
sprite->data[5] = gBattleAnimArgs[1]; // if sprite is to remain invisible
|
||||
sprite->data[5] = gBattleAnimArgs[1]; // if sprite is to remain invisible
|
||||
|
||||
InitAnimLinearTranslation(sprite);
|
||||
sprite->callback = AnimFlyBallAttack_Step;
|
||||
|
||||
@ -730,13 +730,13 @@ static void AnimTask_DuckDownHop_Step1(u8 taskId)
|
||||
{
|
||||
u8 spriteId;
|
||||
|
||||
spriteId = gTasks[taskId].data[0];
|
||||
gTasks[taskId].data[12] += gTasks[taskId].data[5];
|
||||
gSprites[spriteId].y2 = (gTasks[taskId].data[12] >> 8);
|
||||
if (--gTasks[taskId].data[6] == 0)
|
||||
{
|
||||
spriteId = gTasks[taskId].data[0];
|
||||
gTasks[taskId].data[12] += gTasks[taskId].data[5];
|
||||
gSprites[spriteId].y2 = (gTasks[taskId].data[12] >> 8);
|
||||
if (--gTasks[taskId].data[6] == 0)
|
||||
{
|
||||
gTasks[taskId].func = AnimTask_DuckDownHop_Step2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void AnimTask_DuckDownHop_Step2(u8 taskId)
|
||||
@ -748,11 +748,11 @@ static void AnimTask_DuckDownHop_Step2(u8 taskId)
|
||||
}
|
||||
else
|
||||
{
|
||||
spriteId = gTasks[taskId].data[0];
|
||||
gTasks[taskId].data[11] += gTasks[taskId].data[1];
|
||||
gSprites[spriteId].x2 = gTasks[taskId].data[11] >> 8;
|
||||
gSprites[spriteId].y2 = Sin((u8)(gTasks[taskId].data[10] >> 8), gTasks[taskId].data[2]) + (gTasks[taskId].data[12] >> 8);
|
||||
gTasks[taskId].data[10] += gTasks[taskId].data[7];
|
||||
spriteId = gTasks[taskId].data[0];
|
||||
gTasks[taskId].data[11] += gTasks[taskId].data[1];
|
||||
gSprites[spriteId].x2 = gTasks[taskId].data[11] >> 8;
|
||||
gSprites[spriteId].y2 = Sin((u8)(gTasks[taskId].data[10] >> 8), gTasks[taskId].data[2]) + (gTasks[taskId].data[12] >> 8);
|
||||
gTasks[taskId].data[10] += gTasks[taskId].data[7];
|
||||
if (--gTasks[taskId].data[3] == 0)
|
||||
{
|
||||
DestroyAnimVisualTask(taskId);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -830,7 +830,7 @@ void AnimTask_InvertScreenColor(u8 taskId)
|
||||
selectedPalettes |= (0x10000 << gBattleAnimTarget);
|
||||
if (gBattleAnimArgs[0] & 0x8 && IsBattlerAlive(BATTLE_PARTNER(gBattleAnimTarget)))
|
||||
selectedPalettes |= (0x10000 << BATTLE_PARTNER(gBattleAnimTarget));
|
||||
if (gBattleAnimArgs[0] & 0x10 && IsBattlerAlive(BATTLE_PARTNER(gBattleAnimAttacker)))
|
||||
if (gBattleAnimArgs[0] & 0x10 && IsBattlerAlive(BATTLE_PARTNER(gBattleAnimAttacker)))
|
||||
selectedPalettes |= (0x10000 << BATTLE_PARTNER(gBattleAnimAttacker));
|
||||
|
||||
InvertPlttBuffer(selectedPalettes);
|
||||
|
||||
@ -182,24 +182,24 @@ const struct SpriteTemplate gWaterBubbleSpriteTemplate =
|
||||
|
||||
const struct SpriteTemplate gGreenPoisonDrip =
|
||||
{
|
||||
.tileTag = ANIM_TAG_GREEN_POISON_BUBBLE,
|
||||
.paletteTag = ANIM_TAG_GREEN_POISON_BUBBLE,
|
||||
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
|
||||
.tileTag = ANIM_TAG_GREEN_POISON_BUBBLE,
|
||||
.paletteTag = ANIM_TAG_GREEN_POISON_BUBBLE,
|
||||
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
|
||||
.anims = &gAnims_PoisonProjectile[1],
|
||||
.images = NULL,
|
||||
.affineAnims = gAffineAnims_Droplet,
|
||||
.callback = AnimAcidPoisonDroplet,
|
||||
.images = NULL,
|
||||
.affineAnims = gAffineAnims_Droplet,
|
||||
.callback = AnimAcidPoisonDroplet,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gGreenPoisonBubble =
|
||||
{
|
||||
.tileTag = ANIM_TAG_GREEN_POISON_BUBBLE,
|
||||
.paletteTag = ANIM_TAG_GREEN_POISON_BUBBLE,
|
||||
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
|
||||
.anims = gAnims_PoisonProjectile,
|
||||
.images = NULL,
|
||||
.affineAnims = gAffineAnims_PoisonProjectile,
|
||||
.callback = AnimAcidPoisonBubble,
|
||||
.tileTag = ANIM_TAG_GREEN_POISON_BUBBLE,
|
||||
.paletteTag = ANIM_TAG_GREEN_POISON_BUBBLE,
|
||||
.oam = &gOamData_AffineDouble_ObjNormal_16x16,
|
||||
.anims = gAnims_PoisonProjectile,
|
||||
.images = NULL,
|
||||
.affineAnims = gAffineAnims_PoisonProjectile,
|
||||
.callback = AnimAcidPoisonBubble,
|
||||
};
|
||||
|
||||
const union AnimCmd gSuckerPunchAnimCmd[] =
|
||||
|
||||
@ -314,18 +314,18 @@ const struct SpriteTemplate gStealthRockSpriteTemplate =
|
||||
|
||||
static const union AffineAnimCmd sSpriteAffineAnim_CrushGripHandEnemyAttack[] =
|
||||
{
|
||||
AFFINEANIMCMD_FRAME(0, 0, 96, 1), //180 degree turn
|
||||
AFFINEANIMCMD_END
|
||||
AFFINEANIMCMD_FRAME(0, 0, 96, 1), //180 degree turn
|
||||
AFFINEANIMCMD_END
|
||||
};
|
||||
static const union AffineAnimCmd sSpriteAffineAnim_DoNothing[] =
|
||||
{
|
||||
AFFINEANIMCMD_FRAME(0, 0, 0, 1), //Do nothing
|
||||
AFFINEANIMCMD_END
|
||||
AFFINEANIMCMD_FRAME(0, 0, 0, 1), //Do nothing
|
||||
AFFINEANIMCMD_END
|
||||
};
|
||||
static const union AffineAnimCmd* const sSpriteAffineAnimTable_CrushGripHand[] =
|
||||
{
|
||||
sSpriteAffineAnim_DoNothing,
|
||||
sSpriteAffineAnim_CrushGripHandEnemyAttack,
|
||||
sSpriteAffineAnim_DoNothing,
|
||||
sSpriteAffineAnim_CrushGripHandEnemyAttack,
|
||||
};
|
||||
const struct SpriteTemplate gCrushGripHandTemplate =
|
||||
{
|
||||
|
||||
@ -398,28 +398,28 @@ void AnimTask_FrozenIceCubeAttacker(u8 taskId)
|
||||
void AnimTask_CentredFrozenIceCube(u8 taskId)
|
||||
{
|
||||
// same as AnimTask_FrozenIceCube but center position on target(s)
|
||||
s16 x, y;
|
||||
u8 spriteId;
|
||||
u8 battler1 = gBattleAnimTarget;
|
||||
u8 battler2 = BATTLE_PARTNER(battler1);
|
||||
s16 x, y;
|
||||
u8 spriteId;
|
||||
u8 battler1 = gBattleAnimTarget;
|
||||
u8 battler2 = BATTLE_PARTNER(battler1);
|
||||
|
||||
if (!IsDoubleBattle() || IsAlly(gBattleAnimAttacker, gBattleAnimTarget))
|
||||
{
|
||||
x = GetBattlerSpriteCoord(battler1, BATTLER_COORD_X_2);
|
||||
y = GetBattlerSpriteCoord(battler1, BATTLER_COORD_Y_PIC_OFFSET);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = (GetBattlerSpriteCoord(battler1, BATTLER_COORD_X_2) + GetBattlerSpriteCoord(battler2, BATTLER_COORD_X_2)) / 2;
|
||||
y = (GetBattlerSpriteCoord(battler1, BATTLER_COORD_Y_PIC_OFFSET) + GetBattlerSpriteCoord(battler2, BATTLER_COORD_Y_PIC_OFFSET)) / 2;
|
||||
}
|
||||
if (!IsDoubleBattle() || IsAlly(gBattleAnimAttacker, gBattleAnimTarget))
|
||||
{
|
||||
x = GetBattlerSpriteCoord(battler1, BATTLER_COORD_X_2);
|
||||
y = GetBattlerSpriteCoord(battler1, BATTLER_COORD_Y_PIC_OFFSET);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = (GetBattlerSpriteCoord(battler1, BATTLER_COORD_X_2) + GetBattlerSpriteCoord(battler2, BATTLER_COORD_X_2)) / 2;
|
||||
y = (GetBattlerSpriteCoord(battler1, BATTLER_COORD_Y_PIC_OFFSET) + GetBattlerSpriteCoord(battler2, BATTLER_COORD_Y_PIC_OFFSET)) / 2;
|
||||
}
|
||||
|
||||
x -= 32;
|
||||
y -= 36;
|
||||
x -= 32;
|
||||
y -= 36;
|
||||
|
||||
spriteId = CreateSprite(&sFrozenIceCubeSpriteTemplate, x, y, 4);
|
||||
if (GetSpriteTileStartByTag(ANIM_TAG_ICE_CUBE) == 0xFFFF)
|
||||
gSprites[spriteId].invisible = TRUE;
|
||||
spriteId = CreateSprite(&sFrozenIceCubeSpriteTemplate, x, y, 4);
|
||||
if (GetSpriteTileStartByTag(ANIM_TAG_ICE_CUBE) == 0xFFFF)
|
||||
gSprites[spriteId].invisible = TRUE;
|
||||
|
||||
SetSubspriteTables(&gSprites[spriteId], sFrozenIceCubeSubspriteTable);
|
||||
gTasks[taskId].data[15] = spriteId;
|
||||
|
||||
@ -585,14 +585,14 @@ const struct SpriteTemplate gAquaTailHitSpriteTemplate =
|
||||
};
|
||||
|
||||
static const union AnimCmd sAnimCmdAnimatedSpark2[] = {
|
||||
ANIMCMD_FRAME((8 * 8) / (16 * 16) * 0, 8),
|
||||
ANIMCMD_FRAME((8 * 8) / (16 * 16) * 1, 8),
|
||||
ANIMCMD_FRAME((8 * 8) / (16 * 16) * 2, 8),
|
||||
ANIMCMD_JUMP(0)
|
||||
ANIMCMD_FRAME((8 * 8) / (16 * 16) * 0, 8),
|
||||
ANIMCMD_FRAME((8 * 8) / (16 * 16) * 1, 8),
|
||||
ANIMCMD_FRAME((8 * 8) / (16 * 16) * 2, 8),
|
||||
ANIMCMD_JUMP(0)
|
||||
};
|
||||
|
||||
static const union AnimCmd *const sAnimCmdTable_AnimatedSpark2[] = {
|
||||
sAnimCmdAnimatedSpark2,
|
||||
sAnimCmdAnimatedSpark2,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gSparkBeamSpriteTemplate =
|
||||
|
||||
@ -75,7 +75,7 @@ void SetUpBattleVarsAndBirchZigzagoon(void)
|
||||
gBattleControllerExecFlags = 0;
|
||||
ClearBattleAnimationVars();
|
||||
BattleAI_SetupItems();
|
||||
BattleAI_SetupFlags();
|
||||
BattleAI_SetupFlags();
|
||||
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_FIRST_BATTLE)
|
||||
{
|
||||
@ -611,7 +611,7 @@ bool32 IsValidForBattle(struct Pokemon *mon)
|
||||
{
|
||||
u32 species = GetMonData(mon, MON_DATA_SPECIES_OR_EGG);
|
||||
return (species != SPECIES_NONE
|
||||
&& species != SPECIES_EGG
|
||||
&& species != SPECIES_EGG
|
||||
&& GetMonData(mon, MON_DATA_HP) != 0
|
||||
&& GetMonData(mon, MON_DATA_IS_EGG) == FALSE);
|
||||
}
|
||||
|
||||
@ -547,7 +547,7 @@ static const u8 sText_TargetIdentified[] = _("{B_DEF_NAME_WITH_PREFIX} was\niden
|
||||
static const u8 sText_TargetWokeUp[] = _("{B_DEF_NAME_WITH_PREFIX} woke up!");
|
||||
static const u8 sText_PkmnStoleAndAteItem[] = _("{B_ATK_NAME_WITH_PREFIX} stole and\nate {B_DEF_NAME_WITH_PREFIX}'s {B_LAST_ITEM}!");
|
||||
static const u8 sText_TailWindBlew[] = _("The tailwind blew from\nbehind {B_ATK_TEAM2} team!");
|
||||
static const u8 sText_PkmnWentBack[] = _("{B_ATK_NAME_WITH_PREFIX} went back\nto {B_ATK_TRAINER_CLASS} {B_ATK_TRAINER_NAME}");
|
||||
static const u8 sText_PkmnWentBack[] = _("{B_ATK_NAME_WITH_PREFIX} went back\nto {B_ATK_TRAINER_NAME}!");
|
||||
static const u8 sText_PkmnCantUseItemsAnymore[] = _("{B_DEF_NAME_WITH_PREFIX} can't use\nitems anymore!");
|
||||
static const u8 sText_PkmnFlung[] = _("{B_ATK_NAME_WITH_PREFIX} flung its\n{B_LAST_ITEM}!");
|
||||
static const u8 sText_PkmnPreventedFromHealing[] = _("{B_DEF_NAME_WITH_PREFIX} was prevented\nfrom healing!");
|
||||
@ -606,7 +606,6 @@ static const u8 sText_TargetAbilityRaisedStat[] = _("{B_DEF_NAME_WITH_PREFIX}'s
|
||||
static const u8 sText_TargetAbilityLoweredStat[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nlowered its {B_BUFF1}!");
|
||||
static const u8 sText_AttackerAbilityRaisedStat[] = _("{B_ATK_NAME_WITH_PREFIX}'s {B_ATK_ABILITY}\nraised its {B_BUFF1}!");
|
||||
static const u8 sText_ScriptingAbilityRaisedStat[] = _("{B_SCR_ACTIVE_NAME_WITH_PREFIX}'s {B_SCR_ACTIVE_ABILITY}\nraised its {B_BUFF1}!");
|
||||
static const u8 sText_AuroraVeilEnds[] = _("{B_DEF_NAME_WITH_PREFIX}'s {B_DEF_ABILITY}\nwore off!");
|
||||
static const u8 sText_ElectricTerrainEnds[] = _("The electricity disappeared\nfrom the battlefield.");
|
||||
static const u8 sText_MistyTerrainEnds[] = _("The mist disappeared\nfrom the battlefield.");
|
||||
static const u8 sText_PsychicTerrainEnds[] = _("The weirdness disappeared\nfrom the battlefield.");
|
||||
@ -1442,7 +1441,6 @@ const u8 *const gBattleStringsTable[BATTLESTRINGS_COUNT] =
|
||||
[STRINGID_WATERSPORTENDS - BATTLESTRINGS_TABLE_START] = sText_WaterSportEnds,
|
||||
[STRINGID_GRAVITYENDS - BATTLESTRINGS_TABLE_START] = sText_GravityEnds,
|
||||
[STRINGID_AQUARINGHEAL - BATTLESTRINGS_TABLE_START] = sText_AquaRingHeal,
|
||||
[STRINGID_AURORAVEILENDS - BATTLESTRINGS_TABLE_START] = sText_AuroraVeilEnds,
|
||||
[STRINGID_ELECTRICTERRAINENDS - BATTLESTRINGS_TABLE_START] = sText_ElectricTerrainEnds,
|
||||
[STRINGID_MISTYTERRAINENDS - BATTLESTRINGS_TABLE_START] = sText_MistyTerrainEnds,
|
||||
[STRINGID_PSYCHICTERRAINENDS - BATTLESTRINGS_TABLE_START] = sText_PsychicTerrainEnds,
|
||||
|
||||
@ -1240,10 +1240,10 @@ static void Cmd_attackcanceler(void)
|
||||
}
|
||||
|
||||
if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_OFF
|
||||
&& GetBattlerAbility(gBattlerAttacker) == ABILITY_PARENTAL_BOND
|
||||
&& IsMoveAffectedByParentalBond(gCurrentMove, gBattlerAttacker)
|
||||
&& !(gAbsentBattlerFlags & (1u << gBattlerTarget))
|
||||
&& GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE)
|
||||
&& GetBattlerAbility(gBattlerAttacker) == ABILITY_PARENTAL_BOND
|
||||
&& IsMoveAffectedByParentalBond(gCurrentMove, gBattlerAttacker)
|
||||
&& !(gAbsentBattlerFlags & (1u << gBattlerTarget))
|
||||
&& GetActiveGimmick(gBattlerAttacker) != GIMMICK_Z_MOVE)
|
||||
{
|
||||
gSpecialStatuses[gBattlerAttacker].parentalBondState = PARENTAL_BOND_1ST_HIT;
|
||||
gMultiHitCounter = 2;
|
||||
@ -1284,16 +1284,40 @@ static void Cmd_attackcanceler(void)
|
||||
|
||||
if (!(gHitMarker & HITMARKER_OBEYS) && !(gBattleMons[gBattlerAttacker].status2 & STATUS2_MULTIPLETURNS))
|
||||
{
|
||||
switch (IsMonDisobedient())
|
||||
switch (gBattleStruct->obedienceResult)
|
||||
{
|
||||
case 0:
|
||||
case OBEYS:
|
||||
break;
|
||||
case 2:
|
||||
case DISOBEYS_LOAFS:
|
||||
// Randomly select, then print a disobedient string
|
||||
// B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = MOD(Random(), NUM_LOAF_STRINGS);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
|
||||
gMoveResultFlags |= MOVE_RESULT_MISSED;
|
||||
return;
|
||||
case DISOBEYS_HITS_SELF:
|
||||
gBattlerTarget = gBattlerAttacker;
|
||||
gBattleMoveDamage = CalculateMoveDamage(MOVE_NONE, gBattlerAttacker, gBattlerAttacker, TYPE_MYSTERY, 40, FALSE, FALSE, TRUE);
|
||||
gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself;
|
||||
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||||
gHitMarker |= HITMARKER_OBEYS;
|
||||
return;
|
||||
default:
|
||||
case DISOBEYS_FALL_ASLEEP:
|
||||
gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep;
|
||||
gMoveResultFlags |= MOVE_RESULT_MISSED;
|
||||
return;
|
||||
case DISOBEYS_WHILE_ASLEEP:
|
||||
gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep;
|
||||
gMoveResultFlags |= MOVE_RESULT_MISSED;
|
||||
return;
|
||||
case DISOBEYS_RANDOM_MOVE:
|
||||
gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
|
||||
SetAtkCancellerForCalledMove();
|
||||
gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove;
|
||||
gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
|
||||
gHitMarker |= HITMARKER_DISOBEDIENT_MOVE;
|
||||
gHitMarker |= HITMARKER_OBEYS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6003,9 +6027,9 @@ static void Cmd_moveend(void)
|
||||
gBattlerTarget = BATTLE_PARTNER(gBattlerTarget); // Target the partner in doubles for second hit.
|
||||
|
||||
if (gBattleMons[gBattlerAttacker].hp
|
||||
&& gBattleMons[gBattlerTarget].hp
|
||||
&& (gChosenMove == MOVE_SLEEP_TALK || !(gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP))
|
||||
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE))
|
||||
&& gBattleMons[gBattlerTarget].hp
|
||||
&& (gChosenMove == MOVE_SLEEP_TALK || (gChosenMove == MOVE_SNORE) || !(gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP))
|
||||
&& !(gBattleMons[gBattlerAttacker].status1 & STATUS1_FREEZE))
|
||||
{
|
||||
if (gSpecialStatuses[gBattlerAttacker].parentalBondState)
|
||||
gSpecialStatuses[gBattlerAttacker].parentalBondState--;
|
||||
@ -6392,9 +6416,11 @@ static void Cmd_moveend(void)
|
||||
gBattleStruct->additionalEffectsCounter = 0;
|
||||
gBattleStruct->poisonPuppeteerConfusion = FALSE;
|
||||
gBattleStruct->fickleBeamBoosted = FALSE;
|
||||
gBattleStruct->distortedTypeMatchups = 0;
|
||||
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE)
|
||||
SetActiveGimmick(gBattlerAttacker, GIMMICK_NONE);
|
||||
gBattleStruct->distortedTypeMatchups = 0;
|
||||
if (B_CHARGE <= GEN_8 || moveType == TYPE_ELECTRIC)
|
||||
gStatuses3[gBattlerAttacker] &= ~(STATUS3_CHARGED_UP);
|
||||
memset(gQueuedStatBoosts, 0, sizeof(gQueuedStatBoosts));
|
||||
gBattleScripting.moveendState++;
|
||||
break;
|
||||
@ -7149,7 +7175,7 @@ static void UpdateSentMonFlags(u32 battler)
|
||||
|
||||
static bool32 DoSwitchInEffectsForBattler(u32 battler)
|
||||
{
|
||||
u32 i;
|
||||
u32 i = 0;
|
||||
// Neutralizing Gas announces itself before hazards
|
||||
if (gBattleMons[battler].ability == ABILITY_NEUTRALIZING_GAS && gSpecialStatuses[battler].announceNeutralizingGas == 0)
|
||||
{
|
||||
@ -7217,9 +7243,11 @@ static bool32 DoSwitchInEffectsForBattler(u32 battler)
|
||||
}
|
||||
else if (IsBattlerAffectedByHazards(battler, TRUE))
|
||||
{
|
||||
i = GetBattlerAbility(battler);
|
||||
if (!(gBattleMons[battler].status1 & STATUS1_ANY)
|
||||
&& !IS_BATTLER_OF_TYPE(battler, TYPE_STEEL)
|
||||
&& GetBattlerAbility(battler) != ABILITY_IMMUNITY
|
||||
&& i != ABILITY_IMMUNITY
|
||||
&& i != ABILITY_PURIFYING_SALT
|
||||
&& !IsAbilityOnSide(battler, ABILITY_PASTEL_VEIL)
|
||||
&& !(gSideStatuses[GetBattlerSide(battler)] & SIDE_STATUS_SAFEGUARD)
|
||||
&& !(gFieldStatuses & STATUS_FIELD_MISTY_TERRAIN))
|
||||
@ -9923,23 +9951,23 @@ static void Cmd_various(void)
|
||||
else
|
||||
{
|
||||
gSpecialStatuses[gBattlerTarget].instructedChosenTarget = *(gBattleStruct->moveTarget + gBattlerTarget) | 0x4;
|
||||
gBattlerAttacker = gBattlerTarget;
|
||||
gCalledMove = move;
|
||||
for (i = 0; i < MAX_MON_MOVES; i++)
|
||||
{
|
||||
if (gBattleMons[gBattlerAttacker].moves[i] == gCalledMove)
|
||||
if (gBattleMons[gBattlerTarget].moves[i] == gCalledMove)
|
||||
{
|
||||
gCurrMovePos = i;
|
||||
i = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != 4 || gBattleMons[gBattlerAttacker].pp[gCurrMovePos] == 0)
|
||||
if (i != 4 || gBattleMons[gBattlerTarget].pp[gCurrMovePos] == 0)
|
||||
gBattlescriptCurrInstr = cmd->failInstr;
|
||||
else
|
||||
{
|
||||
gBattlerTarget = gBattleStruct->lastMoveTarget[gBattlerAttacker];
|
||||
gEffectBattler = gBattleStruct->lastMoveTarget[gBattlerTarget];
|
||||
gHitMarker &= ~HITMARKER_ATTACKSTRING_PRINTED;
|
||||
gBattleStruct->atkCancellerTracker = 0;
|
||||
PREPARE_MON_NICK_WITH_PREFIX_BUFFER(gBattleTextBuff1, battler, gBattlerPartyIndexes[battler]);
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
@ -11374,7 +11402,7 @@ static void Cmd_jumpifnotfirstturn(void)
|
||||
|
||||
const u8 *jumpInstr = cmd->jumpInstr;
|
||||
|
||||
if (gDisableStructs[gBattlerAttacker].isFirstTurn)
|
||||
if (gDisableStructs[gBattlerAttacker].isFirstTurn && !(gSpecialStatuses[gBattlerAttacker].instructedChosenTarget))
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
else
|
||||
gBattlescriptCurrInstr = jumpInstr;
|
||||
@ -13978,7 +14006,10 @@ static void Cmd_setcharge(void)
|
||||
|
||||
u8 battler = GetBattlerForBattleScript(cmd->battler);
|
||||
gStatuses3[battler] |= STATUS3_CHARGED_UP;
|
||||
gDisableStructs[battler].chargeTimer = 2;
|
||||
if (B_CHARGE < GEN_9)
|
||||
gDisableStructs[battler].chargeTimer = 2;
|
||||
else
|
||||
gDisableStructs[battler].chargeTimer = 0;
|
||||
gBattlescriptCurrInstr++;
|
||||
gBattlescriptCurrInstr = cmd->nextInstr;
|
||||
}
|
||||
|
||||
@ -775,7 +775,7 @@ void BattleTv_SetDataBasedOnMove(u16 move, u16 weatherFlags, struct DisableStruc
|
||||
tvPtr->side[atkSide].usedMoveSlot = moveSlot;
|
||||
AddMovePoints(PTS_MOVE_EFFECT, moveSlot, move, 0);
|
||||
AddPointsBasedOnWeather(weatherFlags, move, moveSlot);
|
||||
if (disableStructPtr->chargeTimer != 0)
|
||||
if (gStatuses3[gBattlerAttacker] & STATUS3_CHARGED_UP)
|
||||
AddMovePoints(PTS_ELECTRIC, move, moveSlot, 0);
|
||||
|
||||
if (move == MOVE_WISH)
|
||||
|
||||
@ -145,6 +145,8 @@ void HandleAction_UseMove(void)
|
||||
gBattleScripting.savedMoveEffect = 0;
|
||||
gCurrMovePos = gChosenMovePos = *(gBattleStruct->chosenMovePositions + gBattlerAttacker);
|
||||
|
||||
gBattleStruct->obedienceResult = GetAttackerObedienceForAction();
|
||||
|
||||
// choose move
|
||||
if (gProtectStructs[gBattlerAttacker].noValidMoves)
|
||||
{
|
||||
@ -348,7 +350,7 @@ void HandleAction_UseMove(void)
|
||||
else
|
||||
{
|
||||
gBattlerTarget = *(gBattleStruct->moveTarget + gBattlerAttacker);
|
||||
if (!IsBattlerAlive(gBattlerTarget))
|
||||
if (!IsBattlerAlive(gBattlerTarget) && moveTarget != MOVE_TARGET_OPPONENTS_FIELD)
|
||||
{
|
||||
if (GetBattlerSide(gBattlerAttacker) != GetBattlerSide(gBattlerTarget))
|
||||
{
|
||||
@ -2300,8 +2302,8 @@ enum
|
||||
ENDTURN_HEALBLOCK,
|
||||
ENDTURN_EMBARGO,
|
||||
ENDTURN_LOCK_ON,
|
||||
ENDTURN_CHARGE,
|
||||
ENDTURN_LASER_FOCUS,
|
||||
ENDTURN_CHARGE,
|
||||
ENDTURN_TAUNT,
|
||||
ENDTURN_YAWN,
|
||||
ENDTURN_ITEMS2,
|
||||
@ -2764,7 +2766,7 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
case ENDTURN_CHARGE: // charge
|
||||
if (gDisableStructs[battler].chargeTimer && --gDisableStructs[battler].chargeTimer == 0)
|
||||
if (gDisableStructs[battler].chargeTimer > 0 && --gDisableStructs[battler].chargeTimer == 0)
|
||||
gStatuses3[battler] &= ~STATUS3_CHARGED_UP;
|
||||
gBattleStruct->turnEffectsTracker++;
|
||||
break;
|
||||
@ -2951,7 +2953,7 @@ u8 DoBattlerEndTurnEffects(void)
|
||||
&& --gBattleStruct->dynamax.dynamaxTurns[battler] == 0)
|
||||
{
|
||||
gBattleScripting.battler = battler;
|
||||
UndoDynamax(battler);
|
||||
UndoDynamax(battler);
|
||||
BattleScriptExecute(BattleScript_DynamaxEnds);
|
||||
effect++;
|
||||
}
|
||||
@ -3230,7 +3232,7 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType)
|
||||
case CANCELLER_FLAGS: // flags clear
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_DESTINY_BOND;
|
||||
gStatuses3[gBattlerAttacker] &= ~STATUS3_GRUDGE;
|
||||
gStatuses4[gBattlerAttacker] &= ~ STATUS4_GLAIVE_RUSH;
|
||||
gStatuses4[gBattlerAttacker] &= ~STATUS4_GLAIVE_RUSH;
|
||||
gBattleStruct->atkCancellerTracker++;
|
||||
break;
|
||||
case CANCELLER_SKY_DROP:
|
||||
@ -3565,7 +3567,8 @@ u8 AtkCanceller_UnableToUseMove(u32 moveType)
|
||||
gBattleStruct->atkCancellerTracker++;
|
||||
break;
|
||||
case CANCELLER_Z_MOVES:
|
||||
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE)
|
||||
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE
|
||||
&& gBattleStruct->obedienceResult == OBEYS)
|
||||
{
|
||||
// For Z-Mirror Move, so it doesn't play the animation twice.
|
||||
bool32 alreadyUsed = HasTrainerUsedGimmick(gBattlerAttacker, GIMMICK_Z_MOVE);
|
||||
@ -8297,11 +8300,13 @@ u32 GetMoveTarget(u16 move, u8 setTarget)
|
||||
case MOVE_TARGET_DEPENDS:
|
||||
case MOVE_TARGET_BOTH:
|
||||
case MOVE_TARGET_FOES_AND_ALLY:
|
||||
case MOVE_TARGET_OPPONENTS_FIELD:
|
||||
targetBattler = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker)));
|
||||
if (!IsBattlerAlive(targetBattler))
|
||||
targetBattler ^= BIT_FLANK;
|
||||
break;
|
||||
case MOVE_TARGET_OPPONENTS_FIELD:
|
||||
targetBattler = GetBattlerAtPosition(BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker)));
|
||||
break;
|
||||
case MOVE_TARGET_RANDOM:
|
||||
side = BATTLE_OPPOSITE(GetBattlerSide(gBattlerAttacker));
|
||||
if (IsAffectedByFollowMe(gBattlerAttacker, side, move))
|
||||
@ -8329,12 +8334,7 @@ u32 GetMoveTarget(u16 move, u8 setTarget)
|
||||
return targetBattler;
|
||||
}
|
||||
|
||||
static bool32 IsBattlerModernFatefulEncounter(u32 battler)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
u8 IsMonDisobedient(void)
|
||||
u8 GetAttackerObedienceForAction()
|
||||
{
|
||||
s32 rnd;
|
||||
s32 calc;
|
||||
@ -8342,40 +8342,37 @@ u8 IsMonDisobedient(void)
|
||||
u8 levelReferenced;
|
||||
|
||||
if (gBattleTypeFlags & (BATTLE_TYPE_LINK | BATTLE_TYPE_RECORDED_LINK))
|
||||
return 0;
|
||||
return OBEYS;
|
||||
if (BattlerHasAi(gBattlerAttacker))
|
||||
return 0;
|
||||
return OBEYS;
|
||||
|
||||
if (IsBattlerModernFatefulEncounter(gBattlerAttacker)) // only false if illegal Mew or Deoxys
|
||||
{
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && GetBattlerPosition(gBattlerAttacker) == B_POSITION_PLAYER_RIGHT)
|
||||
return 0;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
|
||||
return 0;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
|
||||
return 0;
|
||||
if (B_OBEDIENCE_MECHANICS < GEN_8 && !IsOtherTrainer(gBattleMons[gBattlerAttacker].otId, gBattleMons[gBattlerAttacker].otName))
|
||||
return 0;
|
||||
if (FlagGet(FLAG_BADGE08_GET)) // Rain Badge, ignore obedience altogether
|
||||
return 0;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && GetBattlerPosition(gBattlerAttacker) == B_POSITION_PLAYER_RIGHT)
|
||||
return OBEYS;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_FRONTIER)
|
||||
return OBEYS;
|
||||
if (gBattleTypeFlags & BATTLE_TYPE_RECORDED)
|
||||
return OBEYS;
|
||||
if (B_OBEDIENCE_MECHANICS < GEN_8 && !IsOtherTrainer(gBattleMons[gBattlerAttacker].otId, gBattleMons[gBattlerAttacker].otName))
|
||||
return OBEYS;
|
||||
if (FlagGet(FLAG_BADGE08_GET)) // Rain Badge, ignore obedience altogether
|
||||
return OBEYS;
|
||||
|
||||
obedienceLevel = 10;
|
||||
obedienceLevel = 10;
|
||||
|
||||
if (FlagGet(FLAG_BADGE01_GET)) // Stone Badge
|
||||
obedienceLevel = 20;
|
||||
if (FlagGet(FLAG_BADGE02_GET)) // Knuckle Badge
|
||||
obedienceLevel = 30;
|
||||
if (FlagGet(FLAG_BADGE03_GET)) // Dynamo Badge
|
||||
obedienceLevel = 40;
|
||||
if (FlagGet(FLAG_BADGE04_GET)) // Heat Badge
|
||||
obedienceLevel = 50;
|
||||
if (FlagGet(FLAG_BADGE05_GET)) // Balance Badge
|
||||
obedienceLevel = 60;
|
||||
if (FlagGet(FLAG_BADGE06_GET)) // Feather Badge
|
||||
obedienceLevel = 70;
|
||||
if (FlagGet(FLAG_BADGE07_GET)) // Mind Badge
|
||||
obedienceLevel = 80;
|
||||
}
|
||||
if (FlagGet(FLAG_BADGE01_GET)) // Stone Badge
|
||||
obedienceLevel = 20;
|
||||
if (FlagGet(FLAG_BADGE02_GET)) // Knuckle Badge
|
||||
obedienceLevel = 30;
|
||||
if (FlagGet(FLAG_BADGE03_GET)) // Dynamo Badge
|
||||
obedienceLevel = 40;
|
||||
if (FlagGet(FLAG_BADGE04_GET)) // Heat Badge
|
||||
obedienceLevel = 50;
|
||||
if (FlagGet(FLAG_BADGE05_GET)) // Balance Badge
|
||||
obedienceLevel = 60;
|
||||
if (FlagGet(FLAG_BADGE06_GET)) // Feather Badge
|
||||
obedienceLevel = 70;
|
||||
if (FlagGet(FLAG_BADGE07_GET)) // Mind Badge
|
||||
obedienceLevel = 80;
|
||||
|
||||
if (B_OBEDIENCE_MECHANICS >= GEN_8
|
||||
&& !IsOtherTrainer(gBattleMons[gBattlerAttacker].otId, gBattleMons[gBattlerAttacker].otName))
|
||||
@ -8384,86 +8381,58 @@ u8 IsMonDisobedient(void)
|
||||
levelReferenced = gBattleMons[gBattlerAttacker].level;
|
||||
|
||||
if (levelReferenced <= obedienceLevel)
|
||||
return 0;
|
||||
rnd = (Random() & 255);
|
||||
calc = (levelReferenced + obedienceLevel) * rnd >> 8;
|
||||
return OBEYS;
|
||||
|
||||
rnd = Random();
|
||||
calc = (levelReferenced + obedienceLevel) * (rnd & 255) >> 8;
|
||||
if (calc < obedienceLevel)
|
||||
return 0;
|
||||
return OBEYS;
|
||||
|
||||
// Clear the Z-Move flags if the battler is disobedient as to not waste the Z-Move
|
||||
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_Z_MOVE)
|
||||
{
|
||||
gBattleStruct->gimmick.activated[gBattlerAttacker][GIMMICK_Z_MOVE] = FALSE;
|
||||
gBattleStruct->gimmick.activeGimmick[GetBattlerSide(gBattlerAttacker)][gBattlerPartyIndexes[gBattlerAttacker]] = GIMMICK_NONE;
|
||||
}
|
||||
|
||||
// is not obedient
|
||||
if (gCurrentMove == MOVE_RAGE)
|
||||
gBattleMons[gBattlerAttacker].status2 &= ~STATUS2_RAGE;
|
||||
if (gBattleMons[gBattlerAttacker].status1 & STATUS1_SLEEP && (gMovesInfo[gCurrentMove].effect == EFFECT_SNORE || gMovesInfo[gCurrentMove].effect == EFFECT_SLEEP_TALK))
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_IgnoresWhileAsleep;
|
||||
return 1;
|
||||
}
|
||||
return DISOBEYS_WHILE_ASLEEP;
|
||||
|
||||
rnd = (Random() & 255);
|
||||
calc = (levelReferenced + obedienceLevel) * rnd >> 8;
|
||||
calc = (levelReferenced + obedienceLevel) * ((rnd >> 8) & 255) >> 8;
|
||||
if (calc < obedienceLevel)
|
||||
{
|
||||
calc = CheckMoveLimitations(gBattlerAttacker, 1u << gCurrMovePos, MOVE_LIMITATIONS_ALL);
|
||||
if (calc == ALL_MOVES_MASK) // all moves cannot be used
|
||||
{
|
||||
// Randomly select, then print a disobedient string
|
||||
// B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = MOD(Random(), NUM_LOAF_STRINGS);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
|
||||
return 1;
|
||||
}
|
||||
return DISOBEYS_LOAFS;
|
||||
else // use a random move
|
||||
{
|
||||
do
|
||||
{
|
||||
gCurrMovePos = gChosenMovePos = MOD(Random(), MAX_MON_MOVES);
|
||||
} while ((1u << gCurrMovePos) & calc);
|
||||
|
||||
gCalledMove = gBattleMons[gBattlerAttacker].moves[gCurrMovePos];
|
||||
SetAtkCancellerForCalledMove();
|
||||
gBattlescriptCurrInstr = BattleScript_IgnoresAndUsesRandomMove;
|
||||
gBattlerTarget = GetMoveTarget(gCalledMove, NO_TARGET_OVERRIDE);
|
||||
gHitMarker |= HITMARKER_DISOBEDIENT_MOVE;
|
||||
return 2;
|
||||
}
|
||||
while ((1u << gCurrMovePos) & calc);
|
||||
return DISOBEYS_RANDOM_MOVE;
|
||||
}
|
||||
else
|
||||
{
|
||||
obedienceLevel = levelReferenced - obedienceLevel;
|
||||
|
||||
calc = (Random() & 255);
|
||||
calc = ((rnd >> 16) & 255);
|
||||
if (calc < obedienceLevel && CanBeSlept(gBattlerAttacker, GetBattlerAbility(gBattlerAttacker)))
|
||||
{
|
||||
// try putting asleep
|
||||
int i;
|
||||
for (i = 0; i < gBattlersCount; i++)
|
||||
{
|
||||
if (gBattleMons[i].status2 & STATUS2_UPROAR)
|
||||
break;
|
||||
}
|
||||
if (i == gBattlersCount)
|
||||
{
|
||||
gBattlescriptCurrInstr = BattleScript_IgnoresAndFallsAsleep;
|
||||
return 1;
|
||||
}
|
||||
return DISOBEYS_FALL_ASLEEP;
|
||||
}
|
||||
calc -= obedienceLevel;
|
||||
if (calc < obedienceLevel)
|
||||
{
|
||||
gBattleMoveDamage = CalculateMoveDamage(MOVE_NONE, gBattlerAttacker, gBattlerAttacker, TYPE_MYSTERY, 40, FALSE, FALSE, TRUE);
|
||||
gBattlerTarget = gBattlerAttacker;
|
||||
gBattlescriptCurrInstr = BattleScript_IgnoresAndHitsItself;
|
||||
gHitMarker |= HITMARKER_UNABLE_TO_USE_MOVE;
|
||||
return 2;
|
||||
}
|
||||
return DISOBEYS_HITS_SELF;
|
||||
else
|
||||
{
|
||||
// Randomly select, then print a disobedient string
|
||||
// B_MSG_LOAFING, B_MSG_WONT_OBEY, B_MSG_TURNED_AWAY, or B_MSG_PRETEND_NOT_NOTICE
|
||||
gBattleCommunication[MULTISTRING_CHOOSER] = MOD(Random(), NUM_LOAF_STRINGS);
|
||||
gBattlescriptCurrInstr = BattleScript_MoveUsedLoafingAround;
|
||||
return 1;
|
||||
}
|
||||
return DISOBEYS_LOAFS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -432,33 +432,33 @@ const struct SpriteTemplate gFieldEffectObjectTemplate_DeepSandFootprints = {
|
||||
};
|
||||
|
||||
static const struct SpriteFrameImage sPicTable_BugTracks[] = {
|
||||
overworld_frame(gFieldEffectObjectPic_BugTracks, 2, 2, 0),
|
||||
overworld_frame(gFieldEffectObjectPic_BugTracks, 2, 2, 1),
|
||||
overworld_frame(gFieldEffectObjectPic_BugTracks, 2, 2, 0),
|
||||
overworld_frame(gFieldEffectObjectPic_BugTracks, 2, 2, 1),
|
||||
};
|
||||
|
||||
static const struct SpriteFrameImage sPicTable_SpotTracks[] = {
|
||||
overworld_frame(gFieldEffectObjectPic_SpotTracks, 2, 2, 0),
|
||||
overworld_frame(gFieldEffectObjectPic_SpotTracks, 2, 2, 1),
|
||||
overworld_frame(gFieldEffectObjectPic_SpotTracks, 2, 2, 0),
|
||||
overworld_frame(gFieldEffectObjectPic_SpotTracks, 2, 2, 1),
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gFieldEffectObjectTemplate_BugTracks = {
|
||||
.tileTag = 0xFFFF,
|
||||
.paletteTag = FLDEFF_PAL_TAG_GENERAL_0,
|
||||
.oam = &gObjectEventBaseOam_16x16,
|
||||
.anims = sAnimTable_DeepSandFootprints,
|
||||
.images = sPicTable_BugTracks,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = UpdateFootprintsTireTracksFieldEffect,
|
||||
.tileTag = 0xFFFF,
|
||||
.paletteTag = FLDEFF_PAL_TAG_GENERAL_0,
|
||||
.oam = &gObjectEventBaseOam_16x16,
|
||||
.anims = sAnimTable_DeepSandFootprints,
|
||||
.images = sPicTable_BugTracks,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = UpdateFootprintsTireTracksFieldEffect,
|
||||
};
|
||||
|
||||
const struct SpriteTemplate gFieldEffectObjectTemplate_SpotTracks = {
|
||||
.tileTag = 0xFFFF,
|
||||
.paletteTag = FLDEFF_PAL_TAG_GENERAL_0,
|
||||
.oam = &gObjectEventBaseOam_16x16,
|
||||
.anims = sAnimTable_DeepSandFootprints,
|
||||
.images = sPicTable_SpotTracks,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = UpdateFootprintsTireTracksFieldEffect,
|
||||
.tileTag = 0xFFFF,
|
||||
.paletteTag = FLDEFF_PAL_TAG_GENERAL_0,
|
||||
.oam = &gObjectEventBaseOam_16x16,
|
||||
.anims = sAnimTable_DeepSandFootprints,
|
||||
.images = sPicTable_SpotTracks,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = UpdateFootprintsTireTracksFieldEffect,
|
||||
};
|
||||
|
||||
static const struct SpriteFrameImage sPicTable_BikeTireTracks[] = {
|
||||
@ -470,10 +470,10 @@ static const struct SpriteFrameImage sPicTable_BikeTireTracks[] = {
|
||||
|
||||
|
||||
static const struct SpriteFrameImage sPicTable_SlitherTracks[] = {
|
||||
overworld_frame(gFieldEffectObjectPic_SlitherTracks, 2, 2, 0),
|
||||
overworld_frame(gFieldEffectObjectPic_SlitherTracks, 2, 2, 1),
|
||||
overworld_frame(gFieldEffectObjectPic_SlitherTracks, 2, 2, 2),
|
||||
overworld_frame(gFieldEffectObjectPic_SlitherTracks, 2, 2, 3),
|
||||
overworld_frame(gFieldEffectObjectPic_SlitherTracks, 2, 2, 0),
|
||||
overworld_frame(gFieldEffectObjectPic_SlitherTracks, 2, 2, 1),
|
||||
overworld_frame(gFieldEffectObjectPic_SlitherTracks, 2, 2, 2),
|
||||
overworld_frame(gFieldEffectObjectPic_SlitherTracks, 2, 2, 3),
|
||||
};
|
||||
|
||||
static const union AnimCmd sBikeTireTracksAnim_South[] =
|
||||
@ -549,13 +549,13 @@ const struct SpriteTemplate gFieldEffectObjectTemplate_BikeTireTracks = {
|
||||
|
||||
|
||||
const struct SpriteTemplate gFieldEffectObjectTemplate_SlitherTracks = {
|
||||
.tileTag = 0xFFFF,
|
||||
.paletteTag = FLDEFF_PAL_TAG_GENERAL_0,
|
||||
.oam = &gObjectEventBaseOam_16x16,
|
||||
.anims = sAnimTable_BikeTireTracks,
|
||||
.images = sPicTable_SlitherTracks,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = UpdateFootprintsTireTracksFieldEffect,
|
||||
.tileTag = 0xFFFF,
|
||||
.paletteTag = FLDEFF_PAL_TAG_GENERAL_0,
|
||||
.oam = &gObjectEventBaseOam_16x16,
|
||||
.anims = sAnimTable_BikeTireTracks,
|
||||
.images = sPicTable_SlitherTracks,
|
||||
.affineAnims = gDummySpriteAffineAnimTable,
|
||||
.callback = UpdateFootprintsTireTracksFieldEffect,
|
||||
};
|
||||
|
||||
static const struct SpriteFrameImage sPicTable_JumpBigSplash[] = {
|
||||
|
||||
@ -5193,10 +5193,10 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
|
||||
const u32 gMonShinyPalette_WooperPaldean[] = INCBIN_U32("graphics/pokemon/wooper/wooper_paldean/shiny.gbapal.lz");
|
||||
const u8 gMonIcon_WooperPaldean[] = INCBIN_U8("graphics/pokemon/wooper/wooper_paldean/icon.4bpp");
|
||||
#if OW_POKEMON_OBJECT_EVENTS
|
||||
// const u32 gObjectEventPic_WooperPaldean[] = INCBIN_COMP("graphics/pokemon/wooper/wooper_paldean/overworld.4bpp");
|
||||
const u32 gObjectEventPic_WooperPaldean[] = INCBIN_COMP("graphics/pokemon/wooper/wooper_paldean/overworld.4bpp");
|
||||
#if OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE
|
||||
// const u32 gOverworldPalette_WooperPaldean[] = INCBIN_U32("graphics/pokemon/wooper/wooper_paldean/overworld_normal.gbapal.lz");
|
||||
// const u32 gShinyOverworldPalette_WooperPaldean[] = INCBIN_U32("graphics/pokemon/wooper/wooper_paldean/overworld_shiny.gbapal.lz");
|
||||
const u32 gOverworldPalette_WooperPaldean[] = INCBIN_U32("graphics/pokemon/wooper/wooper_paldean/overworld_normal.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_WooperPaldean[] = INCBIN_U32("graphics/pokemon/wooper/wooper_paldean/overworld_shiny.gbapal.lz");
|
||||
#endif //OW_PKMN_OBJECTS_SHARE_PALETTES
|
||||
#endif //OW_POKEMON_OBJECT_EVENTS
|
||||
|
||||
@ -5209,10 +5209,10 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
|
||||
const u8 gMonFootprint_Clodsire[] = INCBIN_U8("graphics/pokemon/clodsire/footprint.1bpp");
|
||||
#endif //P_FOOTPRINTS
|
||||
#if OW_POKEMON_OBJECT_EVENTS
|
||||
// const u32 gObjectEventPic_Clodsire[] = INCBIN_COMP("graphics/pokemon/clodsire/overworld.4bpp");
|
||||
const u32 gObjectEventPic_Clodsire[] = INCBIN_COMP("graphics/pokemon/clodsire/overworld.4bpp");
|
||||
#if OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE
|
||||
// const u32 gOverworldPalette_Clodsire[] = INCBIN_U32("graphics/pokemon/clodsire/overworld_normal.gbapal.lz");
|
||||
// const u32 gShinyOverworldPalette_Clodsire[] = INCBIN_U32("graphics/pokemon/clodsire/overworld_shiny.gbapal.lz");
|
||||
const u32 gOverworldPalette_Clodsire[] = INCBIN_U32("graphics/pokemon/clodsire/overworld_normal.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_Clodsire[] = INCBIN_U32("graphics/pokemon/clodsire/overworld_shiny.gbapal.lz");
|
||||
#endif //OW_PKMN_OBJECTS_SHARE_PALETTES
|
||||
#endif //OW_POKEMON_OBJECT_EVENTS
|
||||
#endif //P_PALDEAN_FORMS
|
||||
@ -12202,6 +12202,17 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
|
||||
const u32 gMonShinyPalette_BasculinBlueStriped[] = INCBIN_U32("graphics/pokemon/basculin/blue_striped/shiny.gbapal.lz");
|
||||
const u8 gMonIcon_BasculinBlueStriped[] = INCBIN_U8("graphics/pokemon/basculin/blue_striped/icon.4bpp");
|
||||
|
||||
#if OW_POKEMON_OBJECT_EVENTS
|
||||
const u32 gObjectEventPic_BasculinRedStriped[] = INCBIN_COMP("graphics/pokemon/basculin/overworld.4bpp");
|
||||
const u32 gObjectEventPic_BasculinBlueStriped[] = INCBIN_COMP("graphics/pokemon/basculin/blue_striped/overworld.4bpp");
|
||||
#if OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE
|
||||
const u32 gOverworldPalette_BasculinRedStriped[] = INCBIN_U32("graphics/pokemon/basculin/overworld_normal.gbapal.lz");
|
||||
const u32 gOverworldPalette_BasculinBlueStriped[] = INCBIN_U32("graphics/pokemon/basculin/blue_striped/overworld_normal.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_BasculinRedStriped[] = INCBIN_U32("graphics/pokemon/basculin/overworld_shiny.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_BasculinBlueStriped[] = INCBIN_U32("graphics/pokemon/basculin/blue_striped/overworld_shiny.gbapal.lz");
|
||||
#endif //OW_PKMN_OBJECTS_SHARE_PALETTES
|
||||
#endif //OW_POKEMON_OBJECT_EVENTS
|
||||
|
||||
#if P_HISUIAN_FORMS
|
||||
const u32 gMonFrontPic_BasculinWhiteStriped[] = INCBIN_U32("graphics/pokemon/basculin/white_striped/anim_front.4bpp.lz");
|
||||
const u32 gMonPalette_BasculinWhiteStriped[] = INCBIN_U32("graphics/pokemon/basculin/white_striped/normal.gbapal.lz");
|
||||
@ -12210,15 +12221,9 @@ const u32 gObjectEventPic_Substitute[] = INCBIN_COMP("graphics/pokemon/question_
|
||||
const u8 gMonIcon_BasculinWhiteStriped[] = INCBIN_U8("graphics/pokemon/basculin/white_striped/icon.4bpp");
|
||||
|
||||
#if OW_POKEMON_OBJECT_EVENTS
|
||||
const u32 gObjectEventPic_BasculinRedStriped[] = INCBIN_COMP("graphics/pokemon/basculin/overworld.4bpp");
|
||||
const u32 gObjectEventPic_BasculinBlueStriped[] = INCBIN_COMP("graphics/pokemon/basculin/blue_striped/overworld.4bpp");
|
||||
const u32 gObjectEventPic_BasculinWhiteStriped[] = INCBIN_COMP("graphics/pokemon/basculin/white_striped/overworld.4bpp");
|
||||
#if OW_PKMN_OBJECTS_SHARE_PALETTES == FALSE
|
||||
const u32 gOverworldPalette_BasculinRedStriped[] = INCBIN_U32("graphics/pokemon/basculin/overworld_normal.gbapal.lz");
|
||||
const u32 gOverworldPalette_BasculinBlueStriped[] = INCBIN_U32("graphics/pokemon/basculin/blue_striped/overworld_normal.gbapal.lz");
|
||||
const u32 gOverworldPalette_BasculinWhiteStriped[] = INCBIN_U32("graphics/pokemon/basculin/white_striped/overworld_normal.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_BasculinRedStriped[] = INCBIN_U32("graphics/pokemon/basculin/overworld_shiny.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_BasculinBlueStriped[] = INCBIN_U32("graphics/pokemon/basculin/blue_striped/overworld_shiny.gbapal.lz");
|
||||
const u32 gShinyOverworldPalette_BasculinWhiteStriped[] = INCBIN_U32("graphics/pokemon/basculin/white_striped/overworld_shiny.gbapal.lz");
|
||||
#endif //OW_PKMN_OBJECTS_SHARE_PALETTES
|
||||
#endif //OW_POKEMON_OBJECT_EVENTS
|
||||
|
||||
@ -10596,9 +10596,9 @@ const struct MoveInfo gMovesInfo[MOVES_COUNT_DYNAMAX] =
|
||||
.description = COMPOUND_STRING(
|
||||
"May cause flinching or\n"
|
||||
#if B_USE_FROSTBITE == TRUE
|
||||
"leave the foe frozen."),
|
||||
#else
|
||||
"leave the foe with frostbite."),
|
||||
#else
|
||||
"leave the foe frozen."),
|
||||
#endif
|
||||
.effect = EFFECT_HIT,
|
||||
.power = 65,
|
||||
|
||||
@ -1426,12 +1426,12 @@ static const struct SpriteFrameImage sPicTable_Quagsire[] = {
|
||||
overworld_ascending_frames(gObjectEventPic_Quagsire, 4, 4),
|
||||
};
|
||||
#if P_PALDEAN_FORMS
|
||||
/*static const struct SpriteFrameImage sPicTable_WooperPaldean[] = {
|
||||
static const struct SpriteFrameImage sPicTable_WooperPaldean[] = {
|
||||
overworld_ascending_frames(gObjectEventPic_WooperPaldean, 4, 4),
|
||||
};
|
||||
static const struct SpriteFrameImage sPicTable_Clodsire[] = {
|
||||
overworld_ascending_frames(gObjectEventPic_Clodsire, 4, 4),
|
||||
};*/
|
||||
};
|
||||
#endif //P_PALDEAN_FORMS
|
||||
#endif //P_FAMILY_WOOPER
|
||||
|
||||
|
||||
@ -3620,7 +3620,7 @@ static const struct LevelUpMove sMoltresGalarianLevelUpLearnset[] = {
|
||||
LEVEL_UP_MOVE(60, MOVE_ENDURE),
|
||||
LEVEL_UP_MOVE(65, MOVE_MEMENTO),
|
||||
LEVEL_UP_MOVE(70, MOVE_SKY_ATTACK),
|
||||
LEVEL_UP_END
|
||||
LEVEL_UP_END
|
||||
};
|
||||
#endif //P_GALARIAN_FORMS
|
||||
#endif //P_FAMILY_MOLTRES
|
||||
|
||||
@ -1604,7 +1604,7 @@ const u16 gPokedexOrder_Weight[] =
|
||||
NATIONAL_DEX_MORGREM,
|
||||
// 28.7 lbs / 13.0 kg
|
||||
NATIONAL_DEX_IVYSAUR,
|
||||
//NATIONAL_DEX_VOLTORB_HISUIAN,
|
||||
//NATIONAL_DEX_VOLTORB_HISUIAN,
|
||||
//NATIONAL_DEX_BANETTE_MEGA,
|
||||
NATIONAL_DEX_MIME_JR,
|
||||
NATIONAL_DEX_LAMPENT,
|
||||
|
||||
@ -3005,6 +3005,14 @@ const struct SpeciesInfo gSpeciesInfoGen2[] =
|
||||
.iconSprite = gMonIcon_WooperPaldean,
|
||||
.iconPalIndex = 2,
|
||||
FOOTPRINT(Wooper)
|
||||
OVERWORLD(
|
||||
sPicTable_WooperPaldean,
|
||||
SIZE_32x32,
|
||||
SHADOW_SIZE_M,
|
||||
TRACKS_FOOT,
|
||||
gOverworldPalette_WooperPaldean,
|
||||
gShinyOverworldPalette_WooperPaldean
|
||||
)
|
||||
.isPaldeanForm = TRUE,
|
||||
.levelUpLearnset = sWooperPaldeanLevelUpLearnset,
|
||||
.teachableLearnset = sWooperPaldeanTeachableLearnset,
|
||||
@ -3061,6 +3069,14 @@ const struct SpeciesInfo gSpeciesInfoGen2[] =
|
||||
.iconSprite = gMonIcon_Clodsire,
|
||||
.iconPalIndex = 0,
|
||||
FOOTPRINT(Clodsire)
|
||||
OVERWORLD(
|
||||
sPicTable_Clodsire,
|
||||
SIZE_32x32,
|
||||
SHADOW_SIZE_M,
|
||||
TRACKS_FOOT,
|
||||
gOverworldPalette_Clodsire,
|
||||
gShinyOverworldPalette_Clodsire
|
||||
)
|
||||
.levelUpLearnset = sClodsireLevelUpLearnset,
|
||||
.teachableLearnset = sClodsireTeachableLearnset,
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -649,7 +649,7 @@ static const u8 sDebugText_Give_BattlePoints[] = _("Max Battle Points");
|
||||
static const u8 sDebugText_Give_DaycareEgg[] = _("Daycare Egg");
|
||||
// Sound Menu
|
||||
static const u8 sDebugText_Sound_SFX[] = _("SFX…{CLEAR_TO 110}{RIGHT_ARROW}");
|
||||
static const u8 sDebugText_Sound_SFX_ID[] = _("SFX ID: {STR_VAR_3} {START_BUTTON} Stop\n{STR_VAR_1} \n{STR_VAR_2}");
|
||||
static const u8 sDebugText_Sound_SFX_ID[] = _("SFX ID: {STR_VAR_3} {START_BUTTON} Stop\n{STR_VAR_1} \n{STR_VAR_2}");
|
||||
static const u8 sDebugText_Sound_Music[] = _("Music…{CLEAR_TO 110}{RIGHT_ARROW}");
|
||||
static const u8 sDebugText_Sound_Music_ID[] = _("Music ID: {STR_VAR_3} {START_BUTTON} Stop\n{STR_VAR_1} \n{STR_VAR_2}");
|
||||
// Berry Function Menu
|
||||
|
||||
@ -9496,30 +9496,30 @@ static void DoTracksGroundEffect_BikeTireTracks(struct ObjectEvent *objEvent, st
|
||||
|
||||
static void DoTracksGroundEffect_SlitherTracks(struct ObjectEvent *objEvent, struct Sprite *sprite, u8 a)
|
||||
{
|
||||
// Specifies which bike track shape to show next.
|
||||
// For example, when the bike turns from up to right, it will show
|
||||
// a track that curves to the right.
|
||||
// Each 4-byte row corresponds to the initial direction of the bike, and
|
||||
// each byte in that row is for the next direction of the bike in the order
|
||||
// of down, up, left, right.
|
||||
static const u8 slitherTracks_Transitions[4][4] = {
|
||||
{1, 2, 7, 8},
|
||||
{1, 2, 6, 5},
|
||||
{5, 8, 3, 4},
|
||||
{6, 7, 3, 4},
|
||||
};
|
||||
// Specifies which bike track shape to show next.
|
||||
// For example, when the bike turns from up to right, it will show
|
||||
// a track that curves to the right.
|
||||
// Each 4-byte row corresponds to the initial direction of the bike, and
|
||||
// each byte in that row is for the next direction of the bike in the order
|
||||
// of down, up, left, right.
|
||||
static const u8 slitherTracks_Transitions[4][4] = {
|
||||
{1, 2, 7, 8},
|
||||
{1, 2, 6, 5},
|
||||
{5, 8, 3, 4},
|
||||
{6, 7, 3, 4},
|
||||
};
|
||||
|
||||
if (objEvent->currentCoords.x != objEvent->previousCoords.x || objEvent->currentCoords.y != objEvent->previousCoords.y)
|
||||
{
|
||||
gFieldEffectArguments[0] = objEvent->previousCoords.x;
|
||||
gFieldEffectArguments[1] = objEvent->previousCoords.y;
|
||||
gFieldEffectArguments[2] = 149;
|
||||
gFieldEffectArguments[3] = 2;
|
||||
gFieldEffectArguments[4] =
|
||||
slitherTracks_Transitions[objEvent->previousMovementDirection][objEvent->facingDirection - 5];
|
||||
if (objEvent->currentCoords.x != objEvent->previousCoords.x || objEvent->currentCoords.y != objEvent->previousCoords.y)
|
||||
{
|
||||
gFieldEffectArguments[0] = objEvent->previousCoords.x;
|
||||
gFieldEffectArguments[1] = objEvent->previousCoords.y;
|
||||
gFieldEffectArguments[2] = 149;
|
||||
gFieldEffectArguments[3] = 2;
|
||||
gFieldEffectArguments[4] =
|
||||
slitherTracks_Transitions[objEvent->previousMovementDirection][objEvent->facingDirection - 5];
|
||||
gFieldEffectArguments[5] = objEvent->previousMetatileBehavior;
|
||||
FieldEffectStart(FLDEFF_TRACKS_SLITHER);
|
||||
}
|
||||
FieldEffectStart(FLDEFF_TRACKS_SLITHER);
|
||||
}
|
||||
}
|
||||
|
||||
void GroundEffect_Ripple(struct ObjectEvent *objEvent, struct Sprite *sprite)
|
||||
|
||||
@ -141,9 +141,9 @@ static s32 _putsEncoded(char *s, s32 len, void *buf)
|
||||
|
||||
static s32 mini_strlen(const char *s)
|
||||
{
|
||||
s32 len = 0;
|
||||
while (s[len] != '\0') len++;
|
||||
return len;
|
||||
s32 len = 0;
|
||||
while (s[len] != '\0') len++;
|
||||
return len;
|
||||
}
|
||||
|
||||
static s32 mini_itoa(s32 value, u32 radix, s32 uppercase, bool32 unsig, char *buffer)
|
||||
|
||||
@ -3511,14 +3511,14 @@ static void SpriteCB_DexListStartMenuCursor(struct Sprite *sprite)
|
||||
//************************************
|
||||
|
||||
//Stat bars on main screen, code by DizzyEgg, idea by Jaizu
|
||||
#define PIXEL_COORDS_TO_OFFSET(x, y)( \
|
||||
/*Add tiles by X*/ \
|
||||
((y / 8) * 32 * 8) \
|
||||
/*Add tiles by X*/ \
|
||||
+ ((x / 8) * 32) \
|
||||
/*Add pixels by Y*/ \
|
||||
+ ((((y) - ((y / 8) * 8))) * 4) \
|
||||
/*Add pixels by X*/ \
|
||||
#define PIXEL_COORDS_TO_OFFSET(x, y)( \
|
||||
/*Add tiles by X*/ \
|
||||
((y / 8) * 32 * 8) \
|
||||
/*Add tiles by X*/ \
|
||||
+ ((x / 8) * 32) \
|
||||
/*Add pixels by Y*/ \
|
||||
+ ((((y) - ((y / 8) * 8))) * 4) \
|
||||
/*Add pixels by X*/ \
|
||||
+ ((((x) - ((x / 8) * 8)) / 2)))
|
||||
|
||||
static inline void WritePixel(u8 *dst, u32 x, u32 y, u32 value)
|
||||
|
||||
@ -263,6 +263,29 @@ SINGLE_BATTLE_TEST("Parental Bond Smack Down effect triggers after 2nd hit")
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Parental Bond Snore strikes twice while asleep")
|
||||
{
|
||||
s16 damage[2];
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_SNORE].effect == EFFECT_SNORE);
|
||||
PLAYER(SPECIES_KANGASKHAN_MEGA) { Status1(STATUS1_SLEEP); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_SNORE); }
|
||||
} SCENE {
|
||||
MESSAGE("Kangaskhan is fast asleep.");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SNORE, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
MESSAGE("Hit 2 time(s)!");
|
||||
} THEN {
|
||||
if (B_PARENTAL_BOND_DMG == GEN_6)
|
||||
EXPECT_MUL_EQ(damage[0], Q_4_12(0.5), damage[1]);
|
||||
else
|
||||
EXPECT_MUL_EQ(damage[0], Q_4_12(0.25), damage[1]);
|
||||
}
|
||||
}
|
||||
|
||||
TO_DO_BATTLE_TEST("Parental Bond tests");
|
||||
|
||||
// Temporary TODO: Convert Bulbapedia description into tests.
|
||||
|
||||
@ -84,3 +84,19 @@ SINGLE_BATTLE_TEST("Purifying Salt grants immunity to status effects")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Purifying Salt user can't be poisoned by Toxic Spikes")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_GARGANACL) { Ability(ABILITY_PURIFYING_SALT); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponent, MOVE_TOXIC_SPIKES); }
|
||||
TURN { SWITCH(player, 1); }
|
||||
} SCENE {
|
||||
SEND_IN_MESSAGE("Garganacl");
|
||||
} THEN {
|
||||
EXPECT_EQ(player->status1, STATUS1_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,167 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
TO_DO_BATTLE_TEST("Charge doubles the damage of the next Electric move of the user");
|
||||
TO_DO_BATTLE_TEST("Charge's effect is removed regardless if the next move is Electric or not (Gen 3-8)");
|
||||
TO_DO_BATTLE_TEST("Charge's effect is kept until the user uses an Electric move (Gen 9+)");
|
||||
TO_DO_BATTLE_TEST("Charge's effect is removed if the user fails using an Electric move (Gen 9+)");
|
||||
TO_DO_BATTLE_TEST("Charge's effect does not stack with Electromorphosis");
|
||||
TO_DO_BATTLE_TEST("Charge's effect does not stack with Wind Power");
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_THUNDERBOLT].power != 0);
|
||||
ASSUME(gMovesInfo[MOVE_THUNDERBOLT].type == TYPE_ELECTRIC);
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Charge doubles the damage of the next Electric move of the user")
|
||||
{
|
||||
s16 normalDamage = 0;
|
||||
s16 chargedUpDamage = 0;
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_THUNDERBOLT); }
|
||||
TURN { MOVE(player, MOVE_CHARGE); }
|
||||
TURN { MOVE(player, MOVE_THUNDERBOLT); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player);
|
||||
HP_BAR(opponent, captureDamage: &normalDamage);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARGE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player);
|
||||
HP_BAR(opponent, captureDamage: &chargedUpDamage);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(normalDamage, Q_4_12(2.0), chargedUpDamage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Charge's effect is kept until the user uses an Electric move (Gen 9+)")
|
||||
{
|
||||
s16 normalDamage = 0;
|
||||
s16 chargedUpDamage = 0;
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_THUNDERBOLT); }
|
||||
TURN { MOVE(player, MOVE_CHARGE); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
TURN { MOVE(player, MOVE_THUNDERBOLT); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player);
|
||||
HP_BAR(opponent, captureDamage: &normalDamage);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARGE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player);
|
||||
HP_BAR(opponent, captureDamage: &chargedUpDamage);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(normalDamage, Q_4_12(2.0), chargedUpDamage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Charge's effect is removed if the user fails using an Electric move (Gen 9+)")
|
||||
{
|
||||
s16 damage[2];
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_THUNDER); }
|
||||
TURN { MOVE(player, MOVE_CHARGE); }
|
||||
TURN { MOVE(player, MOVE_THUNDER, hit: FALSE); }
|
||||
TURN { MOVE(player, MOVE_THUNDER); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDER, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[0]);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARGE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDER, player);
|
||||
HP_BAR(opponent, captureDamage: &damage[1]);
|
||||
} THEN {
|
||||
EXPECT_EQ(damage[0], damage[1]);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Charge's effect does not stack with Electromorphosis or Wind Power")
|
||||
{
|
||||
u32 species, ability;
|
||||
s16 normalDamage = 0;
|
||||
s16 chargedUpDamage = 0;
|
||||
|
||||
PARAMETRIZE { species = SPECIES_WATTREL; ability = ABILITY_WIND_POWER; }
|
||||
PARAMETRIZE { species = SPECIES_TADBULB; ability = ABILITY_ELECTROMORPHOSIS; }
|
||||
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_AIR_CUTTER].windMove == TRUE);
|
||||
PLAYER(species) { Ability(ability); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_THUNDERBOLT); }
|
||||
TURN { MOVE(player, MOVE_CHARGE); MOVE(opponent, MOVE_AIR_CUTTER); }
|
||||
TURN { MOVE(player, MOVE_THUNDERBOLT); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player);
|
||||
HP_BAR(opponent, captureDamage: &normalDamage);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARGE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_AIR_CUTTER, opponent);
|
||||
ABILITY_POPUP(player, ability);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player);
|
||||
HP_BAR(opponent, captureDamage: &chargedUpDamage);
|
||||
} THEN {
|
||||
EXPECT_MUL_EQ(normalDamage, Q_4_12(2.0), chargedUpDamage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Charge's effect is removed regardless if the next move is Electric or not (Gen 3-8)")
|
||||
{
|
||||
s16 normalDamage = 0;
|
||||
s16 chargedUpDamage = 0;
|
||||
|
||||
GIVEN {
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].type != TYPE_ELECTRIC);
|
||||
ASSUME(gMovesInfo[MOVE_TACKLE].power != 0);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_THUNDERBOLT); }
|
||||
TURN { MOVE(player, MOVE_CHARGE); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); }
|
||||
TURN { MOVE(player, MOVE_THUNDERBOLT); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player);
|
||||
HP_BAR(opponent, captureDamage: &normalDamage);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARGE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player);
|
||||
HP_BAR(opponent, captureDamage: &chargedUpDamage);
|
||||
} THEN {
|
||||
if (B_CHARGE < GEN_9)
|
||||
EXPECT_EQ(normalDamage, chargedUpDamage);
|
||||
else
|
||||
EXPECT_MUL_EQ(normalDamage, Q_4_12(2.0), chargedUpDamage);
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Charge will not expire if it flinches twice in a row")
|
||||
{
|
||||
s16 normalDamage = 0;
|
||||
s16 chargedUpDamage = 0;
|
||||
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_LUM_BERRY); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_THUNDERBOLT); }
|
||||
TURN { MOVE(player, MOVE_CHARGE); }
|
||||
TURN { MOVE(opponent, MOVE_IRON_HEAD); MOVE(player, MOVE_THUNDERBOLT); }
|
||||
TURN { MOVE(opponent, MOVE_IRON_HEAD); MOVE(player, MOVE_THUNDERBOLT); }
|
||||
TURN { MOVE(player, MOVE_THUNDERBOLT); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player);
|
||||
HP_BAR(opponent, captureDamage: &normalDamage);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHARGE, player);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_THUNDERBOLT, player);
|
||||
HP_BAR(opponent, captureDamage: &chargedUpDamage);
|
||||
} THEN {
|
||||
if (B_CHARGE < GEN_9)
|
||||
EXPECT_EQ(normalDamage, chargedUpDamage);
|
||||
else
|
||||
EXPECT_MUL_EQ(normalDamage, Q_4_12(2.0), chargedUpDamage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ SINGLE_BATTLE_TEST("Chilly Reception sets up snow and switches the user out")
|
||||
MESSAGE("Slowking is preparing to tell a chillingly bad joke!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHILLY_RECEPTION, player);
|
||||
MESSAGE("It started to snow!");
|
||||
MESSAGE("Slowking went back to 1");
|
||||
MESSAGE("Slowking went back to 1!");
|
||||
SEND_IN_MESSAGE("Slowpoke");
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_SNOW_CONTINUES);
|
||||
}
|
||||
@ -36,7 +36,7 @@ SINGLE_BATTLE_TEST("Chilly Reception switches the user out, even if the weather
|
||||
MESSAGE("Slowking is preparing to tell a chillingly bad joke!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHILLY_RECEPTION, player);
|
||||
MESSAGE("There is no relief from this heavy rain!");
|
||||
MESSAGE("Slowking went back to 1");
|
||||
MESSAGE("Slowking went back to 1!");
|
||||
SEND_IN_MESSAGE("Slowpoke");
|
||||
MESSAGE("Rain continues to fall.");
|
||||
}
|
||||
@ -53,7 +53,7 @@ SINGLE_BATTLE_TEST("Chilly Reception does not switch the user out if no replacem
|
||||
MESSAGE("Slowking is preparing to tell a chillingly bad joke!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHILLY_RECEPTION, player);
|
||||
MESSAGE("It started to snow!");
|
||||
NOT MESSAGE("Slowking went back to 1");
|
||||
NOT MESSAGE("Slowking went back to 1!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ SINGLE_BATTLE_TEST("Chilly Reception does not switch the user out if replacement
|
||||
MESSAGE("Slowking is preparing to tell a chillingly bad joke!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHILLY_RECEPTION, player);
|
||||
MESSAGE("It started to snow!");
|
||||
NOT MESSAGE("Slowking went back to 1");
|
||||
NOT MESSAGE("Slowking went back to 1!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ SINGLE_BATTLE_TEST("Chilly Reception changes the weather, even if the user canno
|
||||
MESSAGE("Slowking is preparing to tell a chillingly bad joke!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_CHILLY_RECEPTION, player);
|
||||
MESSAGE("It started to snow!");
|
||||
NOT MESSAGE("Slowking went back to 1");
|
||||
NOT MESSAGE("Slowking went back to 1!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
218
test/battle/move_effect/instruct.c
Normal file
218
test/battle/move_effect/instruct.c
Normal file
@ -0,0 +1,218 @@
|
||||
#include "global.h"
|
||||
#include "test/battle.h"
|
||||
|
||||
ASSUMPTIONS
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_INSTRUCT].effect == EFFECT_INSTRUCT);
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Instruct fails if target hasn't made a move")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_CELEBRATE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerLeft, MOVE_INSTRUCT, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); }
|
||||
} SCENE {
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Instruct fails if move is banned by Instruct")
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_BIDE].instructBanned == TRUE);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_BIDE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_BIDE); MOVE(playerLeft, MOVE_INSTRUCT, target: playerRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_BIDE, playerRight);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Instruct-called move targets the target of the move picked on its last use")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_FAKE_OUT); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, MOVE_INSTRUCT, target: playerRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
|
||||
HP_BAR(opponentLeft);
|
||||
NOT HP_BAR(opponentRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
|
||||
HP_BAR(opponentLeft);
|
||||
NOT HP_BAR(opponentRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Instruct doesn't bypass sleep")
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(opponentLeft, MOVE_SPORE, target: playerRight); MOVE(playerLeft, MOVE_INSTRUCT, target: playerRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_SPORE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
|
||||
MESSAGE("Wobbuffet is fast asleep.");
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Instruct fails if target doesn't know the last move it used")
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_ORICORIO) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_CELEBRATE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_DRAGON_DANCE); MOVE(playerLeft, MOVE_INSTRUCT, target: playerRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DANCE, opponentLeft);
|
||||
ABILITY_POPUP(playerRight, ABILITY_DANCER);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DANCE, playerRight);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DRAGON_DANCE, playerRight);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Instruct-called move fails if it can only be used on the first turn but consumes PP")
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_FAKE_OUT].effect == EFFECT_FIRST_TURN_ONLY);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_FAKE_OUT); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_FAKE_OUT, target: opponentLeft); MOVE(playerLeft, MOVE_INSTRUCT, target: playerRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_FAKE_OUT, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_FAKE_OUT, playerRight);
|
||||
} THEN {
|
||||
EXPECT_EQ(playerRight->pp[3], gMovesInfo[MOVE_FAKE_OUT].pp - 2);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Instruct-called move doesn't fail if tormented")
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_TORMENT].effect == EFFECT_TORMENT);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_FAKE_OUT); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(opponentLeft, MOVE_TORMENT, target: playerRight); MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(playerLeft, MOVE_INSTRUCT, target: playerRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TORMENT, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Instruct-called status moves don't fail if holding Assault Vest")
|
||||
{
|
||||
ASSUME(gItemsInfo[ITEM_ASSAULT_VEST].holdEffect == HOLD_EFFECT_ASSAULT_VEST);
|
||||
ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_TRICK); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ASSAULT_VEST); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_TRICK, target: opponentLeft); MOVE(playerLeft, MOVE_INSTRUCT, target: playerRight); MOVE(opponentLeft, MOVE_TACKLE, target: playerLeft); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRICK, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TRICK, playerRight);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Instruct-called status move fails if taunted")
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_TAUNT].effect == EFFECT_TAUNT);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_GROWL); MOVE(opponentLeft, MOVE_TAUNT, target: playerRight); MOVE(playerLeft, MOVE_INSTRUCT, target: playerRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_GROWL, playerRight);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TAUNT, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
|
||||
NONE_OF {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_GROWL, playerRight);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentRight);
|
||||
ANIMATION(ANIM_TYPE_GENERAL, B_ANIM_STATS_CHANGE, opponentLeft);
|
||||
}
|
||||
} THEN {
|
||||
EXPECT_EQ(playerRight->pp[3], gMovesInfo[MOVE_GROWL].pp - 1);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Instruct-called moves fail if disabled")
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_DISABLE].effect == EFFECT_DISABLE);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_TACKLE, target: opponentLeft); MOVE(opponentLeft, MOVE_DISABLE, target: playerRight); MOVE(playerLeft, MOVE_INSTRUCT, target: playerRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_DISABLE, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_TACKLE, playerRight);
|
||||
} THEN {
|
||||
EXPECT_EQ(playerRight->pp[0], gMovesInfo[MOVE_TACKLE].pp - 1);
|
||||
}
|
||||
}
|
||||
|
||||
DOUBLE_BATTLE_TEST("Instruct-called moves keep their priority")
|
||||
{
|
||||
ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1);
|
||||
ASSUME(gMovesInfo[MOVE_PSYCHIC_TERRAIN].effect == EFFECT_PSYCHIC_TERRAIN);
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_QUICK_ATTACK); }
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(playerRight, MOVE_QUICK_ATTACK, target: opponentLeft); MOVE(opponentLeft, MOVE_PSYCHIC_TERRAIN, target: playerRight); MOVE(playerLeft, MOVE_INSTRUCT, target: playerRight); }
|
||||
} SCENE {
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_QUICK_ATTACK, playerRight);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_PSYCHIC_TERRAIN, opponentLeft);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_INSTRUCT, playerLeft);
|
||||
NOT ANIMATION(ANIM_TYPE_MOVE, MOVE_QUICK_ATTACK, playerRight);
|
||||
}
|
||||
}
|
||||
@ -85,3 +85,16 @@ SINGLE_BATTLE_TEST("Shed Tail's HP cost doesn't trigger effects that trigger on
|
||||
NOT MESSAGE("Wobbuffet's Air Balloon popped!");
|
||||
}
|
||||
}
|
||||
|
||||
AI_SINGLE_BATTLE_TEST("AI will use Shed Tail to pivot to another mon while in damage stalemate with player")
|
||||
{
|
||||
GIVEN {
|
||||
AI_FLAGS(AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_CHECK_VIABILITY | AI_FLAG_TRY_TO_FAINT);
|
||||
PLAYER(SPECIES_WOBBUFFET) { Speed(100); Ability(ABILITY_RUN_AWAY); Moves(MOVE_TACKLE, MOVE_CELEBRATE); }
|
||||
OPPONENT(SPECIES_WOBBUFFET) { Speed(50); Ability(ABILITY_RUN_AWAY); Moves(MOVE_CONFUSION, MOVE_SHED_TAIL); }
|
||||
OPPONENT(SPECIES_SCIZOR) { Speed(101); Moves(MOVE_CELEBRATE, MOVE_X_SCISSOR); }
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, MOVE_CONFUSION); }
|
||||
TURN { MOVE(player, MOVE_TACKLE); EXPECT_MOVE(opponent, MOVE_SHED_TAIL); }
|
||||
}
|
||||
}
|
||||
|
||||
@ -238,3 +238,36 @@ DOUBLE_BATTLE_TEST("Sticky Web has correct interactions with Mirror Armor - no o
|
||||
EXPECT_EQ(opponentRight->statStages[STAT_SPEED], DEFAULT_STAT_STAGE);
|
||||
}
|
||||
}
|
||||
SINGLE_BATTLE_TEST("Sticky Web is placed on the correct side after Explosion")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_EXPLOSION); MOVE(opponent, MOVE_STICKY_WEB); SEND_OUT(player, 1);}
|
||||
} SCENE {
|
||||
HP_BAR(player, hp: 0);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_EXPLOSION, player);
|
||||
MESSAGE("Wobbuffet fainted!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, opponent);
|
||||
MESSAGE("A sticky web spreads out on the ground around your team!");
|
||||
}
|
||||
}
|
||||
|
||||
SINGLE_BATTLE_TEST("Sticky Web is placed on the correct side after Memento")
|
||||
{
|
||||
GIVEN {
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
PLAYER(SPECIES_WOBBUFFET);
|
||||
OPPONENT(SPECIES_WOBBUFFET);
|
||||
} WHEN {
|
||||
TURN { MOVE(player, MOVE_MEMENTO); MOVE(opponent, MOVE_STICKY_WEB); SEND_OUT(player, 1); }
|
||||
} SCENE {
|
||||
HP_BAR(player, hp: 0);
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_MEMENTO, player);
|
||||
MESSAGE("Wobbuffet fainted!");
|
||||
ANIMATION(ANIM_TYPE_MOVE, MOVE_STICKY_WEB, opponent);
|
||||
MESSAGE("A sticky web spreads out on the ground around your team!");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user