Merge branch 'upcoming' into signpost

This commit is contained in:
psf 2024-09-05 17:11:32 -07:00 committed by GitHub
commit 0e1b62c732
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
106 changed files with 4811 additions and 4304 deletions

View File

@ -1674,14 +1674,56 @@
callnative BS_FickleBeamDamageCalculation
.endm
@ various command changed to more readable macros
.macro cancelmultiturnmoves battler:req
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES
.macro trytarshot failInstr:req
callnative BS_TryTarShot
.4byte \failInstr
.endm
.macro jumpifteainvulnerable battler:req, jumpInstr:req
callnative BS_TeatimeInvul
.byte \battler
.4byte \jumpInstr
.endm
.macro jumpifteanoberry failInstr:req
callnative BS_TeatimeTargets
.4byte \failInstr
.endm
.macro trywindriderpower battler:req, failInstr:req
callnative BS_TryWindRiderPower
.byte \battler
.4byte \failInstr
.endm
.macro activateweatherchangeabilities battler:req
callnative BS_ActivateWeatherChangeAbilities
.byte \battler
.endm
.macro activateterrainchangeabilities battler:req
callnative BS_ActivateTerrainChangeAbilities
.byte \battler
.endm
@ Stores Healing Wish effect.
.macro storehealingwish battler:req
various \battler, VARIOUS_STORE_HEALING_WISH
callnative BS_StoreHealingWish
.byte \battler
.endm
.macro hitswitchtargetfailed
callnative BS_HitSwitchTargetFailed
.endm
.macro tryrevivalblessing, failInstr:req
callnative BS_TryRevivalBlessing
.4byte \failInstr
.endm
@ various command changed to more readable macros
.macro cancelmultiturnmoves battler:req
various \battler, VARIOUS_CANCEL_MULTI_TURN_MOVES
.endm
.macro setmagiccoattarget battler:req
@ -2210,11 +2252,6 @@
.4byte \failInstr
.endm
.macro trytarshot battler:req, failInstr:req
various \battler, VARIOUS_TRY_TAR_SHOT
.4byte \failInstr
.endm
.macro cantarshotwork battler:req, failInstr:req
various \battler, VARIOUS_CAN_TAR_SHOT_WORK
.4byte \failInstr
@ -2230,16 +2267,6 @@
.4byte \failInstr
.endm
.macro jumpifteanoberry jumpInstr:req
various BS_ATTACKER, VARIOUS_TEATIME_TARGETS
.4byte \jumpInstr
.endm
.macro jumpifteainvulnerable battler:req, jumpInstr:req
various \battler, VARIOUS_TEATIME_INVUL
.4byte \jumpInstr
.endm
.macro curecertainstatuses battler:req
various \battler, VARIOUS_CURE_CERTAIN_STATUSES
.endm
@ -2284,19 +2311,6 @@
.byte \stat
.endm
.macro trywindriderpower battler:req, failInstr:req
various \battler, VARIOUS_TRY_WIND_RIDER_POWER
.4byte \failInstr
.endm
.macro activateweatherchangeabilities battler:req
various \battler, VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES
.endm
.macro activateterrainchangeabilities battler:req
various \battler, VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES
.endm
@ helpful macros
.macro setstatchanger stat:req, stages:req, down:req
setbyte sSTATCHANGER, \stat | \stages << 3 | \down << 7
@ -2491,15 +2505,6 @@
waitmessage B_WAIT_TIME_LONG
.endm
.macro hitswitchtargetfailed
various 0, VARIOUS_HIT_SWITCH_TARGET_FAILED
.endm
.macro tryrevivalblessing, jumpInstr:req
various 0, VARIOUS_TRY_REVIVAL_BLESSING
.4byte \jumpInstr
.endm
@ Will jump to script pointer if the specified battler has or has not fainted.
.macro jumpiffainted battler:req, value:req, ptr:req
getbattlerfainted \battler

View File

@ -2321,3 +2321,20 @@
.macro togglefakertc
callnative Script_ToggleFakeRtc
.endm
@ ============================ @
@ ITEM DESCRIPTION HEADER MACROS
@ Used with OW_SHOW_ITEM_DESCRIPTIONS config
.macro showitemdescription
callnative ScriptShowItemDescription
.byte 0
.endm
.macro showberrydescription
callnative ScriptShowItemDescription
.byte 1
.endm
.macro hideitemdescription
callnative ScriptHideItemDescription
.endm

View File

@ -45,6 +45,7 @@ SUPER_ER = 2C
LV = 34
'=' = 35
';' = 36
V_D_ARROW = 38
'¿' = 51
'¡' = 52
PK = 53

File diff suppressed because it is too large Load Diff

View File

@ -902,7 +902,7 @@ BattleScript_EffectTarShot::
printfromtable gStatDownStringIds
waitmessage B_WAIT_TIME_LONG
BattleScript_TryTarShot:
trytarshot BS_TARGET, BattleScript_MoveEnd
trytarshot BattleScript_MoveEnd
printstring STRINGID_PKMNBECAMEWEAKERTOFIRE
waitmessage B_WAIT_TIME_LONG
goto BattleScript_MoveEnd

View File

@ -1108,7 +1108,6 @@ EventScript_VsSeekerChargingDone::
.include "data/text/contest_strings.inc"
.include "data/text/contest_link.inc"
.include "data/text/contest_painting.inc"
.include "data/text/trick_house_mechadolls.inc"
.include "data/scripts/tv.inc"
.include "data/text/tv.inc"
.include "data/scripts/interview.inc"

View File

@ -111,6 +111,7 @@ MtChimney_EventScript_LavaCookieLady::
msgbox MtChimney_Text_ThankYouDear, MSGBOX_DEFAULT
checkitemspace ITEM_LAVA_COOKIE
call_if_eq VAR_RESULT, TRUE, MtChimney_EventScript_RemoveMoney
.if OW_SHOW_ITEM_DESCRIPTIONS == OW_ITEM_DESCRIPTIONS_OFF
giveitem ITEM_LAVA_COOKIE
goto_if_eq VAR_RESULT, FALSE, MtChimney_EventScript_BagIsFull
hidemoneybox
@ -122,6 +123,19 @@ MtChimney_EventScript_BagIsFull::
hidemoneybox
release
end
.else
hidemoneybox
giveitem ITEM_LAVA_COOKIE
goto_if_eq VAR_RESULT, FALSE, MtChimney_EventScript_BagIsFull
release
end
MtChimney_EventScript_BagIsFull::
msgbox gText_TooBadBagIsFull, MSGBOX_DEFAULT
release
end
.endif @ OW_SHOW_ITEM_DESCRIPTIONS
MtChimney_EventScript_RemoveMoney::
removemoney 200

View File

@ -52,8 +52,13 @@ Route109_SeashoreHouse_EventScript_BuySodaPop::
msgbox Route109_SeashoreHouse_Text_HereYouGo, MSGBOX_DEFAULT
removemoney 300
updatemoneybox
.if OW_SHOW_ITEM_DESCRIPTIONS != OW_ITEM_DESCRIPTIONS_OFF
hidemoneybox
giveitem ITEM_SODA_POP
.else
giveitem ITEM_SODA_POP
hidemoneybox
.endif
release
end

View File

@ -176,6 +176,8 @@ BerryTree_EventScript_PickBerry::
special IncrementDailyPickedBerries
special ObjectEventInteractionRemoveBerryTree
message BerryTree_Text_PickedTheBerry
delay 10
showberrydescription
playfanfare MUS_OBTAIN_BERRY
waitmessage
waitfanfare
@ -183,6 +185,7 @@ BerryTree_EventScript_PickBerry::
message BerryTree_Text_PutAwayBerry
waitmessage
waitbuttonpress
hideitemdescription
release
end

View File

@ -2,6 +2,7 @@
.set AMOUNT, VAR_0x8001
Std_ObtainItem::
copyvar VAR_0x8006, ITEMID
additem ITEMID, AMOUNT
copyvar VAR_0x8007, VAR_RESULT
call EventScript_ObtainItemMessage
@ -58,8 +59,11 @@ EventScript_ObtainedItem::
EventScript_ObtainedItemMessage:
message gText_ObtainedTheItem
EventScript_ContinueObtainedItem:
delay 10
showitemdescription
waitfanfare
msgbox gText_PutItemInPocket, MSGBOX_DEFAULT
hideitemdescription
setvar VAR_RESULT, TRUE
return
@ -103,6 +107,7 @@ Std_FindItem::
lock
faceplayer
waitse
copyvar VAR_0x8006, ITEMID
copyvar VAR_0x8004, ITEMID
copyvar VAR_0x8005, AMOUNT
checkitemspace ITEMID, AMOUNT
@ -118,20 +123,25 @@ Std_FindItem::
EventScript_PickUpItem::
removeobject VAR_LAST_TALKED
additem VAR_0x8004, VAR_0x8005
copyvar VAR_0x8006 VAR_0x8004
specialvar VAR_RESULT, BufferTMHMMoveName
copyvar VAR_0x8008, VAR_RESULT
call_if_eq VAR_0x8008, TRUE, EventScript_FoundTMHM
call_if_eq VAR_0x8008, FALSE, EventScript_FoundItem
delay 10
showitemdescription
waitfanfare
waitmessage
bufferitemnameplural STR_VAR_2, VAR_0x8004, VAR_0x8005
pyramid_inchallenge
goto_if_eq VAR_RESULT, TRUE, EventScript_PutBattlePyramidItemInBag
msgbox gText_PutItemInPocket, MSGBOX_DEFAULT
hideitemdescription
return
EventScript_PutBattlePyramidItemInBag::
msgbox gText_PlayerPutItemInBag, MSGBOX_DEFAULT
hideitemdescription
return
EventScript_FoundTMHM::
@ -165,6 +175,7 @@ EventScript_NoRoomToPickUpItem::
EventScript_HiddenItemScript::
lockall
waitse
copyvar VAR_0x8006, VAR_0x8005
additem VAR_0x8005
copyvar VAR_0x8007, VAR_RESULT
bufferitemnameplural STR_VAR_2, VAR_0x8005, 1
@ -194,11 +205,14 @@ EventScript_FoundHiddenItem::
end
EventScript_PutHiddenItemInPocket::
delay 10
showitemdescription
waitmessage
waitfanfare
bufferitemnameplural STR_VAR_2, VAR_0x8004, 1
copyvar VAR_0x8004, VAR_0x8008
msgbox gText_PutItemInPocket, MSGBOX_DEFAULT
hideitemdescription
special TryPutTreasureInvestigatorsOnAir
special SetHiddenItemFlag
releaseall

View File

@ -1,134 +0,0 @@
gTrickHouse_Mechadoll_Oddish::
.string "ODDISH$"
gTrickHouse_Mechadoll_Poochyena::
.string "POOCHYENA$"
gTrickHouse_Mechadoll_Taillow::
.string "TAILLOW$"
gTrickHouse_Mechadoll_Azurill::
.string "AZURILL$"
gTrickHouse_Mechadoll_Lotad::
.string "LOTAD$"
gTrickHouse_Mechadoll_Wingull::
.string "WINGULL$"
gTrickHouse_Mechadoll_Dustox::
.string "DUSTOX$"
gTrickHouse_Mechadoll_Zubat::
.string "ZUBAT$"
gTrickHouse_Mechadoll_Nincada::
.string "NINCADA$"
gTrickHouse_Mechadoll_Ralts::
.string "RALTS$"
gTrickHouse_Mechadoll_Zigzagoon::
.string "ZIGZAGOON$"
gTrickHouse_Mechadoll_Slakoth::
.string "SLAKOTH$"
gTrickHouse_Mechadoll_Poochyena2::
.string "POOCHYENA$"
gTrickHouse_Mechadoll_Shroomish::
.string "SHROOMISH$"
gTrickHouse_Mechadoll_Zigzagoon2::
.string "ZIGZAGOON$"
gTrickHouse_Mechadoll_Poochyena3::
.string "POOCHYENA$"
gTrickHouse_Mechadoll_Zubat2::
.string "ZUBAT$"
gTrickHouse_Mechadoll_Carvanha::
.string "CARVANHA$"
gTrickHouse_Mechadoll_BurnHeal::
.string "BURN HEAL$"
gTrickHouse_Mechadoll_HarborMail::
.string "HARBOR MAIL$"
gTrickHouse_Mechadoll_SamePrice::
.string "Same price$"
gTrickHouse_Mechadoll_60Yen::
.string "¥60$"
gTrickHouse_Mechadoll_55Yen::
.string "¥55$"
gTrickHouse_Mechadoll_Nothing::
.string "Nothing$"
gTrickHouse_Mechadoll_CostMore::
.string "They will cost more.$"
gTrickHouse_Mechadoll_CostLess::
.string "They will cost less.$"
gTrickHouse_Mechadoll_SamePrice2::
.string "Same price$"
gTrickHouse_Mechadoll_Male::
.string "Male$"
gTrickHouse_Mechadoll_Female::
.string "Female$"
gTrickHouse_Mechadoll_Neither::
.string "Neither$"
gTrickHouse_Mechadoll_ElderlyMen::
.string "Elderly men$"
gTrickHouse_Mechadoll_ElderlyLadies::
.string "Elderly ladies$"
gTrickHouse_Mechadoll_SameNumber::
.string "Same number$"
gTrickHouse_Mechadoll_None::
.string "None$"
gTrickHouse_Mechadoll_One::
.string "1$"
gTrickHouse_Mechadoll_Two::
.string "2$"
gTrickHouse_Mechadoll_Two2::
.string "2$"
gTrickHouse_Mechadoll_Three::
.string "3$"
gTrickHouse_Mechadoll_Four::
.string "4$"
gTrickHouse_Mechadoll_Six::
.string "6$"
gTrickHouse_Mechadoll_Seven::
.string "7$"
gTrickHouse_Mechadoll_Eight::
.string "8$"
gTrickHouse_Mechadoll_Six2::
.string "6$"
gTrickHouse_Mechadoll_Seven2::
.string "7$"
gTrickHouse_Mechadoll_Eight2::
.string "8$"

View File

@ -42,8 +42,8 @@ This flag is divided into two components to calculate the best available move fo
This is different to `AI_FLAG_CHECK_BAD_MOVE` as it calculates how poor a move is and not whether it will fail or not.
## `AI_FLAG_SETUP_FIRST_TURN`
AI will prioritize using setup moves on the first turn. These include stat buffs, field effects, status moves, etc.
## `AI_FLAG_FORCE_SETUP_FIRST_TURN`
AI will prioritize using setup moves on the first turn at the expense of all else. These include stat buffs, field effects, status moves, etc. AI_FLAG_CHECK_VIABILITY will instead do this when the AI determines it makes sense.
This is just a flat increase without any consideration of whether it makes sense to use the move or not. For better move choice quality for those moves, `AI_FLAG_CHECK_VIABILITY` should be used.

View File

@ -53,6 +53,7 @@
#define CHAR_EQUALS 0x35
#define CHAR_SEMICOLON 0x36
#define CHAR_BARD_WORD_DELIMIT 0x37 // Empty space to separate words in Bard's song
#define CHAR_V_D_ARROW 0x38
#define CHAR_INV_QUESTION_MARK 0x51
#define CHAR_INV_EXCL_MARK 0x52
#define CHAR_PK 0x53

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
237 28 36
251 239 143
247 228 69
234 209 76
222 186 48
160 113 22
255 255 16
213 222 32
255 255 255
222 153 4
222 171 55
230 188 67
247 210 69
0 0 0
0 0 0
0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
237 28 36
185 255 175
142 243 140
56 177 78
78 214 109
48 126 26
44 177 68
65 206 48
8 248 0
24 189 2
90 189 77
97 210 101
137 226 120
0 0 0
0 0 0
0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
237 28 36
253 242 242
251 225 225
255 210 226
255 198 218
255 181 206
244 159 183
247 187 187
249 210 210
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1003 B

View File

@ -0,0 +1,19 @@
JASC-PAL
0100
16
237 28 36
213 206 232
206 186 224
203 168 232
204 145 230
192 87 219
156 51 183
111 36 130
210 51 171
247 4 107
67 21 79
203 113 225
0 0 0
0 0 0
0 0 0
0 0 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 690 B

After

Width:  |  Height:  |  Size: 664 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 599 B

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 549 B

After

Width:  |  Height:  |  Size: 494 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 561 B

After

Width:  |  Height:  |  Size: 568 B

View File

@ -3,17 +3,17 @@ JASC-PAL
16
128 128 128
26 24 32
135 128 162
86 82 102
145 127 199
84 73 122
8 8 14
0 0 0
37 37 62
77 76 116
255 255 255
64 96 120
96 144 160
254 254 238
121 83 136
61 37 19
175 175 175
121 72 39
136 136 136
105 52 91
193 190 180
132 85 120
97 97 85
14 14 14
15 15 15

View File

@ -3,17 +3,17 @@ JASC-PAL
16
152 208 160
32 48 64
120 112 144
80 72 104
145 127 199
84 73 122
96 144 160
16 16 16
216 112 224
200 176 192
248 248 248
144 96 88
193 190 180
254 254 238
132 85 120
64 96 120
112 48 48
128 104 128
105 52 91
97 97 85
48 64 80
0 0 0
0 0 0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 638 B

After

Width:  |  Height:  |  Size: 592 B

View File

@ -3,17 +3,17 @@ JASC-PAL
16
152 208 160
32 48 64
120 112 144
145 127 199
16 16 16
80 72 104
84 73 122
96 144 160
200 176 192
248 248 248
193 190 180
254 254 238
64 96 120
144 96 88
112 48 48
132 85 120
105 52 91
40 176 224
128 104 128
97 97 85
48 64 80
0 0 0
0 0 0

File diff suppressed because it is too large Load Diff

View File

@ -203,6 +203,9 @@
// Flag and Var settings
#define B_RESET_FLAGS_VARS_AFTER_WHITEOUT TRUE // If TRUE, Overworld_ResetBattleFlagsAndVars will reset battle-related Flags and Vars when the player whites out.
// Ingame partner flag
#define B_SHOW_PARTNER_TARGET FALSE // Shows the battler partner will target.
// Terrain settings
#define B_TERRAIN_BG_CHANGE TRUE // If set to TRUE, terrain moves permanently change the default battle background until the effect fades.
#define B_THUNDERSTORM_TERRAIN TRUE // If TRUE, overworld Thunderstorm generates Rain and Electric Terrain as in Gen 8.

16
include/config/ev_caps.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef GUARD_CONFIG_EV_CAP_H
#define GUARD_CONFIG_EV_CAP_H
// Constants for EV Cap Types
#define EV_CAP_NONE 0 // Regular behavior, no EV caps are applied
#define EV_CAP_FLAG_LIST 1 // EV cap is chosen according to the first unset flag in `sEVCapFlagMap`
#define EV_CAP_VARIABLE 2 // EV cap is chosen according to the contents of the event variable specified by B_EV_CAP_VARIABLE
#define EV_CAP_NO_GAIN 3 // No EVs can be gained
// Configs for EV Cap
#define B_EV_CAP_TYPE EV_CAP_NONE // [EV_CAP_NONE, EV_CAP_FLAG_LIST, EV_CAP_VARIABLE, EV_CAP_NO_GAIN] choose the type of EV cap to apply#define B_EV_CAP_VARIABLE 12 // event variable used to derive EV cap if B_EV_CAP_TYPE is set to EV_CAP_VARIABLE
#define B_EV_CAP_VARIABLE 8 // event variable used to derive EV cap if B_EV_CAP_TYPE is set to EV_CAP_VARIABLE
#define B_EV_ITEMS_CAP FALSE // If set to true, EV-boosting items can't be used to go over the EV cap
#endif /*GUARD_CONFIG_EV_CAP_H*/

View File

@ -11,6 +11,12 @@
#define OW_HIDE_REPEAT_MAP_POPUP FALSE // If enabled, map popups will not appear if entering a map with the same Map Section Id as the last.
#define OW_FRLG_WHITEOUT FALSE // If enabled, shows an additional whiteout message and post whiteout event script with healing NPC.
// Item Obtain Description Box
#define OW_ITEM_DESCRIPTIONS_OFF 0 // never show descriptions
#define OW_ITEM_DESCRIPTIONS_FIRST_TIME 1 // show first time (** SAVE-BREAKING - see struct SaveBlock3 **)
#define OW_ITEM_DESCRIPTIONS_ALWAYS 2 // always show description
#define OW_SHOW_ITEM_DESCRIPTIONS OW_ITEM_DESCRIPTIONS_OFF // If enabled, item descriptions/images will be shown when finding items.
// These generational defines only make a distinction for Berries and the OW_PC_MOVE_ORDER
#define GEN_6_XY GEN_6
#define GEN_6_ORAS GEN_LATEST + 1
@ -69,6 +75,13 @@
#define OW_USE_FAKE_RTC FALSE // When TRUE, seconds on the in-game clock will only advance once every 60 playTimeVBlanks (every 60 frames).
#define OW_ALTERED_TIME_RATIO GEN_LATEST // In GEN_8_PLA, the time in game moves forward 60 seconds for every second in the RTC. In GEN_9, it is 20 seconds. This has no effect if OW_USE_FAKE_RTC is FALSE.
// Time-based wild Pokemon encounters - Allows you to create additional encounter groups in wild_encounters.json (or in porymap).
// The groups are processed by base label's suffix. For example, "gRoute101" (no suffix) contains daytime encounters, and "gRoute101_Night" contains nighttime encounters.
// Not every group needs to be defined for every map - you could for example omit them inside caves and it would fall back to the unsuffixed daytime encounter group.
#define OW_TIME_BASED_WILD_ENCOUNTERS FALSE // Enables the system. If disabled, all suffixes are ignored and the first encounter group found for a map will be used for wild encounters.
#define OW_ENABLE_MORNING_WILD_ENCOUNTERS FALSE // If true, allows definition of morning encounter groups such as "gRoute101_Morning". Otherwise, morning is considered to be day for encounters. No effect if OW_TIME_BASED_WILD_ENCOUNTERS is false.
#define OW_ENABLE_EVENING_WILD_ENCOUNTERS FALSE // If true, allows definition of evening encounter groups such as "gRoute101_Evening". Otherwise, evening is considered to be night for encounters. No effect if OW_TIME_BASED_WILD_ENCOUNTERS is false.
// Overworld flags
// To use the following features in scripting, replace the 0s with the flag ID you're assigning it to.
// Eg: Replace with FLAG_UNUSED_0x264 so you can use that flag to toggle the feature.

View File

@ -25,31 +25,36 @@
#define AI_EFFECTIVENESS_x0 0
// AI Flags. Most run specific functions to update score, new flags are used for internal logic in other scripts
#define AI_FLAG_CHECK_BAD_MOVE (1 << 0)
#define AI_FLAG_TRY_TO_FAINT (1 << 1)
#define AI_FLAG_CHECK_VIABILITY (1 << 2)
#define AI_FLAG_SETUP_FIRST_TURN (1 << 3)
#define AI_FLAG_RISKY (1 << 4)
#define AI_FLAG_PREFER_STRONGEST_MOVE (1 << 5)
#define AI_FLAG_PREFER_BATON_PASS (1 << 6)
#define AI_FLAG_DOUBLE_BATTLE (1 << 7) // Automatically set for double battles, handles AI behaviour with partner
#define AI_FLAG_HP_AWARE (1 << 8)
#define AI_FLAG_POWERFUL_STATUS (1 << 9) // AI prefers moves that set up field effects or side statuses, even if the user can faint the target
// See docs/ai_flags.md for more details.
#define AI_FLAG_CHECK_BAD_MOVE (1 << 0) // AI will avoid using moves that are likely to fail or be ineffective in the current situation.
#define AI_FLAG_TRY_TO_FAINT (1 << 1) // AI will prioritize KOing the player's mon if able.
#define AI_FLAG_CHECK_VIABILITY (1 << 2) // AI damaging moves and move effects to determine the best available move in the current situation.
#define AI_FLAG_FORCE_SETUP_FIRST_TURN (1 << 3) // AI will prioritize using setup moves on the first turn at the expensve of all else. AI_FLAG_CHECK_VIABILITY will instead do this when the AI determines it makes sense.
#define AI_FLAG_RISKY (1 << 4) // AI will generally behave more recklessly, prioritizing damage over accuracy, explosions, etc.
#define AI_FLAG_PREFER_STRONGEST_MOVE (1 << 5) // AI adds score bonus to any move the AI has that either OHKOs or 2HKOs the player.
#define AI_FLAG_PREFER_BATON_PASS (1 << 6) // AI prefers raising its own stats and setting for / using Baton Pass.
#define AI_FLAG_DOUBLE_BATTLE (1 << 7) // Automatically set for double battles, handles AI behaviour with partner.
#define AI_FLAG_HP_AWARE (1 << 8) // AI will favour certain move effects based on how much remaining HP it and the player's mon have.
#define AI_FLAG_POWERFUL_STATUS (1 << 9) // AI prefers moves that set up field effects or side statuses, even if the user can faint the target.
// New, Trainer Handicap Flags
#define AI_FLAG_NEGATE_UNAWARE (1 << 10) // AI is NOT aware of negating effects like wonder room, mold breaker, etc
#define AI_FLAG_WILL_SUICIDE (1 << 11) // AI will use explosion / self destruct / final gambit / etc
#define AI_FLAG_NEGATE_UNAWARE (1 << 10) // AI is NOT aware of negating effects like wonder room, mold breaker, etc.
#define AI_FLAG_WILL_SUICIDE (1 << 11) // AI will use explosion / self destruct / final gambit / etc.
// New, Trainer Strategy Flags
#define AI_FLAG_PREFER_STATUS_MOVES (1 << 12) // AI gets a score bonus for status moves. Should be combined with AI_FLAG_CHECK_BAD_MOVE to prevent using only status moves
#define AI_FLAG_STALL (1 << 13) // AI stalls battle and prefers secondary damage/trapping/etc. TODO not finished
#define AI_FLAG_PREFER_STATUS_MOVES (1 << 12) // AI gets a score bonus for status moves. Should be combined with AI_FLAG_CHECK_BAD_MOVE to prevent using only status moves.
#define AI_FLAG_STALL (1 << 13) // AI stalls battle and prefers secondary damage/trapping/etc. TODO not finished.
#define AI_FLAG_SMART_SWITCHING (1 << 14) // AI includes a lot more switching checks. Automatically includes AI_FLAG_SMART_MON_CHOICES.
#define AI_FLAG_ACE_POKEMON (1 << 15) // AI has an Ace Pokemon. The last Pokemon in the party will not be used until it's the last one remaining.
#define AI_FLAG_OMNISCIENT (1 << 16) // AI has full knowledge of player moves, abilities, hold items
#define AI_FLAG_OMNISCIENT (1 << 16) // AI has full knowledge of player moves, abilities, hold items.
#define AI_FLAG_SMART_MON_CHOICES (1 << 17) // AI will make smarter decisions when choosing which mon to send out mid-battle and after a KO, which are separate decisions. Automatically included by AI_FLAG_SMART_SWITCHING.
#define AI_FLAG_CONSERVATIVE (1 << 18) // AI assumes all moves will low roll damage
#define AI_FLAG_SEQUENCE_SWITCHING (1 << 19) // AI switches in mons in exactly party order, and never switches mid-battle
#define AI_FLAG_CONSERVATIVE (1 << 18) // AI assumes all moves will low roll damage.
#define AI_FLAG_SEQUENCE_SWITCHING (1 << 19) // AI switches in mons in exactly party order, and never switches mid-battle.
#define AI_FLAG_COUNT 20
// The following options are enough to have a basic/smart trainer. Any other addtion could make the trainer worse/better depending on the flag
#define AI_FLAG_BASIC_TRAINER (AI_FLAG_CHECK_BAD_MOVE | AI_FLAG_TRY_TO_FAINT | AI_FLAG_CHECK_VIABILITY)
#define AI_FLAG_SMART_TRAINER (AI_FLAG_BASIC_TRAINER | AI_FLAG_OMNISCIENT | AI_FLAG_SMART_SWITCHING | AI_FLAG_SMART_MON_CHOICES)
// 'other' ai logic flags
#define AI_FLAG_DYNAMIC_FUNC (1 << 28) // Create custom AI functions for specific battles via "setdynamicaifunc" cmd
#define AI_FLAG_ROAMING (1 << 29)

View File

@ -528,7 +528,7 @@
#define BG_CHLOROBLAST 80
#define BG_RAINBOW 81
// table ids for general animations (gBattleAnims_General)
// table ids for general animations (sBattleAnims_General)
#define B_ANIM_STATS_CHANGE 0
#define B_ANIM_SUBSTITUTE_FADE 1
#define B_ANIM_SUBSTITUTE_APPEAR 2
@ -583,7 +583,9 @@
#define B_ANIM_TERA_ACTIVATE 51
#define B_ANIM_SIMPLE_HEAL 52
// special animations table (gBattleAnims_Special)
#define NUM_B_ANIMS_GENERAL 53
// special animations table (sBattleAnims_Special)
#define B_ANIM_LVL_UP 0
#define B_ANIM_SWITCH_OUT_PLAYER_MON 1
#define B_ANIM_SWITCH_OUT_OPPONENT_MON 2
@ -593,7 +595,9 @@
#define B_ANIM_MON_TO_SUBSTITUTE 6
#define B_ANIM_CRITICAL_CAPTURE_THROW 7
// status animation table (gBattleAnims_StatusConditions)
#define NUM_B_ANIMS_SPECIAL 8
// status animation table (sBattleAnims_StatusConditions)
#define B_ANIM_STATUS_PSN 0
#define B_ANIM_STATUS_CONFUSION 1
#define B_ANIM_STATUS_BRN 2
@ -603,7 +607,8 @@
#define B_ANIM_STATUS_FRZ 6
#define B_ANIM_STATUS_CURSED 7
#define B_ANIM_STATUS_NIGHTMARE 8
#define B_ANIM_STATUS_WRAPPED 9 // does not actually exist
#define NUM_B_ANIMS_STATUS 9
// Tasks with return values often assign them to gBattleAnimArgs[7].
#define ARG_RET_ID 7

View File

@ -226,14 +226,6 @@
#define VARIOUS_SET_BEAK_BLAST 134
#define VARIOUS_SWAP_SIDE_STATUSES 135
#define VARIOUS_SWAP_STATS 136
#define VARIOUS_TEATIME_INVUL 137
#define VARIOUS_TEATIME_TARGETS 138
#define VARIOUS_TRY_WIND_RIDER_POWER 139
#define VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES 140
#define VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES 141
#define VARIOUS_STORE_HEALING_WISH 142
#define VARIOUS_HIT_SWITCH_TARGET_FAILED 143
#define VARIOUS_TRY_REVIVAL_BLESSING 144
// Cmd_manipulatedamage
#define DMG_CHANGE_SIGN 0

View File

@ -8,6 +8,7 @@
#include "config/level_caps.h"
#include "config/pokemon.h"
#include "config/overworld.h"
#include "config/ev_caps.h"
// Invalid Versions show as "----------" in Gen 4 and Gen 5's summary screen.
// In Gens 6 and 7, invalid versions instead show "a distant land" in the summary screen.

View File

@ -1736,6 +1736,7 @@
#define SPECIES_SANDSHREW_ALOLA SPECIES_SANDSHREW_ALOLAN
#define SPECIES_SANDSLASH_ALOLA SPECIES_SANDSLASH_ALOLAN
#define SPECIES_SHELLOS_EAST SPECIES_SHELLOS_EAST_SEA
#define SPECIES_SIRFETCH_D SPECIES_SIRFETCHD
#define SPECIES_SLIGGOO_HISUI SPECIES_SLIGGOO_HISUIAN
#define SPECIES_SLOWBRO_GALAR SPECIES_SLOWBRO_GALARIAN
#define SPECIES_SLOWKING_GALAR SPECIES_SLOWKING_GALARIAN

10
include/ev_caps.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef GUARD_EV_CAP_H
#define GUARD_EV_CAP_H
#if B_EV_CAP_TYPE != EV_CAP_NONE && B_EV_CAP_TYPE != EV_CAP_FLAG_LIST && B_EV_CAP_TYPE != EV_CAP_VARIABLE && B_EV_CAP_TYPE != EV_CAP_NO_GAIN
#error "Invalid choice for B_EV_CAP_TYPE, must be one of [EV_CAP_NONE, EV_CAP_FLAG_LIST, EV_CAP_VARIABLE, EV_CAP_NO_GAIN]"
#endif
u32 GetCurrentEVCap(void);
#endif /* GUARD_EV_CAP_H */

View File

@ -24,5 +24,6 @@ u16 GetFrontierBrainMonMove(u8 monId, u8 moveSlotId);
u8 GetFrontierBrainMonNature(u8 monId);
u8 GetFrontierBrainMonEvs(u8 monId, u8 evStatId);
s32 GetFronterBrainSymbol(void);
void ClearEnemyPartyAfterChallenge(void);
#endif // GUARD_FRONTIER_UTIL_H

View File

@ -200,12 +200,17 @@ struct Time
/*0x04*/ s8 seconds;
};
#include "constants/items.h"
#define ITEM_FLAGS_COUNT ((ITEMS_COUNT / 8) + ((ITEMS_COUNT % 8) ? 1 : 0))
struct SaveBlock3
{
#if OW_USE_FAKE_RTC
struct Time fakeRTC;
#endif
#if OW_SHOW_ITEM_DESCRIPTIONS == OW_ITEM_DESCRIPTIONS_FIRST_TIME
u8 itemFlags[ITEM_FLAGS_COUNT];
#endif
};
extern struct SaveBlock3 *gSaveBlock3Ptr;

View File

@ -155,4 +155,12 @@ bool32 Overworld_SendKeysToLinkIsRunning(void);
bool32 IsSendingKeysOverCable(void);
void ClearLinkPlayerObjectEvents(void);
// Item Description Headers
enum ItemObtainFlags
{
FLAG_GET_ITEM_OBTAINED,
FLAG_SET_ITEM_OBTAINED,
};
bool8 GetSetItemObtained(u16 item, enum ItemObtainFlags caseId);
#endif // GUARD_OVERWORLD_H

View File

@ -216,17 +216,6 @@ extern const u8 gMenuText_Confirm[];
extern const u8 gMenuText_Show[];
extern const u8 gMenuText_Give2[];
extern const u8 gText_WithdrawPokemon[];
extern const u8 gText_WithdrawMonDescription[];
extern const u8 gText_DepositPokemon[];
extern const u8 gText_DepositMonDescription[];
extern const u8 gText_MovePokemon[];
extern const u8 gText_MoveMonDescription[];
extern const u8 gText_MoveItems[];
extern const u8 gText_MoveItemsDescription[];
extern const u8 gText_SeeYa[];
extern const u8 gText_SeeYaDescription[];
extern const u8 gText_EggNickname[];
extern const u8 gText_Pokemon[];
extern const u8 gText_InParty[];
@ -1011,51 +1000,6 @@ extern const u8 gText_Yes[];
extern const u8 gText_No[];
extern const u8 gText_Challenge[];
extern const u8 gText_Info3[];
extern const u8 gTrickHouse_Mechadoll_Oddish[];
extern const u8 gTrickHouse_Mechadoll_Poochyena[];
extern const u8 gTrickHouse_Mechadoll_Taillow[];
extern const u8 gTrickHouse_Mechadoll_Azurill[];
extern const u8 gTrickHouse_Mechadoll_Lotad[];
extern const u8 gTrickHouse_Mechadoll_Wingull[];
extern const u8 gTrickHouse_Mechadoll_Dustox[];
extern const u8 gTrickHouse_Mechadoll_Zubat[];
extern const u8 gTrickHouse_Mechadoll_Nincada[];
extern const u8 gTrickHouse_Mechadoll_Ralts[];
extern const u8 gTrickHouse_Mechadoll_Zigzagoon[];
extern const u8 gTrickHouse_Mechadoll_Slakoth[];
extern const u8 gTrickHouse_Mechadoll_Poochyena2[];
extern const u8 gTrickHouse_Mechadoll_Shroomish[];
extern const u8 gTrickHouse_Mechadoll_Zigzagoon2[];
extern const u8 gTrickHouse_Mechadoll_Poochyena3[];
extern const u8 gTrickHouse_Mechadoll_Zubat2[];
extern const u8 gTrickHouse_Mechadoll_Carvanha[];
extern const u8 gTrickHouse_Mechadoll_BurnHeal[];
extern const u8 gTrickHouse_Mechadoll_HarborMail[];
extern const u8 gTrickHouse_Mechadoll_SamePrice[];
extern const u8 gTrickHouse_Mechadoll_60Yen[];
extern const u8 gTrickHouse_Mechadoll_55Yen[];
extern const u8 gTrickHouse_Mechadoll_Nothing[];
extern const u8 gTrickHouse_Mechadoll_CostMore[];
extern const u8 gTrickHouse_Mechadoll_CostLess[];
extern const u8 gTrickHouse_Mechadoll_SamePrice2[];
extern const u8 gTrickHouse_Mechadoll_Male[];
extern const u8 gTrickHouse_Mechadoll_Female[];
extern const u8 gTrickHouse_Mechadoll_Neither[];
extern const u8 gTrickHouse_Mechadoll_ElderlyMen[];
extern const u8 gTrickHouse_Mechadoll_ElderlyLadies[];
extern const u8 gTrickHouse_Mechadoll_SameNumber[];
extern const u8 gTrickHouse_Mechadoll_None[];
extern const u8 gTrickHouse_Mechadoll_One[];
extern const u8 gTrickHouse_Mechadoll_Two[];
extern const u8 gTrickHouse_Mechadoll_Two2[];
extern const u8 gTrickHouse_Mechadoll_Three[];
extern const u8 gTrickHouse_Mechadoll_Four[];
extern const u8 gTrickHouse_Mechadoll_Six[];
extern const u8 gTrickHouse_Mechadoll_Seven[];
extern const u8 gTrickHouse_Mechadoll_Eight[];
extern const u8 gTrickHouse_Mechadoll_Six2[];
extern const u8 gTrickHouse_Mechadoll_Seven2[];
extern const u8 gTrickHouse_Mechadoll_Eight2[];
// Pokédex strings
extern const u8 gText_SearchForPkmnBasedOnParameters[];
@ -1926,78 +1870,7 @@ extern const u8 BattlePyramid_Text_SixTrainersRemaining6[];
extern const u8 BattlePyramid_Text_SevenTrainersRemaining6[];
// PC strings
extern const u8 gText_ExitFromBox[];
extern const u8 gText_WhatDoYouWantToDo[];
extern const u8 gText_PleasePickATheme[];
extern const u8 gText_PickTheWallpaper[];
extern const u8 gText_PkmnIsSelected[];
extern const u8 gText_JumpToWhichBox[];
extern const u8 gText_DepositInWhichBox[];
extern const u8 gText_PkmnWasDeposited[];
extern const u8 gText_BoxIsFull2[];
extern const u8 gText_ReleaseThisPokemon[];
extern const u8 gText_PkmnWasReleased[];
extern const u8 gText_ByeByePkmn[];
extern const u8 gText_MarkYourPkmn[];
extern const u8 gText_ThatsYourLastPkmn[];
extern const u8 gText_YourPartysFull[];
extern const u8 gText_YoureHoldingAPkmn[];
extern const u8 gText_WhichOneWillYouTake[];
extern const u8 gText_YouCantReleaseAnEgg[];
extern const u8 gText_ContinueBoxOperations[];
extern const u8 gText_PkmnCameBack[];
extern const u8 gText_WasItWorriedAboutYou[];
extern const u8 gText_FourEllipsesExclamation[];
extern const u8 gText_PleaseRemoveTheMail[];
extern const u8 gText_GiveToAPkmn[];
extern const u8 gText_PlacedItemInBag[];
extern const u8 gText_BagIsFull2[];
extern const u8 gText_PutItemInBag[];
extern const u8 gText_ItemIsNowHeld[];
extern const u8 gText_ChangedToNewItem[];
extern const u8 gText_MailCantBeStored[];
extern const u8 gPCText_Cancel[];
extern const u8 gPCText_Store[];
extern const u8 gPCText_Withdraw[];
extern const u8 gPCText_Move[];
extern const u8 gPCText_Shift[];
extern const u8 gPCText_Place[];
extern const u8 gPCText_Summary[];
extern const u8 gPCText_Release[];
extern const u8 gPCText_Mark[];
extern const u8 gPCText_Jump[];
extern const u8 gPCText_Wallpaper[];
extern const u8 gPCText_Name[];
extern const u8 gPCText_Take[];
extern const u8 gPCText_Give[];
extern const u8 gPCText_Give[];
extern const u8 gPCText_Switch[];
extern const u8 gPCText_Bag[];
extern const u8 gPCText_Info[];
extern const u8 gPCText_Scenery1[];
extern const u8 gPCText_Scenery2[];
extern const u8 gPCText_Scenery3[];
extern const u8 gPCText_Etcetera[];
extern const u8 gPCText_Friends[];
extern const u8 gPCText_Forest[];
extern const u8 gPCText_City[];
extern const u8 gPCText_Desert[];
extern const u8 gPCText_Savanna[];
extern const u8 gPCText_Crag[];
extern const u8 gPCText_Volcano[];
extern const u8 gPCText_Snow[];
extern const u8 gPCText_Cave[];
extern const u8 gPCText_Beach[];
extern const u8 gPCText_Seafloor[];
extern const u8 gPCText_River[];
extern const u8 gPCText_Sky[];
extern const u8 gPCText_PolkaDot[];
extern const u8 gPCText_Pokecenter[];
extern const u8 gPCText_Machine[];
extern const u8 gPCText_Simple[];
extern const u8 gText_PartyFull[];
extern const u8 gText_Box[];
extern const u8 gText_JustOnePkmn[];
// battle main
extern const u8 gText_LinkStandby3[];

View File

@ -20,6 +20,7 @@ struct WildPokemonHeader
{
u8 mapGroup;
u8 mapNum;
u8 timeOfDay;
const struct WildPokemonInfo *landMonsInfo;
const struct WildPokemonInfo *waterMonsInfo;
const struct WildPokemonInfo *rockSmashMonsInfo;

View File

@ -3474,6 +3474,9 @@ $(POKEMONGFXDIR)/eiscue/overworld.4bpp: %.4bpp: %.png
$(POKEMONGFXDIR)/indeedee/overworld.4bpp: %.4bpp: %.png
$(GFX) $< $@ -mwidth 4 -mheight 4
$(POKEMONGFXDIR)/indeedee/female/overworld.4bpp: %.4bpp: %.png
$(GFX) $< $@ -mwidth 4 -mheight 4
$(POKEMONGFXDIR)/morpeko/overworld.4bpp: %.4bpp: %.png
$(GFX) $< $@ -mwidth 4 -mheight 4

View File

@ -46,7 +46,7 @@ EWRAM_DATA AiScoreFunc sDynamicAiFunc = NULL;
static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score);
static s32 AI_TryToFaint(u32 battlerAtk, u32 battlerDef, u32 move, s32 score);
static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score);
static s32 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32 score);
static s32 AI_ForceSetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32 score);
static s32 AI_Risky(u32 battlerAtk, u32 battlerDef, u32 move, s32 score);
static s32 AI_PreferStrongestMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score);
static s32 AI_PreferBatonPass(u32 battlerAtk, u32 battlerDef, u32 move, s32 score);
@ -64,7 +64,7 @@ static s32 (*const sBattleAiFuncTable[])(u32, u32, u32, s32) =
[0] = AI_CheckBadMove, // AI_FLAG_CHECK_BAD_MOVE
[1] = AI_TryToFaint, // AI_FLAG_TRY_TO_FAINT
[2] = AI_CheckViability, // AI_FLAG_CHECK_VIABILITY
[3] = AI_SetupFirstTurn, // AI_FLAG_SETUP_FIRST_TURN
[3] = AI_ForceSetupFirstTurn, // AI_FLAG_FORCE_SETUP_FIRST_TURN
[4] = AI_Risky, // AI_FLAG_RISKY
[5] = AI_PreferStrongestMove, // AI_FLAG_PREFER_STRONGEST_MOVE
[6] = AI_PreferBatonPass, // AI_FLAG_PREFER_BATON_PASS
@ -891,7 +891,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
break;
case ABILITY_WONDER_GUARD:
if (effectiveness < AI_EFFECTIVENESS_x2)
return 0;
RETURN_SCORE_MINUS(20);
break;
case ABILITY_JUSTIFIED:
if (moveType == TYPE_DARK && !IS_MOVE_STATUS(move))
@ -1500,7 +1500,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
break;
case EFFECT_OHKO:
if (B_SHEER_COLD_IMMUNITY >= GEN_7 && move == MOVE_SHEER_COLD && IS_BATTLER_OF_TYPE(battlerDef, TYPE_ICE))
return 0;
RETURN_SCORE_MINUS(20);
if (!ShouldTryOHKO(battlerAtk, battlerDef, aiData->abilities[battlerAtk], aiData->abilities[battlerDef], move))
ADJUST_SCORE(-10);
else if (GetActiveGimmick(battlerDef) == GIMMICK_DYNAMAX)
@ -2510,7 +2510,7 @@ static s32 AI_CheckBadMove(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
if (IS_TARGETING_PARTNER(battlerAtk, battlerDef))
{
if (gStatuses3[battlerDef] & STATUS3_HEAL_BLOCK)
return 0;
return 0; // cannot even select
if (AtMaxHp(battlerDef))
ADJUST_SCORE(-10);
else if (gBattleMons[battlerDef].hp > gBattleMons[battlerDef].maxHP / 2)
@ -4821,7 +4821,7 @@ static s32 AI_CheckViability(u32 battlerAtk, u32 battlerDef, u32 move, s32 score
}
// Effects that are encouraged on the first turn of battle
static s32 AI_SetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
static s32 AI_ForceSetupFirstTurn(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
{
u8 i;
if (IS_TARGETING_PARTNER(battlerAtk, battlerDef)

View File

@ -1,6 +1,7 @@
#include "global.h"
#include "battle.h"
#include "battle_anim.h"
#include "battle_anim_scripts.h"
#include "battle_controllers.h"
#include "battle_interface.h"
#include "battle_util.h"
@ -29,11 +30,6 @@
#define ANIM_SPRITE_INDEX_COUNT 8
extern const u16 gMovesWithQuietBGM[];
extern const u8 *const gBattleAnims_General[];
extern const u8 *const gBattleAnims_Special[];
extern const u8 *const gBattleAnims_StatusConditions[];
static void Cmd_loadspritegfx(void);
static void Cmd_unloadspritegfx(void);
static void Cmd_createsprite(void);
@ -182,6 +178,93 @@ static void (* const sScriptCmdTable[])(void) =
Cmd_createdragondartsprite, // 0x34
};
static const u16 sMovesWithQuietBGM[] =
{
MOVE_SING, MOVE_PERISH_SONG, MOVE_GRASS_WHISTLE
};
static const u8* const sBattleAnims_StatusConditions[NUM_B_ANIMS_STATUS] =
{
[B_ANIM_STATUS_PSN] = gBattleAnimStatus_Poison,
[B_ANIM_STATUS_CONFUSION] = gBattleAnimStatus_Confusion,
[B_ANIM_STATUS_BRN] = gBattleAnimStatus_Burn,
[B_ANIM_STATUS_INFATUATION] = gBattleAnimStatus_Infatuation,
[B_ANIM_STATUS_SLP] = gBattleAnimStatus_Sleep,
[B_ANIM_STATUS_PRZ] = gBattleAnimStatus_Paralysis,
[B_ANIM_STATUS_FRZ] = gBattleAnimStatus_Freeze,
[B_ANIM_STATUS_CURSED] = gBattleAnimStatus_Curse,
[B_ANIM_STATUS_NIGHTMARE] = gBattleAnimStatus_Nightmare,
};
static const u8* const sBattleAnims_General[NUM_B_ANIMS_GENERAL] =
{
[B_ANIM_STATS_CHANGE] = gBattleAnimGeneral_StatsChange,
[B_ANIM_SUBSTITUTE_FADE] = gBattleAnimGeneral_SubstituteFade,
[B_ANIM_SUBSTITUTE_APPEAR] = gBattleAnimGeneral_SubstituteAppear,
[B_ANIM_POKEBLOCK_THROW] = gBattleAnimGeneral_PokeblockThrow,
[B_ANIM_ITEM_KNOCKOFF] = gBattleAnimGeneral_ItemKnockoff,
[B_ANIM_TURN_TRAP] = gBattleAnimGeneral_TurnTrap,
[B_ANIM_HELD_ITEM_EFFECT] = gBattleAnimGeneral_HeldItemEffect,
[B_ANIM_SMOKEBALL_ESCAPE] = gBattleAnimGeneral_SmokeballEscape,
[B_ANIM_HANGED_ON] = gBattleAnimGeneral_HangedOn,
[B_ANIM_RAIN_CONTINUES] = gBattleAnimGeneral_Rain,
[B_ANIM_SUN_CONTINUES] = gBattleAnimGeneral_Sun,
[B_ANIM_SANDSTORM_CONTINUES] = gBattleAnimGeneral_Sandstorm,
[B_ANIM_HAIL_CONTINUES] = gBattleAnimGeneral_Hail,
[B_ANIM_LEECH_SEED_DRAIN] = gBattleAnimGeneral_LeechSeedDrain,
[B_ANIM_MON_HIT] = gBattleAnimGeneral_MonHit,
[B_ANIM_ITEM_STEAL] = gBattleAnimGeneral_ItemSteal,
[B_ANIM_SNATCH_MOVE] = gBattleAnimGeneral_SnatchMove,
[B_ANIM_FUTURE_SIGHT_HIT] = gBattleAnimGeneral_FutureSightHit,
[B_ANIM_DOOM_DESIRE_HIT] = gBattleAnimGeneral_DoomDesireHit,
[B_ANIM_FOCUS_PUNCH_SETUP] = gBattleAnimGeneral_FocusPunchSetUp,
[B_ANIM_INGRAIN_HEAL] = gBattleAnimGeneral_IngrainHeal,
[B_ANIM_WISH_HEAL] = gBattleAnimGeneral_WishHeal,
[B_ANIM_MEGA_EVOLUTION] = gBattleAnimGeneral_MegaEvolution,
[B_ANIM_ILLUSION_OFF] = gBattleAnimGeneral_IllusionOff,
[B_ANIM_FORM_CHANGE] = gBattleAnimGeneral_FormChange,
[B_ANIM_SLIDE_OFFSCREEN] = gBattleAnimGeneral_SlideOffScreen,
[B_ANIM_RESTORE_BG] = gBattleAnimGeneral_RestoreBg,
[B_ANIM_TOTEM_FLARE] = gBattleAnimGeneral_TotemFlare,
[B_ANIM_GULP_MISSILE] = gBattleAnimGeneral_GulpMissile,
[B_ANIM_STRONG_WINDS] = gBattleAnimGeneral_StrongWinds,
[B_ANIM_PRIMAL_REVERSION] = gBattleAnimGeneral_PrimalReversion,
[B_ANIM_AQUA_RING_HEAL] = gBattleAnimGeneral_AquaRingHeal,
[B_ANIM_BEAK_BLAST_SETUP] = gBattleAnimGeneral_BeakBlastSetUp,
[B_ANIM_SHELL_TRAP_SETUP] = gBattleAnimGeneral_ShellTrapSetUp,
[B_ANIM_ZMOVE_ACTIVATE] = gBattleAnimGeneral_ZMoveActivate,
[B_ANIM_AFFECTION_HANGED_ON] = gBattleAnimGeneral_AffectionHangedOn,
[B_ANIM_SNOW_CONTINUES] = gBattleAnimGeneral_Snow,
[B_ANIM_ULTRA_BURST] = gBattleAnimGeneral_UltraBurst,
[B_ANIM_SALT_CURE_DAMAGE] = gBattleAnimGeneral_SaltCureDamage,
[B_ANIM_DYNAMAX_GROWTH] = gBattleAnimGeneral_DynamaxGrowth,
[B_ANIM_MAX_SET_WEATHER] = gBattleAnimGeneral_SetWeather,
[B_ANIM_SYRUP_BOMB_SPEED_DROP] = gBattleAnimGeneral_SyrupBombSpeedDrop,
[B_ANIM_RAINBOW] = gBattleAnimGeneral_Rainbow,
[B_ANIM_SEA_OF_FIRE] = gBattleAnimGeneral_SeaOfFire,
[B_ANIM_SWAMP] = gBattleAnimGeneral_Swamp,
[B_ANIM_TRICK_ROOM] = gBattleAnimGeneral_TrickRoom,
[B_ANIM_WONDER_ROOM] = gBattleAnimGeneral_WonderRoom,
[B_ANIM_MAGIC_ROOM] = gBattleAnimGeneral_MagicRoom,
[B_ANIM_TAILWIND] = gBattleAnimGeneral_Tailwind,
[B_ANIM_FOG_CONTINUES] = gBattleAnimGeneral_Fog,
[B_ANIM_TERA_CHARGE] = gBattleAnimGeneral_TeraCharge,
[B_ANIM_TERA_ACTIVATE] = gBattleAnimGeneral_TeraActivate,
[B_ANIM_SIMPLE_HEAL] = gBattleAnimGeneral_SimpleHeal,
};
static const u8* const sBattleAnims_Special[NUM_B_ANIMS_SPECIAL] =
{
[B_ANIM_LVL_UP] = gBattleAnimSpecial_LevelUp,
[B_ANIM_SWITCH_OUT_PLAYER_MON] = gBattleAnimSpecial_SwitchOutPlayerMon,
[B_ANIM_SWITCH_OUT_OPPONENT_MON] = gBattleAnimSpecial_SwitchOutOpponentMon,
[B_ANIM_BALL_THROW] = gBattleAnimSpecial_BallThrow,
[B_ANIM_BALL_THROW_WITH_TRAINER] = gBattleAnimSpecial_BallThrowWithTrainer,
[B_ANIM_SUBSTITUTE_TO_MON] = gBattleAnimSpecial_SubstituteToMon,
[B_ANIM_MON_TO_SUBSTITUTE] = gBattleAnimSpecial_MonToSubstitute,
[B_ANIM_CRITICAL_CAPTURE_THROW] = gBattleAnimSpecial_CriticalCaptureBallThrow,
};
void ClearBattleAnimationVars(void)
{
s32 i;
@ -314,16 +397,16 @@ void LaunchBattleAnimation(u32 animType, u32 animId)
{
case ANIM_TYPE_GENERAL:
default:
sBattleAnimScriptPtr = gBattleAnims_General[animId];
sBattleAnimScriptPtr = sBattleAnims_General[animId];
break;
case ANIM_TYPE_MOVE:
sBattleAnimScriptPtr = GetMoveAnimationScript(animId);
break;
case ANIM_TYPE_STATUS:
sBattleAnimScriptPtr = gBattleAnims_StatusConditions[animId];
sBattleAnimScriptPtr = sBattleAnims_StatusConditions[animId];
break;
case ANIM_TYPE_SPECIAL:
sBattleAnimScriptPtr = gBattleAnims_Special[animId];
sBattleAnimScriptPtr = sBattleAnims_Special[animId];
break;
}
gAnimScriptActive = TRUE;
@ -335,9 +418,9 @@ void LaunchBattleAnimation(u32 animType, u32 animId)
if (animType == ANIM_TYPE_MOVE)
{
for (i = 0; gMovesWithQuietBGM[i] != 0xFFFF; i++)
for (i = 0; i < ARRAY_COUNT(sMovesWithQuietBGM); i++)
{
if (animId == gMovesWithQuietBGM[i])
if (animId == sMovesWithQuietBGM[i])
{
m4aMPlayVolumeControl(&gMPlayInfo_BGM, TRACKS_ALL, 128);
break;

View File

@ -529,6 +529,7 @@ static void SetArenaData(void)
static void SaveArenaChallenge(void)
{
ClearEnemyPartyAfterChallenge();
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_CHALLENGE_STATUS, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE;

View File

@ -887,7 +887,7 @@ void HandleInputChooseMove(u32 battler)
}
else if (JOY_NEW(START_BUTTON))
{
if (gBattleStruct->gimmick.usableGimmick[battler] != GIMMICK_NONE)
if (gBattleStruct->gimmick.usableGimmick[battler] != GIMMICK_NONE && !HasTrainerUsedGimmick(battler, gBattleStruct->gimmick.usableGimmick[battler]))
{
gBattleStruct->gimmick.playerSelect ^= 1;
ReloadMoveNames(battler);
@ -2053,7 +2053,41 @@ static void PlayerHandleChooseAction(u32 battler)
ActionSelectionCreateCursorAt(gActionSelectionCursor[battler], 0);
PREPARE_MON_NICK_BUFFER(gBattleTextBuff1, battler, gBattlerPartyIndexes[battler]);
BattleStringExpandPlaceholdersToDisplayedString(gText_WhatWillPkmnDo);
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT);
if (B_SHOW_PARTNER_TARGET && gBattleTypeFlags & BATTLE_TYPE_INGAME_PARTNER && IsBattlerAlive(B_POSITION_PLAYER_RIGHT))
{
StringCopy(gStringVar1, COMPOUND_STRING("Partner will use:\n"));
u32 move = gBattleMons[B_POSITION_PLAYER_RIGHT].moves[*(gBattleStruct->chosenMovePositions + B_POSITION_PLAYER_RIGHT)];
StringAppend(gStringVar1, gMovesInfo[move].name);
if (gMovesInfo[move].target == MOVE_TARGET_SELECTED)
{
if (gBattleStruct->aiChosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_OPPONENT_LEFT)
StringAppend(gStringVar1, COMPOUND_STRING(" -{UP_ARROW}"));
else if (gBattleStruct->aiChosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_OPPONENT_RIGHT)
StringAppend(gStringVar1, COMPOUND_STRING(" {UP_ARROW}-"));
else if (gBattleStruct->aiChosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_PLAYER_LEFT)
StringAppend(gStringVar1, COMPOUND_STRING(" {DOWN_ARROW}-"));
else if (gBattleStruct->aiChosenTarget[B_POSITION_PLAYER_RIGHT] == B_POSITION_PLAYER_RIGHT)
StringAppend(gStringVar1, COMPOUND_STRING(" {DOWN_ARROW}-"));
}
else if (gMovesInfo[move].target == MOVE_TARGET_BOTH)
{
StringAppend(gStringVar1, COMPOUND_STRING(" {UP_ARROW}{UP_ARROW}"));
}
else if (gMovesInfo[move].target == MOVE_TARGET_FOES_AND_ALLY)
{
StringAppend(gStringVar1, COMPOUND_STRING(" {V_D_ARROW}{UP_ARROW}"));
}
else if (gMovesInfo[move].target == MOVE_TARGET_ALL_BATTLERS)
{
StringAppend(gStringVar1, COMPOUND_STRING(" {V_D_ARROW}{V_D_ARROW}"));
}
BattlePutTextOnWindow(gStringVar1, B_WIN_ACTION_PROMPT);
}
else
{
BattlePutTextOnWindow(gDisplayedStringBattle, B_WIN_ACTION_PROMPT);
}
}
static void PlayerHandleYesNoBox(u32 battler)

View File

@ -2593,6 +2593,7 @@ static void SetDomeOpponentGraphicsId(void)
static void SaveDomeChallenge(void)
{
ClearEnemyPartyAfterChallenge();
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_CHALLENGE_STATUS, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE;

View File

@ -406,7 +406,6 @@ static u8 GetMaxPowerTier(u32 move)
case EFFECT_NATURAL_GIFT:
case EFFECT_MIRROR_COAT:
case EFFECT_FINAL_GAMBIT:
//case EFFECT_DRAGON_DARTS:
return MAX_POWER_TIER_2;
case EFFECT_OHKO:
case EFFECT_RETURN:

View File

@ -268,6 +268,7 @@ static void SetBattleFactoryData(void)
static void SaveFactoryChallenge(void)
{
ClearEnemyPartyAfterChallenge();
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_CHALLENGE_STATUS, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE;
@ -430,9 +431,6 @@ static void SetPlayerAndOpponentParties(void)
ivs = gSaveBlock2Ptr->frontier.rentalMons[i].ivs;
CreateFacilityMon(&gFacilityTrainerMons[monId], monLevel, ivs, OT_ID_PLAYER_ID, FLAG_FRONTIER_MON_FACTORY, &gPlayerParty[i]);
SetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY,
&gSaveBlock2Ptr->frontier.rentalMons[i].personality);
CalculateMonStats(&gPlayerParty[i]);
}
}
@ -444,12 +442,7 @@ static void SetPlayerAndOpponentParties(void)
{
monId = gSaveBlock2Ptr->frontier.rentalMons[i + FRONTIER_PARTY_SIZE].monId;
ivs = gSaveBlock2Ptr->frontier.rentalMons[i + FRONTIER_PARTY_SIZE].ivs;
CreateFacilityMon(&gFacilityTrainerMons[monId],
monLevel, ivs, OT_ID_PLAYER_ID, FLAG_FRONTIER_MON_FACTORY,
&gEnemyParty[i]);
SetMonData(&gPlayerParty[i], MON_DATA_PERSONALITY,
&gSaveBlock2Ptr->frontier.rentalMons[i + FRONTIER_PARTY_SIZE].personality);
CalculateMonStats(&gPlayerParty[i]);
CreateFacilityMon(&gFacilityTrainerMons[monId], monLevel, ivs, OT_ID_PLAYER_ID, FLAG_FRONTIER_MON_FACTORY, &gEnemyParty[i]);
}
break;
}

View File

@ -436,8 +436,6 @@ void InitAndLaunchChosenStatusAnimation(u32 battler, bool32 isStatus2, u32 statu
LaunchStatusAnimation(battler, B_ANIM_STATUS_CURSED);
else if (status & STATUS2_NIGHTMARE)
LaunchStatusAnimation(battler, B_ANIM_STATUS_NIGHTMARE);
else if (status & STATUS2_WRAPPED)
LaunchStatusAnimation(battler, B_ANIM_STATUS_WRAPPED); // this animation doesn't actually exist
else // no animation
gBattleSpritesDataPtr->healthBoxesData[battler].statusAnimActive = 0;
}

View File

@ -144,7 +144,8 @@ void CreateGimmickTriggerSprite(u32 battler)
// Exit if there shouldn't be a sprite produced.
if (GetBattlerSide(battler) == B_SIDE_OPPONENT
|| gBattleStruct->gimmick.usableGimmick[battler] == GIMMICK_NONE
|| gimmick->triggerSheet == NULL)
|| gimmick->triggerSheet == NULL
|| HasTrainerUsedGimmick(battler, gBattleStruct->gimmick.usableGimmick[battler]))
{
return;
}

View File

@ -5615,9 +5615,14 @@ static void FreeResetData_ReturnToOvOrDoEvolutions(void)
}
FreeAllWindowBuffers();
if (gBattleStruct != NULL && !(gBattleTypeFlags & BATTLE_TYPE_LINK))
if (!(gBattleTypeFlags & BATTLE_TYPE_LINK))
{
ZeroEnemyPartyMons();
// To account for Battle Factory and Slateport Battle Tent, enemy parties are zeroed out in the facilitites respective src/xxx.c files
// The ZeroEnemyPartyMons() call happens in SaveXXXChallenge function (eg. SaveFactoryChallenge)
if (!(gBattleTypeFlags & BATTLE_TYPE_FRONTIER))
{
ZeroEnemyPartyMons();
}
ResetDynamicAiFunc();
FreeMonSpritesGfx();
FreeBattleResources();

View File

@ -180,6 +180,7 @@ static void IncrementPalaceStreak(void)
static void SavePalaceChallenge(void)
{
ClearEnemyPartyAfterChallenge();
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_CHALLENGE_STATUS, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE;

View File

@ -707,6 +707,7 @@ static void ClearInWildMonRoom(void)
static void SavePikeChallenge(void)
{
ClearEnemyPartyAfterChallenge();
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_CHALLENGE_STATUS, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE;

View File

@ -2,6 +2,7 @@
#include "battle_pyramid.h"
#include "battle_pyramid_bag.h"
#include "event_data.h"
#include "frontier_util.h"
#include "battle.h"
#include "battle_setup.h"
#include "battle_tower.h"
@ -936,6 +937,7 @@ static void SetBattlePyramidData(void)
static void SavePyramidChallenge(void)
{
ClearEnemyPartyAfterChallenge();
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_CHALLENGE_STATUS, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE;

View File

@ -1728,6 +1728,13 @@ static void AccuracyCheck(bool32 recalcDragonDarts, const u8 *nextInstr, const u
gBattlescriptCurrInstr = failInstr;
else if (!JumpIfMoveAffectedByProtect(gCurrentMove))
gBattlescriptCurrInstr = nextInstr;
if (GetActiveGimmick(gBattlerAttacker) == GIMMICK_DYNAMAX)
{
if (gProtectStructs[gBattlerTarget].maxGuarded)
gBattlescriptCurrInstr = nextInstr;
else
AbilityBattleEffects(ABILITYEFFECT_ABSORBING, gBattlerTarget, 0, 0, gCurrentMove);
}
}
else if (gSpecialStatuses[gBattlerAttacker].parentalBondState == PARENTAL_BOND_2ND_HIT
|| (gSpecialStatuses[gBattlerAttacker].multiHitOn
@ -6005,15 +6012,18 @@ static void Cmd_moveend(void)
&& gMultiHitCounter
&& !(gMovesInfo[gCurrentMove].effect == EFFECT_PRESENT && gBattleStruct->presentBasePower == 0)) // Silly edge case
{
gMultiHitCounter--;
if (!IsBattlerAlive(gBattlerTarget) && gMovesInfo[gCurrentMove].effect != EFFECT_DRAGON_DARTS)
gMultiHitCounter = 0;
gBattleScripting.multihitString[4]++;
if (--gMultiHitCounter == 0)
if (gMultiHitCounter == 0)
{
if (gMovesInfo[gCurrentMove].argument == MOVE_EFFECT_SCALE_SHOT && !NoAliveMonsForEitherParty())
{
BattleScriptPush(gBattlescriptCurrInstr + 1);
gBattlescriptCurrInstr = BattleScript_DefDownSpeedUp;
}
BattleScriptPushCursor();
gBattlescriptCurrInstr = BattleScript_MultiHitPrintStrings;
effect = TRUE;
@ -10702,20 +10712,6 @@ static void Cmd_various(void)
}
return;
}
case VARIOUS_TRY_TAR_SHOT:
{
VARIOUS_ARGS(const u8 *failInstr);
if (gDisableStructs[battler].tarShot)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
else
{
gDisableStructs[battler].tarShot = TRUE;
gBattlescriptCurrInstr = cmd->nextInstr;
}
return;
}
case VARIOUS_CAN_TAR_SHOT_WORK:
{
VARIOUS_ARGS(const u8 *failInstr);
@ -10863,123 +10859,6 @@ static void Cmd_various(void)
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
case VARIOUS_TEATIME_TARGETS:
{
VARIOUS_ARGS(const u8 *jumpInstr);
u32 count = 0;
for (i = 0; i < gBattlersCount; i++)
{
if (IsTeatimeAffected(i))
count++;
}
if (count == 0)
gBattlescriptCurrInstr = cmd->jumpInstr; // Teatime fails
else
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
case VARIOUS_TEATIME_INVUL:
{
VARIOUS_ARGS(const u8 *jumpInstr);
if (ItemId_GetPocket(gBattleMons[battler].item) == POCKET_BERRIES && !(gStatuses3[gBattlerTarget] & (STATUS3_SEMI_INVULNERABLE)))
gBattlescriptCurrInstr = cmd->nextInstr;
else
gBattlescriptCurrInstr = cmd->jumpInstr;
return;
}
case VARIOUS_TRY_WIND_RIDER_POWER:
{
VARIOUS_ARGS(const u8 *failInstr);
u16 ability = GetBattlerAbility(battler);
if (GetBattlerSide(battler) == GetBattlerSide(gBattlerAttacker)
&& (ability == ABILITY_WIND_RIDER || ability == ABILITY_WIND_POWER))
{
gLastUsedAbility = ability;
RecordAbilityBattle(battler, gLastUsedAbility);
gBattlerAbility = gBattleScripting.battler = battler;
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
gBattlescriptCurrInstr = cmd->failInstr;
}
return;
}
case VARIOUS_ACTIVATE_WEATHER_CHANGE_ABILITIES:
{
VARIOUS_ARGS();
gBattlescriptCurrInstr = cmd->nextInstr;
AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, battler, 0, 0, 0);
return;
}
case VARIOUS_ACTIVATE_TERRAIN_CHANGE_ABILITIES:
{
VARIOUS_ARGS();
gBattlescriptCurrInstr = cmd->nextInstr;
AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, battler, 0, 0, 0);
return;
}
case VARIOUS_STORE_HEALING_WISH:
{
VARIOUS_ARGS();
if (gCurrentMove == MOVE_LUNAR_DANCE)
gBattleStruct->storedLunarDance |= 1u << battler;
else
gBattleStruct->storedHealingWish |= 1u << battler;
break;
}
case VARIOUS_HIT_SWITCH_TARGET_FAILED:
{
VARIOUS_ARGS();
gBattleStruct->hitSwitchTargetFailed = TRUE;
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
case VARIOUS_TRY_REVIVAL_BLESSING:
{
VARIOUS_ARGS(const u8 *failInstr);
u32 side = GetBattlerSide(gBattlerAttacker);
u8 index = GetFirstFaintedPartyIndex(gBattlerAttacker);
// Move fails if there are no battlers to revive.
if (index == PARTY_SIZE)
{
gBattlescriptCurrInstr = cmd->failInstr;
return;
}
// Battler selected! Revive and go to next instruction.
if (gSelectedMonPartyId != PARTY_SIZE)
{
struct Pokemon *party = GetSideParty(side);
u16 hp = GetMonData(&party[gSelectedMonPartyId], MON_DATA_MAX_HP) / 2;
BtlController_EmitSetMonData(gBattlerAttacker, BUFFER_A, REQUEST_HP_BATTLE, 1u << gSelectedMonPartyId, sizeof(hp), &hp);
MarkBattlerForControllerExec(gBattlerAttacker);
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gSelectedMonPartyId], MON_DATA_SPECIES));
// If an on-field battler is revived, it needs to be sent out again.
if (IsDoubleBattle() &&
gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)] == gSelectedMonPartyId)
{
gBattleScripting.battler = BATTLE_PARTNER(gBattlerAttacker);
gBattleCommunication[MULTIUSE_STATE] = TRUE;
}
gSelectedMonPartyId = PARTY_SIZE;
gBattlescriptCurrInstr = cmd->nextInstr;
return;
}
// Open party menu, wait to go to next instruction.
else
{
BtlController_EmitChoosePokemon(gBattlerAttacker, BUFFER_A, PARTY_ACTION_CHOOSE_FAINTED_MON, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[gBattlerAttacker]);
MarkBattlerForControllerExec(gBattlerAttacker);
}
return;
}
} // End of switch (cmd->id)
gBattlescriptCurrInstr = cmd->nextInstr;
@ -16116,7 +15995,6 @@ static void TryUpdateRoundTurnOrder(void)
for (i = 0; roundUsers[i] != 0xFF && i < 3; i++)
{
gBattlerByTurnOrder[currRounder] = roundUsers[i];
gActionsByTurnOrder[currRounder] = gActionsByTurnOrder[roundUsers[i]];
gProtectStructs[roundUsers[i]].quash = TRUE; // Make it so their turn order can't be changed again
currRounder++;
}
@ -16125,7 +16003,6 @@ static void TryUpdateRoundTurnOrder(void)
for (i = 0; nonRoundUsers[i] != 0xFF && i < 3; i++)
{
gBattlerByTurnOrder[currRounder] = nonRoundUsers[i];
gActionsByTurnOrder[currRounder] = gActionsByTurnOrder[nonRoundUsers[i]];
currRounder++;
}
}
@ -17197,3 +17074,143 @@ void BS_FickleBeamDamageCalculation(void)
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
void BS_TryTarShot(void)
{
NATIVE_ARGS(const u8 *failInstr);
if (gDisableStructs[gBattlerTarget].tarShot || GetActiveGimmick(gBattlerTarget) == GIMMICK_TERA)
{
gBattlescriptCurrInstr = cmd->failInstr;
}
else
{
gDisableStructs[gBattlerTarget].tarShot = TRUE;
gBattlescriptCurrInstr = cmd->nextInstr;
}
}
void BS_TeatimeInvul(void)
{
NATIVE_ARGS(u8 battler, const u8 *jumpInstr);
u32 battler = GetBattlerForBattleScript(cmd->battler);
if (ItemId_GetPocket(gBattleMons[battler].item) == POCKET_BERRIES && !(gStatuses3[gBattlerTarget] & (STATUS3_SEMI_INVULNERABLE)))
gBattlescriptCurrInstr = cmd->nextInstr;
else
gBattlescriptCurrInstr = cmd->jumpInstr;
}
void BS_TeatimeTargets(void)
{
NATIVE_ARGS(const u8 *failInstr);
u32 count = 0, i;
for (i = 0; i < gBattlersCount; i++)
{
if (IsTeatimeAffected(i))
count++;
}
if (count == 0)
gBattlescriptCurrInstr = cmd->failInstr;
else
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_TryWindRiderPower(void)
{
NATIVE_ARGS(u8 battler, const u8 *failInstr);
u32 battler = GetBattlerForBattleScript(cmd->battler);
u16 ability = GetBattlerAbility(battler);
if (GetBattlerSide(battler) == GetBattlerSide(gBattlerAttacker)
&& (ability == ABILITY_WIND_RIDER || ability == ABILITY_WIND_POWER))
{
gLastUsedAbility = ability;
RecordAbilityBattle(battler, gLastUsedAbility);
gBattlerAbility = gBattleScripting.battler = battler;
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
gBattlescriptCurrInstr = cmd->failInstr;
}
}
void BS_ActivateWeatherChangeAbilities(void)
{
NATIVE_ARGS(u8 battler);
u32 battler = GetBattlerForBattleScript(cmd->battler);
gBattlescriptCurrInstr = cmd->nextInstr;
AbilityBattleEffects(ABILITYEFFECT_ON_WEATHER, battler, 0, 0, 0);
}
void BS_ActivateTerrainChangeAbilities(void)
{
NATIVE_ARGS(u8 battler);
u32 battler = GetBattlerForBattleScript(cmd->battler);
gBattlescriptCurrInstr = cmd->nextInstr;
AbilityBattleEffects(ABILITYEFFECT_ON_TERRAIN, battler, 0, 0, 0);
}
void BS_StoreHealingWish(void)
{
NATIVE_ARGS(u8 battler);
u32 battler = GetBattlerForBattleScript(cmd->battler);
if (gCurrentMove == MOVE_LUNAR_DANCE)
gBattleStruct->storedLunarDance |= 1u << battler;
else
gBattleStruct->storedHealingWish |= 1u << battler;
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_HitSwitchTargetFailed(void)
{
NATIVE_ARGS();
gBattleStruct->hitSwitchTargetFailed = TRUE;
gBattlescriptCurrInstr = cmd->nextInstr;
}
void BS_TryRevivalBlessing(void)
{
NATIVE_ARGS(const u8 *failInstr);
u32 side = GetBattlerSide(gBattlerAttacker);
u8 index = GetFirstFaintedPartyIndex(gBattlerAttacker);
// Move fails if there are no battlers to revive.
if (index == PARTY_SIZE)
{
gBattlescriptCurrInstr = cmd->failInstr;
return;
}
// Battler selected! Revive and go to next instruction.
if (gSelectedMonPartyId != PARTY_SIZE)
{
struct Pokemon *party = GetSideParty(side);
u16 hp = GetMonData(&party[gSelectedMonPartyId], MON_DATA_MAX_HP) / 2;
BtlController_EmitSetMonData(gBattlerAttacker, BUFFER_A, REQUEST_HP_BATTLE, 1u << gSelectedMonPartyId, sizeof(hp), &hp);
MarkBattlerForControllerExec(gBattlerAttacker);
PREPARE_SPECIES_BUFFER(gBattleTextBuff1, GetMonData(&party[gSelectedMonPartyId], MON_DATA_SPECIES));
// If an on-field battler is revived, it needs to be sent out again.
if (IsDoubleBattle() &&
gBattlerPartyIndexes[BATTLE_PARTNER(gBattlerAttacker)] == gSelectedMonPartyId)
{
gBattleScripting.battler = BATTLE_PARTNER(gBattlerAttacker);
gBattleCommunication[MULTIUSE_STATE] = TRUE;
}
gSelectedMonPartyId = PARTY_SIZE;
gBattlescriptCurrInstr = cmd->nextInstr;
}
else
{
// Open party menu, wait to go to next instruction.
BtlController_EmitChoosePokemon(gBattlerAttacker, BUFFER_A, PARTY_ACTION_CHOOSE_FAINTED_MON, PARTY_SIZE, ABILITY_NONE, gBattleStruct->battlerPartyOrders[gBattlerAttacker]);
MarkBattlerForControllerExec(gBattlerAttacker);
}
}

View File

@ -139,6 +139,7 @@ static void BufferVerdanturfTentTrainerIntro(void)
static void SaveVerdanturfTentChallenge(void)
{
ClearEnemyPartyAfterChallenge();
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_CHALLENGE_STATUS, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE;
@ -189,6 +190,7 @@ static void SetFallarborTentPrize(void)
static void SaveFallarborTentChallenge(void)
{
ClearEnemyPartyAfterChallenge();
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_CHALLENGE_STATUS, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE;
@ -244,6 +246,7 @@ static void SetSlateportTentPrize(void)
static void SaveSlateportTentChallenge(void)
{
ClearEnemyPartyAfterChallenge();
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_CHALLENGE_STATUS, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE;

View File

@ -2206,6 +2206,7 @@ static void SaveTowerChallenge(void)
if (gSpecialVar_0x8005 == 0 && (challengeNum > 1 || gSaveBlock2Ptr->frontier.curChallengeBattleNum != 0))
SaveBattleTowerRecord();
ClearEnemyPartyAfterChallenge();
gSaveBlock2Ptr->frontier.challengeStatus = gSpecialVar_0x8005;
VarSet(VAR_TEMP_CHALLENGE_STATUS, 0);
gSaveBlock2Ptr->frontier.challengePaused = TRUE;

View File

@ -8818,6 +8818,9 @@ static inline u32 CalcMoveBasePower(u32 move, u32 battlerAtk, u32 battlerDef, u3
if (GetActiveGimmick(battlerAtk) == GIMMICK_Z_MOVE)
return GetZMovePower(gBattleStruct->zmove.baseMoves[battlerAtk]);
if (GetActiveGimmick(battlerAtk) == GIMMICK_DYNAMAX)
return GetMaxMovePower(move);
switch (gMovesInfo[move].effect)
{
case EFFECT_PLEDGE:
@ -11787,5 +11790,10 @@ u32 GetMoveType(u32 move)
{
if (gMain.inBattle && gBattleStruct->dynamicMoveType)
return gBattleStruct->dynamicMoveType & DYNAMIC_TYPE_MASK;
else if (B_UPDATED_MOVE_TYPES < GEN_5
&& (move == MOVE_BEAT_UP
|| move == MOVE_FUTURE_SIGHT
|| move == MOVE_DOOM_DESIRE))
return TYPE_MYSTERY;
return gMovesInfo[move].type;
}

View File

@ -2144,6 +2144,8 @@ void ObjectEventInteractionGetBerryCountString(void)
u8 treeId = GetObjectEventBerryTreeId(gSelectedObjectEvent);
u8 berry = GetBerryTypeByBerryTreeId(treeId);
u8 count = GetBerryCountByBerryTreeId(treeId);
gSpecialVar_0x8006 = BerryTypeToItemId(berry);
CopyItemNameHandlePlural(BerryTypeToItemId(berry), gStringVar1, count);
berry = GetTreeMutationValue(treeId);
if (berry > 0)

File diff suppressed because it is too large Load Diff

View File

@ -1063,7 +1063,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] =
.eggGroups = MON_EGG_GROUPS(EGG_GROUP_FLYING),
.abilities = { ABILITY_PRESSURE, ABILITY_UNNERVE, ABILITY_MIRROR_ARMOR },
.bodyColor = BODY_COLOR_PURPLE,
.speciesName = _("Corviknigh"),
.speciesName = _("Corviknight"),
.cryId = CRY_CORVIKNIGHT,
.natDexNum = NATIONAL_DEX_CORVIKNIGHT,
.categoryName = _("Raven"),
@ -3605,7 +3605,7 @@ const struct SpeciesInfo gSpeciesInfoGen8[] =
.eggGroups = MON_EGG_GROUPS(EGG_GROUP_BUG),
.abilities = { ABILITY_FLASH_FIRE, ABILITY_WHITE_SMOKE, ABILITY_FLAME_BODY },
.bodyColor = BODY_COLOR_RED,
.speciesName = _("Centiskorc"),
.speciesName = _("Centiskorch"),
.cryId = CRY_CENTISKORCH,
.natDexNum = NATIONAL_DEX_CENTISKORCH,
.categoryName = _("Radiator"),
@ -5280,6 +5280,14 @@ const struct SpeciesInfo gSpeciesInfoGen8[] =
.iconSprite = gMonIcon_IndeedeeFemale,
.iconPalIndex = 2,
FOOTPRINT(Indeedee)
OVERWORLD(
sPicTable_IndeedeeFemale,
SIZE_32x32,
SHADOW_SIZE_M,
TRACKS_FOOT,
gOverworldPalette_IndeedeeFemale,
gShinyOverworldPalette_IndeedeeFemale
)
.levelUpLearnset = sIndeedeeFemaleLevelUpLearnset,
.teachableLearnset = sIndeedeeFemaleTeachableLearnset,
.eggMoveLearnset = sIndeedeeFemaleEggMoveLearnset,

View File

@ -105,107 +105,107 @@ static const struct MenuAction MultichoiceList_LevelMode[] =
static const struct MenuAction MultichoiceList_Mechadoll1_Q1[] =
{
{gTrickHouse_Mechadoll_Oddish},
{gTrickHouse_Mechadoll_Poochyena},
{gTrickHouse_Mechadoll_Taillow},
{COMPOUND_STRING("ODDISH")},
{COMPOUND_STRING("POOCHYENA")},
{COMPOUND_STRING("TAILLOW")},
};
static const struct MenuAction MultichoiceList_Mechadoll1_Q2[] =
{
{gTrickHouse_Mechadoll_Azurill},
{gTrickHouse_Mechadoll_Lotad},
{gTrickHouse_Mechadoll_Wingull},
{COMPOUND_STRING("AZURILL")},
{COMPOUND_STRING("LOTAD")},
{COMPOUND_STRING("WINGULL")},
};
static const struct MenuAction MultichoiceList_Mechadoll1_Q3[] =
{
{gTrickHouse_Mechadoll_Dustox},
{gTrickHouse_Mechadoll_Zubat},
{gTrickHouse_Mechadoll_Nincada},
{COMPOUND_STRING("DUSTOX")},
{COMPOUND_STRING("ZUBAT")},
{COMPOUND_STRING("NINCADA")},
};
static const struct MenuAction MultichoiceList_Mechadoll2_Q1[] =
{
{gTrickHouse_Mechadoll_Ralts},
{gTrickHouse_Mechadoll_Zigzagoon},
{gTrickHouse_Mechadoll_Slakoth},
{COMPOUND_STRING("RALTS")},
{COMPOUND_STRING("ZIGZAGOON")},
{COMPOUND_STRING("SLAKOTH")},
};
static const struct MenuAction MultichoiceList_Mechadoll2_Q2[] =
{
{gTrickHouse_Mechadoll_Poochyena2},
{gTrickHouse_Mechadoll_Shroomish},
{gTrickHouse_Mechadoll_Zigzagoon2},
{COMPOUND_STRING("POOCHYENA")},
{COMPOUND_STRING("SHROOMISH")},
{COMPOUND_STRING("ZIGZAGOON")},
};
static const struct MenuAction MultichoiceList_Mechadoll2_Q3[] =
{
{gTrickHouse_Mechadoll_Poochyena3},
{gTrickHouse_Mechadoll_Zubat2},
{gTrickHouse_Mechadoll_Carvanha},
{COMPOUND_STRING("POOCHYENA")},
{COMPOUND_STRING("ZUBAT")},
{COMPOUND_STRING("CARVANHA")},
};
static const struct MenuAction MultichoiceList_Mechadoll3_Q1[] =
{
{gTrickHouse_Mechadoll_BurnHeal},
{gTrickHouse_Mechadoll_HarborMail},
{gTrickHouse_Mechadoll_SamePrice},
{COMPOUND_STRING("BURN HEAL")},
{COMPOUND_STRING("HARBOR MAIL")},
{COMPOUND_STRING("Same price")},
};
static const struct MenuAction MultichoiceList_Mechadoll3_Q2[] =
{
{gTrickHouse_Mechadoll_60Yen},
{gTrickHouse_Mechadoll_55Yen},
{gTrickHouse_Mechadoll_Nothing},
{COMPOUND_STRING("¥60")},
{COMPOUND_STRING("¥55")},
{COMPOUND_STRING("Nothing")},
};
static const struct MenuAction MultichoiceList_Mechadoll3_Q3[] =
{
{gTrickHouse_Mechadoll_CostMore},
{gTrickHouse_Mechadoll_CostLess},
{gTrickHouse_Mechadoll_SamePrice2},
{COMPOUND_STRING("They will cost more.")},
{COMPOUND_STRING("They will cost less.")},
{COMPOUND_STRING("Same price")},
};
static const struct MenuAction MultichoiceList_Mechadoll4_Q1[] =
{
{gTrickHouse_Mechadoll_Male},
{gTrickHouse_Mechadoll_Female},
{gTrickHouse_Mechadoll_Neither},
{COMPOUND_STRING("Male")},
{COMPOUND_STRING("Female")},
{COMPOUND_STRING("Neither")},
};
static const struct MenuAction MultichoiceList_Mechadoll4_Q2[] =
{
{gTrickHouse_Mechadoll_ElderlyMen},
{gTrickHouse_Mechadoll_ElderlyLadies},
{gTrickHouse_Mechadoll_SameNumber},
{COMPOUND_STRING("Elderly men")},
{COMPOUND_STRING("Elderly ladies")},
{COMPOUND_STRING("Same number")},
};
static const struct MenuAction MultichoiceList_Mechadoll4_Q3[] =
{
{gTrickHouse_Mechadoll_None},
{gTrickHouse_Mechadoll_One},
{gTrickHouse_Mechadoll_Two},
{COMPOUND_STRING("None")},
{COMPOUND_STRING("1")},
{COMPOUND_STRING("2")},
};
static const struct MenuAction MultichoiceList_Mechadoll5_Q1[] =
{
{gTrickHouse_Mechadoll_Two2},
{gTrickHouse_Mechadoll_Three},
{gTrickHouse_Mechadoll_Four},
{COMPOUND_STRING("2")},
{COMPOUND_STRING("3")},
{COMPOUND_STRING("4")},
};
static const struct MenuAction MultichoiceList_Mechadoll5_Q2[] =
{
{gTrickHouse_Mechadoll_Six},
{gTrickHouse_Mechadoll_Seven},
{gTrickHouse_Mechadoll_Eight},
{COMPOUND_STRING("6")},
{COMPOUND_STRING("7")},
{COMPOUND_STRING("8")},
};
static const struct MenuAction MultichoiceList_Mechadoll5_Q3[] =
{
{gTrickHouse_Mechadoll_Six2},
{gTrickHouse_Mechadoll_Seven2},
{gTrickHouse_Mechadoll_Eight2},
{COMPOUND_STRING("6")},
{COMPOUND_STRING("7")},
{COMPOUND_STRING("8")},
};
static const struct MenuAction MultichoiceList_VendingMachine[] =

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -72,6 +72,7 @@ const struct WildPokemonHeader {{ wild_encounter_group.label }}[] =
{
.mapGroup = {% if wild_encounter_group.for_maps %}MAP_GROUP({{ removePrefix(encounter.map, "MAP_") }}){% else %}0{% endif %},
.mapNum = {% if wild_encounter_group.for_maps %}MAP_NUM({{ removePrefix(encounter.map, "MAP_") }}){% else %}{{ loop.index1 }}{% endif %},
.timeOfDay = {% if stringEndsWith(encounter.base_label, "_Night") or stringContains(encounter.base_label, "_Night_") %}TIME_NIGHT{% else if stringEndsWith(encounter.base_label, "_Morning") or stringContains(encounter.base_label, "_Morning_") %}TIME_MORNING{% else if stringEndsWith(encounter.base_label, "_Evening") or stringContains(encounter.base_label, "_Evening_") %}TIME_EVENING{% else %}TIME_DAY{% endif %},
.landMonsInfo = {% if existsIn(encounter, "land_mons") %}&{{ encounter.base_label }}_LandMonsInfo{% else %}NULL{% endif %},
.waterMonsInfo = {% if existsIn(encounter, "water_mons") %}&{{ encounter.base_label }}_WaterMonsInfo{% else %}NULL{% endif %},
.rockSmashMonsInfo = {% if existsIn(encounter, "rock_smash_mons") %}&{{ encounter.base_label }}_RockSmashMonsInfo{% else %}NULL{% endif %},
@ -81,6 +82,7 @@ const struct WildPokemonHeader {{ wild_encounter_group.label }}[] =
{
.mapGroup = MAP_GROUP(UNDEFINED),
.mapNum = MAP_NUM(UNDEFINED),
.timeOfDay = TIME_DAY,
.landMonsInfo = NULL,
.waterMonsInfo = NULL,
.rockSmashMonsInfo = NULL,

41
src/ev_caps.c Normal file
View File

@ -0,0 +1,41 @@
#include "global.h"
#include "battle.h"
#include "event_data.h"
#include "ev_caps.h"
#include "pokemon.h"
u32 GetCurrentEVCap(void)
{
static const u16 sEvCapFlagMap[][2] = {
// Define EV caps for each milestone
{FLAG_BADGE01_GET, 30},
{FLAG_BADGE02_GET, 90},
{FLAG_BADGE03_GET, 150},
{FLAG_BADGE04_GET, 210},
{FLAG_BADGE05_GET, 270},
{FLAG_BADGE06_GET, 330},
{FLAG_BADGE07_GET, 390},
{FLAG_BADGE08_GET, 450},
{FLAG_IS_CHAMPION, MAX_TOTAL_EVS},
};
if (B_EV_CAP_TYPE == EV_CAP_FLAG_LIST)
{
for (u32 evCap = 0; evCap < ARRAY_COUNT(sEvCapFlagMap); evCap++)
{
if (!FlagGet(sEvCapFlagMap[evCap][0]))
return sEvCapFlagMap[evCap][1];
}
}
else if (B_EV_CAP_TYPE == EV_CAP_VARIABLE)
{
return VarGet(B_EV_CAP_VARIABLE);
}
else if (B_EV_CAP_TYPE == EV_CAP_NO_GAIN)
{
return 0;
}
return MAX_TOTAL_EVS;
}

View File

@ -149,7 +149,7 @@ ALIGNED(4) const u8 gFontNormalLatinGlyphWidths[] = {
3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 6, 6, 6, 6, 6,
8, 6, 6, 6, 6, 6, 6, 6, 3, 6, 6, 6, 6, 6, 6, 3,
6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 6, 9, 7, 6, 3,
3, 3, 3, 3, 10, 8, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 10, 8, 3, 3, 7, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
6, 6, 4, 8, 8, 8, 7, 8, 8, 4, 6, 6, 4, 4, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 6, 3, 3, 3, 3, 3, 3, 6,

View File

@ -2554,3 +2554,14 @@ static void CopyFrontierBrainText(bool8 playerWonText)
break;
}
}
void ClearEnemyPartyAfterChallenge()
{
// We zero out the Enemy's party here when the player either wins or loses the challenge since we
// can't do it the usual way in FreeResetData_ReturnToOvOrDoEvolutions() in battle_main.c due to the
// way facilities like the Battle Factory and the Slateport Battle Tent work
if (gSpecialVar_0x8005 == 0)
{
ZeroEnemyPartyMons();
}
}

View File

@ -1445,10 +1445,6 @@ const u32 gBattleAnimBgTilemap_ClangorousSoulblaze[] = INCBIN_U32("graphics/batt
const u32 gBattleAnimBgPalette_DynamaxCannon[] = INCBIN_U32("graphics/battle_anims/backgrounds/dynamax_cannon.gbapal.lz");
const u32 gBattleAnimBgImage_ElectricTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/electric_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_ElectricTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/electric_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_ElectricTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/electric_terrain.bin.lz");
const u32 gBattleAnimBgImage_Fire1[] = INCBIN_U32("graphics/battle_anims/backgrounds/fire1.4bpp.lz");
const u32 gBattleAnimBgPalette_Fire1[] = INCBIN_U32("graphics/battle_anims/backgrounds/fire1.gbapal.lz");
const u32 gBattleAnimBgTilemap_Fire1[] = INCBIN_U32("graphics/battle_anims/backgrounds/fire1.bin.lz");
@ -1461,10 +1457,6 @@ const u32 gBattleAnimBgTilemap_FocusBlast[] = INCBIN_U32("graphics/battle_anims/
const u32 gBattleAnimBgPalette_GarbageFalls[] = INCBIN_U32("graphics/battle_anims/backgrounds/garbage_falls.gbapal.lz");
const u32 gBattleAnimBgImage_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/grassy_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/grassy_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/grassy_terrain.bin.lz");
const u32 gBattleAnimBgPalette_GunkShot[] = INCBIN_U32("graphics/battle_anims/backgrounds/gunk_shot.gbapal.lz");
const u32 gBattleAnimBgImage_HydroCannon[] = INCBIN_U32("graphics/battle_anims/backgrounds/hydro_cannon.4bpp.lz");
@ -1496,14 +1488,44 @@ const u32 gBattleAnimBgImage_MaxLightning[] = INCBIN_U32("graphics/battle_anims/
const u32 gBattleAnimBgPalette_MaxLightning[] = INCBIN_U32("graphics/battle_anims/backgrounds/max_lightning.gbapal.lz");
const u32 gBattleAnimBgTilemap_MaxLightning[] = INCBIN_U32("graphics/battle_anims/backgrounds/max_lightning.bin.lz");
const u32 gBattleAnimBgImage_MistyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/misty_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_MistyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/misty_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_MistyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/misty_terrain.bin.lz");
const u32 gBattleAnimBgImage_NeverendingNightmare[] = INCBIN_U32("graphics/battle_anims/backgrounds/neverending_nightmare.4bpp.lz");
const u32 gBattleAnimBgPalette_NeverendingNightmare[] = INCBIN_U32("graphics/battle_anims/backgrounds/neverending_nightmare.gbapal.lz");
const u32 gBattleAnimBgTilemap_NeverendingNightmare[] = INCBIN_U32("graphics/battle_anims/backgrounds/neverending_nightmare.bin.lz");
#if B_NEW_TERRAIN_BACKGROUNDS
const u32 gBattleAnimBgImage_ElectricTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_electric_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_ElectricTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_electric_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_ElectricTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_electric_terrain.bin.lz");
const u32 gBattleAnimBgImage_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_grassy_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_grassy_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_grassy_terrain.bin.lz");
const u32 gBattleAnimBgImage_MistyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_misty_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_MistyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_misty_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_MistyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_misty_terrain.bin.lz");
const u32 gBattleAnimBgImage_PsychicTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_psychic_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_PsychicTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_psychic_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_PsychicTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/new_psychic_terrain.bin.lz");
#else
const u32 gBattleAnimBgImage_PsychicTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/psychic_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_PsychicTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/psychic_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_PsychicTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/psychic_terrain.bin.lz");
const u32 gBattleAnimBgImage_ElectricTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/electric_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_ElectricTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/electric_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_ElectricTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/electric_terrain.bin.lz");
const u32 gBattleAnimBgImage_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/grassy_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/grassy_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_GrassyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/grassy_terrain.bin.lz");
const u32 gBattleAnimBgImage_MistyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/misty_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_MistyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/misty_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_MistyTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/misty_terrain.bin.lz");
#endif
const u32 gBattleAnimBgImage_Nightmare[] = INCBIN_U32("graphics/battle_anims/backgrounds/nightmare.4bpp.lz");
const u32 gBattleAnimBgPalette_Nightmare[] = INCBIN_U32("graphics/battle_anims/backgrounds/nightmare.gbapal.lz");
const u32 gBattleAnimBgTilemap_Nightmare[] = INCBIN_U32("graphics/battle_anims/backgrounds/nightmare.bin.lz");
@ -1512,10 +1534,6 @@ const u32 gBattleAnimBgPalette_PoisonFalls[] = INCBIN_U32("graphics/battle_anims
const u32 gBattleAnimBgPalette_PsychicNew[] = INCBIN_U32("graphics/battle_anims/backgrounds/psychic_new.gbapal.lz");
const u32 gBattleAnimBgImage_PsychicTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/psychic_terrain.4bpp.lz");
const u32 gBattleAnimBgPalette_PsychicTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/psychic_terrain.gbapal.lz");
const u32 gBattleAnimBgTilemap_PsychicTerrain[] = INCBIN_U32("graphics/battle_anims/backgrounds/psychic_terrain.bin.lz");
const u32 gBattleAnimBgImage_ShatteredPsyche[] = INCBIN_U32("graphics/battle_anims/backgrounds/shattered_psyche.4bpp.lz");
const u32 gBattleAnimBgPalette_ShatteredPsyche[] = INCBIN_U32("graphics/battle_anims/backgrounds/shattered_psyche.gbapal.lz");
const u32 gBattleAnimBgTilemap_ShatteredPsyche[] = INCBIN_U32("graphics/battle_anims/backgrounds/shattered_psyche.bin.lz");

View File

@ -24,6 +24,8 @@
#include "gpu_regs.h"
#include "heal_location.h"
#include "io_reg.h"
#include "item.h"
#include "item_icon.h"
#include "link.h"
#include "link_rfu.h"
#include "load_save.h"
@ -51,6 +53,7 @@
#include "secret_base.h"
#include "sound.h"
#include "start_menu.h"
#include "string_util.h"
#include "task.h"
#include "tileset_anims.h"
#include "time_events.h"
@ -3291,3 +3294,207 @@ static void SpriteCB_LinkPlayer(struct Sprite *sprite)
sprite->data[7]++;
}
}
// ----------------
// Item Header Descriptions
// Item Description Header
#define ITEM_ICON_X 26
#define ITEM_ICON_Y 24
#define ITEM_TAG 0x2722 //same as money label
bool8 GetSetItemObtained(u16 item, enum ItemObtainFlags caseId)
{
#if OW_SHOW_ITEM_DESCRIPTIONS == OW_ITEM_DESCRIPTIONS_FIRST_TIME
u8 index = item / 8;
u8 bit = item % 8;
u8 mask = 1 << bit;
switch (caseId)
{
case FLAG_GET_ITEM_OBTAINED:
return gSaveBlock3Ptr->itemFlags[index] & mask;
case FLAG_SET_ITEM_OBTAINED:
gSaveBlock3Ptr->itemFlags[index] |= mask;
return TRUE;
}
#endif
return FALSE;
}
#if OW_SHOW_ITEM_DESCRIPTIONS != OW_ITEM_DESCRIPTIONS_OFF
EWRAM_DATA static u8 sHeaderBoxWindowId = 0;
EWRAM_DATA u8 sItemIconSpriteId = 0;
EWRAM_DATA u8 sItemIconSpriteId2 = 0;
static void ShowItemIconSprite(u16 item, bool8 firstTime, bool8 flash);
static void DestroyItemIconSprite(void);
static u8 ReformatItemDescription(u16 item, u8 *dest)
{
u8 count = 0;
u8 numLines = 1;
u8 maxChars = 32;
u8 *desc = (u8 *)gItemsInfo[item].description;
while (*desc != EOS)
{
if (count >= maxChars)
{
while (*desc != CHAR_SPACE && *desc != CHAR_NEWLINE)
{
*dest = *desc; //finish word
dest++;
desc++;
}
*dest = CHAR_NEWLINE;
count = 0;
numLines++;
dest++;
desc++;
continue;
}
*dest = *desc;
if (*desc == CHAR_NEWLINE)
{
*dest = CHAR_SPACE;
}
dest++;
desc++;
count++;
}
// finish string
*dest = EOS;
return numLines;
}
void ScriptShowItemDescription(struct ScriptContext *ctx)
{
u8 headerType = ScriptReadByte(ctx);
struct WindowTemplate template;
u16 item = gSpecialVar_0x8006;
u8 textY;
u8 *dst;
bool8 handleFlash = FALSE;
if (GetFlashLevel() > 0 || InBattlePyramid_())
handleFlash = TRUE;
if (headerType == 1) // berry
dst = gStringVar3;
else
dst = gStringVar1;
if (GetSetItemObtained(item, FLAG_GET_ITEM_OBTAINED))
{
ShowItemIconSprite(item, FALSE, handleFlash);
return; //no box if item obtained previously
}
SetWindowTemplateFields(&template, 0, 1, 1, 28, 3, 15, 8);
sHeaderBoxWindowId = AddWindow(&template);
FillWindowPixelBuffer(sHeaderBoxWindowId, PIXEL_FILL(0));
PutWindowTilemap(sHeaderBoxWindowId);
CopyWindowToVram(sHeaderBoxWindowId, 3);
SetStandardWindowBorderStyle(sHeaderBoxWindowId, FALSE);
DrawStdFrameWithCustomTileAndPalette(sHeaderBoxWindowId, FALSE, 0x214, 14);
if (ReformatItemDescription(item, dst) == 1)
textY = 4;
else
textY = 0;
ShowItemIconSprite(item, TRUE, handleFlash);
AddTextPrinterParameterized(sHeaderBoxWindowId, 0, dst, ITEM_ICON_X + 2, textY, 0, NULL);
}
void ScriptHideItemDescription(struct ScriptContext *ctx)
{
DestroyItemIconSprite();
if (!GetSetItemObtained(gSpecialVar_0x8006, FLAG_GET_ITEM_OBTAINED))
{
//header box only exists if haven't seen item before
GetSetItemObtained(gSpecialVar_0x8006, FLAG_SET_ITEM_OBTAINED);
ClearStdWindowAndFrameToTransparent(sHeaderBoxWindowId, FALSE);
CopyWindowToVram(sHeaderBoxWindowId, 3);
RemoveWindow(sHeaderBoxWindowId);
}
}
static void ShowItemIconSprite(u16 item, bool8 firstTime, bool8 flash)
{
s16 x = 0, y = 0;
u8 iconSpriteId;
u8 spriteId2 = MAX_SPRITES;
if (flash)
{
SetGpuRegBits(REG_OFFSET_DISPCNT, DISPCNT_OBJWIN_ON);
SetGpuRegBits(REG_OFFSET_WINOUT, WINOUT_WINOBJ_OBJ);
}
iconSpriteId = AddItemIconSprite(ITEM_TAG, ITEM_TAG, item);
if (flash)
spriteId2 = AddItemIconSprite(ITEM_TAG, ITEM_TAG, item);
if (iconSpriteId != MAX_SPRITES)
{
if (!firstTime)
{
//show in message box
x = 213;
y = 140;
}
else
{
// show in header box
x = ITEM_ICON_X;
y = ITEM_ICON_Y;
}
gSprites[iconSpriteId].x2 = x;
gSprites[iconSpriteId].y2 = y;
gSprites[iconSpriteId].oam.priority = 0;
}
if (spriteId2 != MAX_SPRITES)
{
gSprites[spriteId2].x2 = x;
gSprites[spriteId2].y2 = y;
gSprites[spriteId2].oam.priority = 0;
gSprites[spriteId2].oam.objMode = ST_OAM_OBJ_WINDOW;
sItemIconSpriteId2 = spriteId2;
}
sItemIconSpriteId = iconSpriteId;
}
static void DestroyItemIconSprite(void)
{
FreeSpriteTilesByTag(ITEM_TAG);
FreeSpritePaletteByTag(ITEM_TAG);
FreeSpriteOamMatrix(&gSprites[sItemIconSpriteId]);
DestroySprite(&gSprites[sItemIconSpriteId]);
if ((GetFlashLevel() > 0 || InBattlePyramid_()) && sItemIconSpriteId2 != MAX_SPRITES)
{
FreeSpriteOamMatrix(&gSprites[sItemIconSpriteId2]);
DestroySprite(&gSprites[sItemIconSpriteId2]);
}
}
#else
void ScriptShowItemDescription(struct ScriptContext *ctx)
{
(void) ScriptReadByte(ctx);
}
void ScriptHideItemDescription(struct ScriptContext *ctx)
{
}
#endif // OW_SHOW_ITEM_DESCRIPTIONS

View File

@ -60,6 +60,7 @@
#include "constants/union_room.h"
#include "constants/weather.h"
#include "wild_encounter.h"
#include "ev_caps.h"
#define FRIENDSHIP_EVO_THRESHOLD ((P_FRIENDSHIP_EVO_THRESHOLD >= GEN_9) ? 160 : 220)
@ -3752,6 +3753,9 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
s8 evChange;
u16 evCount;
// Determine the EV cap to use
u32 maxAllowedEVs = !B_EV_ITEMS_CAP ? MAX_TOTAL_EVS : GetCurrentEVCap();
// Get item hold effect
heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, NULL);
if (heldItem == ITEM_ENIGMA_BERRY_E_READER)
@ -3879,27 +3883,31 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
if (evChange > 0) // Increasing EV (HP or Atk)
{
// Has EV increase limit already been reached?
if (evCount >= MAX_TOTAL_EVS)
// Check if the total EV limit is reached
if (evCount >= maxAllowedEVs)
return TRUE;
if (itemEffect[10] & ITEM10_IS_VITAMIN)
evCap = EV_ITEM_RAISE_LIMIT;
else
evCap = MAX_PER_STAT_EVS;
// Ensure the increase does not exceed the max EV per stat (252)
evCap = (itemEffect[10] & ITEM10_IS_VITAMIN) ? EV_ITEM_RAISE_LIMIT : MAX_PER_STAT_EVS;
// Check if the per-stat limit is reached
if (dataSigned >= evCap)
break;
// Limit the increase
return TRUE; // Prevents item use if the per-stat cap is already reached
if (dataSigned + evChange > evCap)
temp2 = evCap - (dataSigned + evChange) + evChange;
temp2 = evCap - dataSigned;
else
temp2 = evChange;
if (evCount + temp2 > MAX_TOTAL_EVS)
temp2 += MAX_TOTAL_EVS - (evCount + temp2);
// Ensure the total EVs do not exceed the maximum allowed (510)
if (evCount + temp2 > maxAllowedEVs)
temp2 = maxAllowedEVs - evCount;
// Prevent item use if no EVs can be increased
if (temp2 == 0)
return TRUE;
// Apply the EV increase
dataSigned += temp2;
}
else if (evChange < 0) // Decreasing EV (HP or Atk)
@ -4064,27 +4072,31 @@ bool8 PokemonUseItemEffects(struct Pokemon *mon, u16 item, u8 partyIndex, u8 mov
evChange = temp2;
if (evChange > 0) // Increasing EV
{
// Has EV increase limit already been reached?
if (evCount >= MAX_TOTAL_EVS)
// Check if the total EV limit is reached
if (evCount >= maxAllowedEVs)
return TRUE;
if (itemEffect[10] & ITEM10_IS_VITAMIN)
evCap = EV_ITEM_RAISE_LIMIT;
else
evCap = MAX_PER_STAT_EVS;
// Ensure the increase does not exceed the max EV per stat (252)
evCap = (itemEffect[10] & ITEM10_IS_VITAMIN) ? EV_ITEM_RAISE_LIMIT : MAX_PER_STAT_EVS;
// Check if the per-stat limit is reached
if (dataSigned >= evCap)
break;
// Limit the increase
return TRUE; // Prevents item use if the per-stat cap is already reached
if (dataSigned + evChange > evCap)
temp2 = evCap - (dataSigned + evChange) + evChange;
temp2 = evCap - dataSigned;
else
temp2 = evChange;
if (evCount + temp2 > MAX_TOTAL_EVS)
temp2 += MAX_TOTAL_EVS - (evCount + temp2);
// Ensure the total EVs do not exceed the maximum allowed (510)
if (evCount + temp2 > maxAllowedEVs)
temp2 = maxAllowedEVs - evCount;
// Prevent item use if no EVs can be increased
if (temp2 == 0)
return TRUE;
// Apply the EV increase
dataSigned += temp2;
}
else if (evChange < 0) // Decreasing EV
@ -5195,6 +5207,7 @@ void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies)
int i, multiplier;
u8 stat;
u8 bonus;
u32 currentEVCap = GetCurrentEVCap();
heldItem = GetMonData(mon, MON_DATA_HELD_ITEM, 0);
if (heldItem == ITEM_ENIGMA_BERRY_E_READER)
@ -5224,7 +5237,7 @@ void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies)
for (i = 0; i < NUM_STATS; i++)
{
if (totalEVs >= MAX_TOTAL_EVS)
if (totalEVs >= currentEVCap)
break;
if (CheckPartyHasHadPokerus(mon, 0))
@ -5275,8 +5288,8 @@ void MonGainEVs(struct Pokemon *mon, u16 defeatedSpecies)
if (holdEffect == HOLD_EFFECT_MACHO_BRACE)
evIncrease *= 2;
if (totalEVs + (s16)evIncrease > MAX_TOTAL_EVS)
evIncrease = ((s16)evIncrease + MAX_TOTAL_EVS) - (totalEVs + evIncrease);
if (totalEVs + (s16)evIncrease > currentEVCap)
evIncrease = ((s16)evIncrease + currentEVCap) - (totalEVs + evIncrease);
if (evs[i] + (s16)evIncrease > MAX_PER_STAT_EVS)
{
@ -6889,7 +6902,7 @@ const u8 *GetMoveAnimationScript(u16 moveId)
if (gMovesInfo[moveId].battleAnimScript == NULL)
{
DebugPrintfLevel(MGBA_LOG_WARN, "No animation for moveId=%u", moveId);
return Move_TACKLE;
return gMovesInfo[MOVE_NONE].battleAnimScript;
}
return gMovesInfo[moveId].battleAnimScript;
}

View File

@ -892,16 +892,20 @@ static void UnkUtil_DmaRun(struct UnkUtilData *);
void SetMonFormPSS(struct BoxPokemon *boxMon);
void UpdateSpeciesSpritePSS(struct BoxPokemon *boxmon);
static const u8 gText_JustOnePkmn[] = _("There is just one POKéMON with you.");
static const u8 gText_PartyFull[] = _("Your party is full!");
static const u8 gText_Box[] = _("BOX");
struct {
const u8 *text;
const u8 *desc;
} static const sMainMenuTexts[OPTIONS_COUNT] =
{
[OPTION_WITHDRAW] = {gText_WithdrawPokemon, gText_WithdrawMonDescription},
[OPTION_DEPOSIT] = {gText_DepositPokemon, gText_DepositMonDescription},
[OPTION_MOVE_MONS] = {gText_MovePokemon, gText_MoveMonDescription},
[OPTION_MOVE_ITEMS] = {gText_MoveItems, gText_MoveItemsDescription},
[OPTION_EXIT] = {gText_SeeYa, gText_SeeYaDescription}
[OPTION_WITHDRAW] = {COMPOUND_STRING("WITHDRAW POKéMON"), COMPOUND_STRING("Move POKéMON stored in BOXES to\nyour party.")},
[OPTION_DEPOSIT] = {COMPOUND_STRING("DEPOSIT POKéMON"), COMPOUND_STRING("Store POKéMON in your party in BOXES.")},
[OPTION_MOVE_MONS] = {COMPOUND_STRING("MOVE POKéMON"), COMPOUND_STRING("Organize the POKéMON in BOXES and\nin your party.")},
[OPTION_MOVE_ITEMS] = {COMPOUND_STRING("MOVE ITEMS"), COMPOUND_STRING("Move items held by any POKéMON\nin a BOX or your party.")},
[OPTION_EXIT] = {COMPOUND_STRING("SEE YA!"), COMPOUND_STRING("Return to the previous menu.")}
};
static const struct WindowTemplate sWindowTemplate_MainMenu =
@ -1078,39 +1082,41 @@ static const struct SpriteTemplate sSpriteTemplate_DisplayMon =
.callback = SpriteCallbackDummy,
};
static const u8 gText_PkmnIsSelected[] = _("{DYNAMIC 0} is selected.");
static const struct StorageMessage sMessages[] =
{
[MSG_EXIT_BOX] = {gText_ExitFromBox, MSG_VAR_NONE},
[MSG_WHAT_YOU_DO] = {gText_WhatDoYouWantToDo, MSG_VAR_NONE},
[MSG_PICK_A_THEME] = {gText_PleasePickATheme, MSG_VAR_NONE},
[MSG_PICK_A_WALLPAPER] = {gText_PickTheWallpaper, MSG_VAR_NONE},
[MSG_IS_SELECTED] = {gText_PkmnIsSelected, MSG_VAR_MON_NAME_1},
[MSG_JUMP_TO_WHICH_BOX] = {gText_JumpToWhichBox, MSG_VAR_NONE},
[MSG_DEPOSIT_IN_WHICH_BOX] = {gText_DepositInWhichBox, MSG_VAR_NONE},
[MSG_WAS_DEPOSITED] = {gText_PkmnWasDeposited, MSG_VAR_MON_NAME_1},
[MSG_BOX_IS_FULL] = {gText_BoxIsFull2, MSG_VAR_NONE},
[MSG_RELEASE_POKE] = {gText_ReleaseThisPokemon, MSG_VAR_NONE},
[MSG_WAS_RELEASED] = {gText_PkmnWasReleased, MSG_VAR_RELEASE_MON_1},
[MSG_BYE_BYE] = {gText_ByeByePkmn, MSG_VAR_RELEASE_MON_3},
[MSG_MARK_POKE] = {gText_MarkYourPkmn, MSG_VAR_NONE},
[MSG_LAST_POKE] = {gText_ThatsYourLastPkmn, MSG_VAR_NONE},
[MSG_PARTY_FULL] = {gText_YourPartysFull, MSG_VAR_NONE},
[MSG_HOLDING_POKE] = {gText_YoureHoldingAPkmn, MSG_VAR_NONE},
[MSG_WHICH_ONE_WILL_TAKE] = {gText_WhichOneWillYouTake, MSG_VAR_NONE},
[MSG_CANT_RELEASE_EGG] = {gText_YouCantReleaseAnEgg, MSG_VAR_NONE},
[MSG_CONTINUE_BOX] = {gText_ContinueBoxOperations, MSG_VAR_NONE},
[MSG_CAME_BACK] = {gText_PkmnCameBack, MSG_VAR_MON_NAME_1},
[MSG_WORRIED] = {gText_WasItWorriedAboutYou, MSG_VAR_NONE},
[MSG_SURPRISE] = {gText_FourEllipsesExclamation, MSG_VAR_NONE},
[MSG_PLEASE_REMOVE_MAIL] = {gText_PleaseRemoveTheMail, MSG_VAR_NONE},
[MSG_IS_SELECTED2] = {gText_PkmnIsSelected, MSG_VAR_ITEM_NAME},
[MSG_GIVE_TO_MON] = {gText_GiveToAPkmn, MSG_VAR_NONE},
[MSG_PLACED_IN_BAG] = {gText_PlacedItemInBag, MSG_VAR_ITEM_NAME},
[MSG_BAG_FULL] = {gText_BagIsFull2, MSG_VAR_NONE},
[MSG_PUT_IN_BAG] = {gText_PutItemInBag, MSG_VAR_NONE},
[MSG_ITEM_IS_HELD] = {gText_ItemIsNowHeld, MSG_VAR_ITEM_NAME},
[MSG_CHANGED_TO_ITEM] = {gText_ChangedToNewItem, MSG_VAR_ITEM_NAME},
[MSG_CANT_STORE_MAIL] = {gText_MailCantBeStored, MSG_VAR_NONE},
[MSG_EXIT_BOX] = {COMPOUND_STRING("Exit from the BOX?"), MSG_VAR_NONE},
[MSG_WHAT_YOU_DO] = {COMPOUND_STRING("What do you want to do?"), MSG_VAR_NONE},
[MSG_PICK_A_THEME] = {COMPOUND_STRING("Please pick a theme."), MSG_VAR_NONE},
[MSG_PICK_A_WALLPAPER] = {COMPOUND_STRING("Pick the wallpaper."), MSG_VAR_NONE},
[MSG_IS_SELECTED] = {gText_PkmnIsSelected, MSG_VAR_MON_NAME_1},
[MSG_JUMP_TO_WHICH_BOX] = {COMPOUND_STRING("Jump to which BOX?"), MSG_VAR_NONE},
[MSG_DEPOSIT_IN_WHICH_BOX] = {COMPOUND_STRING("Deposit in which BOX?"), MSG_VAR_NONE},
[MSG_WAS_DEPOSITED] = {COMPOUND_STRING("{DYNAMIC 0} was deposited."), MSG_VAR_MON_NAME_1},
[MSG_BOX_IS_FULL] = {COMPOUND_STRING("The BOX is full."), MSG_VAR_NONE},
[MSG_RELEASE_POKE] = {COMPOUND_STRING("Release this POKéMON?"), MSG_VAR_NONE},
[MSG_WAS_RELEASED] = {COMPOUND_STRING("{DYNAMIC 0} was released."), MSG_VAR_RELEASE_MON_1},
[MSG_BYE_BYE] = {COMPOUND_STRING("Bye-bye, {DYNAMIC 0}!"), MSG_VAR_RELEASE_MON_3},
[MSG_MARK_POKE] = {COMPOUND_STRING("Mark your POKéMON."), MSG_VAR_NONE},
[MSG_LAST_POKE] = {COMPOUND_STRING("That's your last POKéMON!"), MSG_VAR_NONE},
[MSG_PARTY_FULL] = {gText_YourPartysFull, MSG_VAR_NONE},
[MSG_HOLDING_POKE] = {COMPOUND_STRING("You're holding a POKéMON!"), MSG_VAR_NONE},
[MSG_WHICH_ONE_WILL_TAKE] = {COMPOUND_STRING("Which one will you take?"), MSG_VAR_NONE},
[MSG_CANT_RELEASE_EGG] = {COMPOUND_STRING("You can't release an EGG."), MSG_VAR_NONE},
[MSG_CONTINUE_BOX] = {COMPOUND_STRING("Continue BOX operations?"), MSG_VAR_NONE},
[MSG_CAME_BACK] = {COMPOUND_STRING("{DYNAMIC 0} came back!"), MSG_VAR_MON_NAME_1},
[MSG_WORRIED] = {COMPOUND_STRING("Was it worried about you?"), MSG_VAR_NONE},
[MSG_SURPRISE] = {COMPOUND_STRING("… … … … !"), MSG_VAR_NONE},
[MSG_PLEASE_REMOVE_MAIL] = {COMPOUND_STRING("Please remove the MAIL."), MSG_VAR_NONE},
[MSG_IS_SELECTED2] = {gText_PkmnIsSelected, MSG_VAR_ITEM_NAME},
[MSG_GIVE_TO_MON] = {COMPOUND_STRING("GIVE to a POKéMON?"), MSG_VAR_NONE},
[MSG_PLACED_IN_BAG] = {COMPOUND_STRING("Placed item in the BAG."), MSG_VAR_ITEM_NAME},
[MSG_BAG_FULL] = {COMPOUND_STRING("The BAG is full."), MSG_VAR_NONE},
[MSG_PUT_IN_BAG] = {COMPOUND_STRING("Put this item in the BAG?"), MSG_VAR_NONE},
[MSG_ITEM_IS_HELD] = {COMPOUND_STRING("{DYNAMIC 0} is now held."), MSG_VAR_ITEM_NAME},
[MSG_CHANGED_TO_ITEM] = {COMPOUND_STRING("Changed to {DYNAMIC 0}."), MSG_VAR_ITEM_NAME},
[MSG_CANT_STORE_MAIL] = {COMPOUND_STRING("MAIL can't be stored!"), MSG_VAR_NONE},
};
static const struct WindowTemplate sYesNoWindowTemplate =
@ -8041,47 +8047,49 @@ static void InitMenu(void)
sStorage->menuWindow.baseBlock = 92;
}
static const u8 gPCText_Give[] = _("GIVE");
static const u8 *const sMenuTexts[] =
{
[MENU_CANCEL] = gPCText_Cancel,
[MENU_STORE] = gPCText_Store,
[MENU_WITHDRAW] = gPCText_Withdraw,
[MENU_MOVE] = gPCText_Move,
[MENU_SHIFT] = gPCText_Shift,
[MENU_PLACE] = gPCText_Place,
[MENU_SUMMARY] = gPCText_Summary,
[MENU_RELEASE] = gPCText_Release,
[MENU_MARK] = gPCText_Mark,
[MENU_JUMP] = gPCText_Jump,
[MENU_WALLPAPER] = gPCText_Wallpaper,
[MENU_NAME] = gPCText_Name,
[MENU_TAKE] = gPCText_Take,
[MENU_CANCEL] = COMPOUND_STRING("CANCEL"),
[MENU_STORE] = COMPOUND_STRING("STORE"),
[MENU_WITHDRAW] = COMPOUND_STRING("WITHDRAW"),
[MENU_MOVE] = COMPOUND_STRING("SHIFT"),
[MENU_SHIFT] = COMPOUND_STRING("MOVE"),
[MENU_PLACE] = COMPOUND_STRING("PLACE"),
[MENU_SUMMARY] = COMPOUND_STRING("SUMMARY"),
[MENU_RELEASE] = COMPOUND_STRING("RELEASE"),
[MENU_MARK] = COMPOUND_STRING("MARK"),
[MENU_JUMP] = COMPOUND_STRING("NAME"),
[MENU_WALLPAPER] = COMPOUND_STRING("JUMP"),
[MENU_NAME] = COMPOUND_STRING("WALLPAPER"),
[MENU_TAKE] = COMPOUND_STRING("TAKE"),
[MENU_GIVE] = gPCText_Give,
[MENU_GIVE_2] = gPCText_Give,
[MENU_SWITCH] = gPCText_Switch,
[MENU_BAG] = gPCText_Bag,
[MENU_INFO] = gPCText_Info,
[MENU_SCENERY_1] = gPCText_Scenery1,
[MENU_SCENERY_2] = gPCText_Scenery2,
[MENU_SCENERY_3] = gPCText_Scenery3,
[MENU_ETCETERA] = gPCText_Etcetera,
[MENU_FRIENDS] = gPCText_Friends,
[MENU_FOREST] = gPCText_Forest,
[MENU_CITY] = gPCText_City,
[MENU_DESERT] = gPCText_Desert,
[MENU_SAVANNA] = gPCText_Savanna,
[MENU_CRAG] = gPCText_Crag,
[MENU_VOLCANO] = gPCText_Volcano,
[MENU_SNOW] = gPCText_Snow,
[MENU_CAVE] = gPCText_Cave,
[MENU_BEACH] = gPCText_Beach,
[MENU_SEAFLOOR] = gPCText_Seafloor,
[MENU_RIVER] = gPCText_River,
[MENU_SKY] = gPCText_Sky,
[MENU_POLKADOT] = gPCText_PolkaDot,
[MENU_POKECENTER] = gPCText_Pokecenter,
[MENU_MACHINE] = gPCText_Machine,
[MENU_SIMPLE] = gPCText_Simple,
[MENU_SWITCH] = COMPOUND_STRING("SWITCH"),
[MENU_BAG] = COMPOUND_STRING("BAG"),
[MENU_INFO] = COMPOUND_STRING("INFO"),
[MENU_SCENERY_1] = COMPOUND_STRING("SCENERY 1"),
[MENU_SCENERY_2] = COMPOUND_STRING("SCENERY 2"),
[MENU_SCENERY_3] = COMPOUND_STRING("SCENERY 3"),
[MENU_ETCETERA] = COMPOUND_STRING("ETCETERA"),
[MENU_FRIENDS] = COMPOUND_STRING("FRIENDS"),
[MENU_FOREST] = COMPOUND_STRING("FOREST"),
[MENU_CITY] = COMPOUND_STRING("CITY"),
[MENU_DESERT] = COMPOUND_STRING("DESERT"),
[MENU_SAVANNA] = COMPOUND_STRING("SAVANNA"),
[MENU_CRAG] = COMPOUND_STRING("CRAG"),
[MENU_VOLCANO] = COMPOUND_STRING("VOLCANO"),
[MENU_SNOW] = COMPOUND_STRING("SNOW"),
[MENU_CAVE] = COMPOUND_STRING("CAVE"),
[MENU_BEACH] = COMPOUND_STRING("BEACH"),
[MENU_SEAFLOOR] = COMPOUND_STRING("SEAFLOOR"),
[MENU_RIVER] = COMPOUND_STRING("RIVER"),
[MENU_SKY] = COMPOUND_STRING("SKY"),
[MENU_POLKADOT] = COMPOUND_STRING("POLKA-DOT"),
[MENU_POKECENTER] = COMPOUND_STRING("POKéCENTER"),
[MENU_MACHINE] = COMPOUND_STRING("MACHINE"),
[MENU_SIMPLE] = COMPOUND_STRING("SIMPLE"),
};
static void SetMenuText(u8 textId)

View File

@ -1127,6 +1127,7 @@ static void BuyMenuTryMakePurchase(u8 taskId)
{
if (AddBagItem(tItemId, tItemCount) == TRUE)
{
GetSetItemObtained(tItemId, FLAG_SET_ITEM_OBTAINED);
RecordItemPurchase(taskId);
BuyMenuDisplayMessage(taskId, gText_HereYouGoThankYou, BuyMenuSubtractMoney);
}

View File

@ -814,88 +814,7 @@ const u8 gText_MtPyre[] = _("MT. PYRE");
const u8 gText_SkyPillar[] = _("SKY PILLAR");
const u8 gText_DontRemember[] = _("Don't remember");
const u8 gText_Exit[] = _("EXIT");
const u8 gText_ExitFromBox[] = _("Exit from the BOX?");
const u8 gText_WhatDoYouWantToDo[] = _("What do you want to do?");
const u8 gText_PleasePickATheme[] = _("Please pick a theme.");
const u8 gText_PickTheWallpaper[] = _("Pick the wallpaper.");
const u8 gText_PkmnIsSelected[] = _("{DYNAMIC 0} is selected.");
const u8 gText_JumpToWhichBox[] = _("Jump to which BOX?");
const u8 gText_DepositInWhichBox[] = _("Deposit in which BOX?");
const u8 gText_PkmnWasDeposited[] = _("{DYNAMIC 0} was deposited.");
const u8 gText_BoxIsFull2[] = _("The BOX is full.");
const u8 gText_ReleaseThisPokemon[] = _("Release this POKéMON?");
const u8 gText_PkmnWasReleased[] = _("{DYNAMIC 0} was released.");
const u8 gText_ByeByePkmn[] = _("Bye-bye, {DYNAMIC 0}!");
const u8 gText_MarkYourPkmn[] = _("Mark your POKéMON.");
const u8 gText_ThatsYourLastPkmn[] = _("That's your last POKéMON!");
const u8 gText_YourPartysFull[] = _("Your party's full!{PAUSE_UNTIL_PRESS}");
const u8 gText_YoureHoldingAPkmn[] = _("You're holding a POKéMON!");
const u8 gText_WhichOneWillYouTake[] = _("Which one will you take?");
const u8 gText_YouCantReleaseAnEgg[] = _("You can't release an EGG.");
const u8 gText_ContinueBoxOperations[] = _("Continue BOX operations?");
const u8 gText_PkmnCameBack[] = _("{DYNAMIC 0} came back!");
const u8 gText_WasItWorriedAboutYou[] = _("Was it worried about you?");
const u8 gText_FourEllipsesExclamation[] = _("… … … … !");
const u8 gText_PleaseRemoveTheMail[] = _("Please remove the MAIL.");
const u8 gText_GiveToAPkmn[] = _("GIVE to a POKéMON?");
const u8 gText_PlacedItemInBag[] = _("Placed item in the BAG.");
const u8 gText_BagIsFull2[] = _("The BAG is full.");
const u8 gText_PutItemInBag[] = _("Put this item in the BAG?");
const u8 gText_ItemIsNowHeld[] = _("{DYNAMIC 0} is now held.");
const u8 gText_ChangedToNewItem[] = _("Changed to {DYNAMIC 0}.");
const u8 gText_MailCantBeStored[] = _("MAIL can't be stored!");
const u8 gPCText_Cancel[] = _("CANCEL");
const u8 gPCText_Store[] = _("STORE");
const u8 gPCText_Withdraw[] = _("WITHDRAW");
const u8 gPCText_Shift[] = _("SHIFT");
const u8 gPCText_Move[] = _("MOVE");
const u8 gPCText_Place[] = _("PLACE");
const u8 gPCText_Summary[] = _("SUMMARY");
const u8 gPCText_Release[] = _("RELEASE");
const u8 gPCText_Mark[] = _("MARK");
const u8 gPCText_Name[] = _("NAME");
const u8 gPCText_Jump[] = _("JUMP");
const u8 gPCText_Wallpaper[] = _("WALLPAPER");
const u8 gPCText_Take[] = _("TAKE");
const u8 gPCText_Give[] = _("GIVE");
const u8 gPCText_Switch[] = _("SWITCH");
const u8 gPCText_Bag[] = _("BAG");
const u8 gPCText_Info[] = _("INFO");
const u8 gPCText_Scenery1[] = _("SCENERY 1");
const u8 gPCText_Scenery2[] = _("SCENERY 2");
const u8 gPCText_Scenery3[] = _("SCENERY 3");
const u8 gPCText_Etcetera[] = _("ETCETERA");
const u8 gPCText_Friends[] = _("FRIENDS");
const u8 gPCText_Forest[] = _("FOREST");
const u8 gPCText_City[] = _("CITY");
const u8 gPCText_Desert[] = _("DESERT");
const u8 gPCText_Savanna[] = _("SAVANNA");
const u8 gPCText_Crag[] = _("CRAG");
const u8 gPCText_Volcano[] = _("VOLCANO");
const u8 gPCText_Snow[] = _("SNOW");
const u8 gPCText_Cave[] = _("CAVE");
const u8 gPCText_Beach[] = _("BEACH");
const u8 gPCText_Seafloor[] = _("SEAFLOOR");
const u8 gPCText_River[] = _("RIVER");
const u8 gPCText_Sky[] = _("SKY");
const u8 gPCText_PolkaDot[] = _("POLKA-DOT");
const u8 gPCText_Pokecenter[] = _("POKéCENTER");
const u8 gPCText_Machine[] = _("MACHINE");
const u8 gPCText_Simple[] = _("SIMPLE");
const u8 gText_WhatWouldYouLikeToDo[] = _("What would you like to do?"); // Unused
const u8 gText_WithdrawPokemon[] = _("WITHDRAW POKéMON");
const u8 gText_DepositPokemon[] = _("DEPOSIT POKéMON");
const u8 gText_MovePokemon[] = _("MOVE POKéMON");
const u8 gText_MoveItems[] = _("MOVE ITEMS");
const u8 gText_SeeYa[] = _("SEE YA!");
const u8 gText_WithdrawMonDescription[] = _("Move POKéMON stored in BOXES to\nyour party.");
const u8 gText_DepositMonDescription[] = _("Store POKéMON in your party in BOXES.");
const u8 gText_MoveMonDescription[] = _("Organize the POKéMON in BOXES and\nin your party.");
const u8 gText_MoveItemsDescription[] = _("Move items held by any POKéMON\nin a BOX or your party.");
const u8 gText_SeeYaDescription[] = _("Return to the previous menu.");
const u8 gText_JustOnePkmn[] = _("There is just one POKéMON with you.");
const u8 gText_PartyFull[] = _("Your party is full!");
const u8 gText_Box[] = _("BOX");
const u8 gText_NatureSlash[] = _("NATURE/");
const u8 gText_InParty[] = _("IN PARTY");
const u8 gText_PokemonMaleLv[] = _("{DYNAMIC 0}{COLOR_HIGHLIGHT_SHADOW LIGHT_RED WHITE GREEN}♂{COLOR_HIGHLIGHT_SHADOW DARK_GRAY WHITE LIGHT_GRAY}/{LV}{DYNAMIC 1}"); // Unused

View File

@ -11,6 +11,7 @@
#include "pokeblock.h"
#include "battle_setup.h"
#include "roamer.h"
#include "rtc.h"
#include "tv.h"
#include "link.h"
#include "script.h"
@ -354,9 +355,32 @@ static u8 ChooseWildMonLevel(const struct WildPokemon *wildPokemon, u8 wildMonIn
}
}
static bool8 IsExactTimeOfDayMatchForWildEncounters(u8 currentTimeOfDay, u8 encounterTimeOfDay)
{
switch (currentTimeOfDay)
{
case TIME_MORNING:
if (OW_ENABLE_MORNING_WILD_ENCOUNTERS)
return encounterTimeOfDay == TIME_MORNING;
// fallthrough
case TIME_DAY:
return encounterTimeOfDay == TIME_DAY;
case TIME_EVENING:
if (OW_ENABLE_EVENING_WILD_ENCOUNTERS)
return encounterTimeOfDay == TIME_EVENING;
// fallthrough
case TIME_NIGHT:
return encounterTimeOfDay == TIME_NIGHT;
}
return FALSE;
}
static u16 GetCurrentMapWildMonHeaderId(void)
{
u16 i;
u8 currentTimeOfDay = GetTimeOfDay();
u16 dayId = HEADER_NONE;
u16 nightId = HEADER_NONE;
for (i = 0; ; i++)
{
@ -375,13 +399,30 @@ static u16 GetCurrentMapWildMonHeaderId(void)
alteringCaveId = 0;
i += alteringCaveId;
return i; // Altering cave is not affected by time-of-day encounters.
}
return i;
if (OW_TIME_BASED_WILD_ENCOUNTERS)
{
if (IsExactTimeOfDayMatchForWildEncounters(currentTimeOfDay, gWildMonHeaders[i].timeOfDay))
return i;
else if (gWildMonHeaders[i].timeOfDay == TIME_DAY && dayId == HEADER_NONE)
dayId = i;
else if (gWildMonHeaders[i].timeOfDay == TIME_NIGHT && nightId == HEADER_NONE)
nightId = i;
}
else
return i;
}
}
return HEADER_NONE;
if (!OW_TIME_BASED_WILD_ENCOUNTERS)
return HEADER_NONE;
// Exact match for time of day was not found. We fall back to other encounter groups for this map
if (currentTimeOfDay == TIME_EVENING && OW_ENABLE_EVENING_WILD_ENCOUNTERS && nightId != HEADER_NONE)
return nightId;
return dayId;
}
u8 PickWildMonNature(void)

View File

@ -3,9 +3,8 @@
SINGLE_BATTLE_TEST("Anger Point raises Attack stage to maximum after receiving a critical hit")
{
ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit);
GIVEN {
ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit);
PLAYER(SPECIES_PRIMEAPE) { Ability(ABILITY_ANGER_POINT); }
OPPONENT(SPECIES_SNORUNT);
} WHEN {
@ -23,10 +22,9 @@ SINGLE_BATTLE_TEST("Anger Point raises Attack stage to maximum after receiving a
SINGLE_BATTLE_TEST("Anger Point does not trigger when already at maximum Attack stage")
{
ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit);
ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM);
GIVEN {
ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit);
ASSUME(gMovesInfo[MOVE_BELLY_DRUM].effect == EFFECT_BELLY_DRUM);
PLAYER(SPECIES_PRIMEAPE) { Ability(ABILITY_ANGER_POINT); Speed(2); }
OPPONENT(SPECIES_SNORUNT) { Speed(1); }
} WHEN {
@ -51,10 +49,9 @@ TO_DO_BATTLE_TEST("Anger Point triggers when a substitute takes the hit (Gen4)")
SINGLE_BATTLE_TEST("Anger Point does not trigger when a substitute takes the hit (Gen5+)")
{
ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit);
ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE);
GIVEN {
ASSUME(gMovesInfo[MOVE_FROST_BREATH].alwaysCriticalHit);
ASSUME(gMovesInfo[MOVE_SUBSTITUTE].effect == EFFECT_SUBSTITUTE);
PLAYER(SPECIES_PRIMEAPE) { Ability(ABILITY_ANGER_POINT); Speed(2); }
OPPONENT(SPECIES_SNORUNT) { Speed(1); }
} WHEN {

View File

@ -28,10 +28,10 @@ SINGLE_BATTLE_TEST("Galvanize can not turn certain moves into Electric type move
PARAMETRIZE { move = MOVE_WEATHER_BALL; }
PARAMETRIZE { move = MOVE_MULTI_ATTACK; }
ASSUME(gMovesInfo[MOVE_HIDDEN_POWER].effect == EFFECT_HIDDEN_POWER);
ASSUME(gMovesInfo[MOVE_WEATHER_BALL].effect == EFFECT_WEATHER_BALL);
ASSUME(gMovesInfo[MOVE_MULTI_ATTACK].effect == EFFECT_CHANGE_TYPE_ON_ITEM);
GIVEN {
ASSUME(gMovesInfo[MOVE_HIDDEN_POWER].effect == EFFECT_HIDDEN_POWER);
ASSUME(gMovesInfo[MOVE_WEATHER_BALL].effect == EFFECT_WEATHER_BALL);
ASSUME(gMovesInfo[MOVE_MULTI_ATTACK].effect == EFFECT_CHANGE_TYPE_ON_ITEM);
PLAYER(SPECIES_KRABBY);
OPPONENT(SPECIES_GEODUDE_ALOLAN) { Ability(ABILITY_GALVANIZE); }
} WHEN {

View File

@ -60,8 +60,8 @@ SINGLE_BATTLE_TEST("Harvest doesn't always restore a Berry if Cloud Nine/Air Loc
SINGLE_BATTLE_TEST("Harvest restores a Berry even after being switched out and back in")
{
ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT);
GIVEN {
ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); MaxHP(500); HP(251); Item(ITEM_SITRUS_BERRY); }
OPPONENT(SPECIES_WOBBUFFET);
@ -79,8 +79,8 @@ SINGLE_BATTLE_TEST("Harvest restores a Berry even after being switched out and b
SINGLE_BATTLE_TEST("Harvest restores a Berry consumed by Fling")
{
ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING);
GIVEN {
ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -96,8 +96,8 @@ SINGLE_BATTLE_TEST("Harvest restores a Berry consumed by Fling")
SINGLE_BATTLE_TEST("Harvest restores a Berry consumed by Natural Gift")
{
ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT);
GIVEN {
ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -116,8 +116,8 @@ TO_DO_BATTLE_TEST("Harvest only works once per turn"); // Check for berries that
SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when destroyed by Incinerate")
{
PASSES_RANDOMLY(1, 1, RNG_HARVEST);
ASSUME(MoveHasAdditionalEffect(MOVE_INCINERATE, MOVE_EFFECT_INCINERATE));
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_INCINERATE, MOVE_EFFECT_INCINERATE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -134,8 +134,8 @@ SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when destroyed by Incinerate
SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when knocked off by Knock Off")
{
PASSES_RANDOMLY(1, 1, RNG_HARVEST);
ASSUME(MoveHasAdditionalEffect(MOVE_KNOCK_OFF, MOVE_EFFECT_KNOCK_OFF));
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_KNOCK_OFF, MOVE_EFFECT_KNOCK_OFF));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -152,8 +152,8 @@ SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when knocked off by Knock Of
SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when eaten by Bug Bite/Pluck")
{
PASSES_RANDOMLY(1, 1, RNG_HARVEST);
ASSUME(MoveHasAdditionalEffect(MOVE_BUG_BITE, MOVE_EFFECT_BUG_BITE));
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_BUG_BITE, MOVE_EFFECT_BUG_BITE));
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -208,8 +208,8 @@ DOUBLE_BATTLE_TEST("Harvest order is affected by speed")
SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when transfered to another Pokémon")
{
ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
GIVEN {
ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -225,8 +225,8 @@ SINGLE_BATTLE_TEST("Harvest doesn't restore a Berry when transfered to another P
SINGLE_BATTLE_TEST("Harvest can restore a Berry that was transferred from another Pokémon")
{
ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
GIVEN {
ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
PLAYER(SPECIES_TORKOAL) { Ability(ABILITY_DROUGHT); Item(ITEM_SITRUS_BERRY); }
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); HP(100); MaxHP(500); }
} WHEN {
@ -244,9 +244,9 @@ SINGLE_BATTLE_TEST("Harvest can restore a Berry that was transferred from anothe
SINGLE_BATTLE_TEST("Harvest can only restore the newest berry consumed that was transferred from another Pokémon instead of its original Berry")
{
ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
ASSUME(gItemsInfo[ITEM_APICOT_BERRY].holdEffect == HOLD_EFFECT_SP_DEFENSE_UP);
GIVEN {
ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
ASSUME(gItemsInfo[ITEM_APICOT_BERRY].holdEffect == HOLD_EFFECT_SP_DEFENSE_UP);
PLAYER(SPECIES_TORKOAL) { Ability(ABILITY_DROUGHT); Item(ITEM_SITRUS_BERRY); }
OPPONENT(SPECIES_EXEGGUTOR) { Ability(ABILITY_HARVEST); HP(100); MaxHP(500); Item(ITEM_APICOT_BERRY); }
} WHEN {

View File

@ -43,8 +43,8 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant the user their item")
SINGLE_BATTLE_TEST("Pickup doesn't grant another Pokémon's popped Air Balloon")
{
ASSUME(gItemsInfo[ITEM_AIR_BALLOON].holdEffect == HOLD_EFFECT_AIR_BALLOON);
GIVEN {
ASSUME(gItemsInfo[ITEM_AIR_BALLOON].holdEffect == HOLD_EFFECT_AIR_BALLOON);
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_AIR_BALLOON); }
} WHEN {
@ -102,8 +102,8 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an item after its holder faints")
SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if holder is replaced")
{
ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT);
GIVEN {
ASSUME(gMovesInfo[MOVE_PARTING_SHOT].effect == EFFECT_PARTING_SHOT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { MaxHP(300); HP(151); Item(ITEM_SITRUS_BERRY); }
@ -127,8 +127,8 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if holder is replaced")
SINGLE_BATTLE_TEST("Pickup doesn't grant an item if it destroyed the item with Incinerate")
{
ASSUME(MoveHasAdditionalEffect(MOVE_INCINERATE, MOVE_EFFECT_INCINERATE));
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_INCINERATE, MOVE_EFFECT_INCINERATE));
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -146,8 +146,8 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an item if it destroyed the item with I
SINGLE_BATTLE_TEST("Pickup doesn't grant an item if it knocked off that item")
{
ASSUME(MoveHasAdditionalEffect(MOVE_KNOCK_OFF, MOVE_EFFECT_KNOCK_OFF));
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_KNOCK_OFF, MOVE_EFFECT_KNOCK_OFF));
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -165,8 +165,8 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an item if it knocked off that item")
SINGLE_BATTLE_TEST("Pickup doesn't grant an item if the user eats it with Bug Bite/Pluck")
{
ASSUME(MoveHasAdditionalEffect(MOVE_BUG_BITE, MOVE_EFFECT_BUG_BITE));
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_BUG_BITE, MOVE_EFFECT_BUG_BITE));
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -184,8 +184,8 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an item if the user eats it with Bug Bi
SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if its user already restored it")
{
ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE);
GIVEN {
ASSUME(gMovesInfo[MOVE_RECYCLE].effect == EFFECT_RECYCLE);
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -204,8 +204,8 @@ SINGLE_BATTLE_TEST("Pickup doesn't grant an used item if its user already restor
SINGLE_BATTLE_TEST("Pickup restores an item that has been Flinged")
{
ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING);
GIVEN {
ASSUME(gMovesInfo[MOVE_FLING].effect == EFFECT_FLING);
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -221,8 +221,8 @@ SINGLE_BATTLE_TEST("Pickup restores an item that has been Flinged")
SINGLE_BATTLE_TEST("Pickup restores an item that was used by Natural Gift")
{
ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT);
GIVEN {
ASSUME(gMovesInfo[MOVE_NATURAL_GIFT].effect == EFFECT_NATURAL_GIFT);
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_SITRUS_BERRY); }
} WHEN {
@ -258,8 +258,8 @@ DOUBLE_BATTLE_TEST("Pickup triggers based on Speed order")
DOUBLE_BATTLE_TEST("Pickup grants a random item used by another Pokémon")
{
PASSES_RANDOMLY(1, 3, RNG_PICKUP);
ASSUME(gItemsInfo[ITEM_WHITE_HERB].holdEffect == HOLD_EFFECT_RESTORE_STATS);
GIVEN {
ASSUME(gItemsInfo[ITEM_WHITE_HERB].holdEffect == HOLD_EFFECT_RESTORE_STATS);
PLAYER(SPECIES_ZIGZAGOON) { Ability(ABILITY_PICKUP); }
PLAYER(SPECIES_WOBBUFFET) { Item(ITEM_WHITE_HERB); }
OPPONENT(SPECIES_WOBBUFFET) { MaxHP(100); HP(51); Item(ITEM_SITRUS_BERRY); }

View File

@ -107,8 +107,8 @@ SINGLE_BATTLE_TEST("Wind Rider activates when it's no longer effected by Neutral
SINGLE_BATTLE_TEST("Wind Rider absorbs Wind moves and raises Attack by one stage")
{
ASSUME(gMovesInfo[MOVE_GUST].windMove == TRUE);
GIVEN {
ASSUME(gMovesInfo[MOVE_GUST].windMove == TRUE);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_BRAMBLIN) { Ability(ABILITY_WIND_RIDER); }
} WHEN {

View File

@ -11,12 +11,12 @@ SINGLE_BATTLE_TEST("Shaymin-Sky reverts to Shaymin-Land when frozen or frostbitt
PARAMETRIZE { move = MOVE_POISON_STING; }
PARAMETRIZE { move = MOVE_POISON_FANG; }
ASSUME(MoveHasAdditionalEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE));
ASSUME(MoveHasAdditionalEffect(MOVE_EMBER, MOVE_EFFECT_BURN));
ASSUME(MoveHasAdditionalEffect(MOVE_THUNDERSHOCK, MOVE_EFFECT_PARALYSIS));
ASSUME(MoveHasAdditionalEffect(MOVE_POISON_STING, MOVE_EFFECT_POISON));
ASSUME(MoveHasAdditionalEffect(MOVE_POISON_FANG, MOVE_EFFECT_TOXIC));
GIVEN {
ASSUME(MoveHasAdditionalEffect(MOVE_POWDER_SNOW, MOVE_EFFECT_FREEZE_OR_FROSTBITE));
ASSUME(MoveHasAdditionalEffect(MOVE_EMBER, MOVE_EFFECT_BURN));
ASSUME(MoveHasAdditionalEffect(MOVE_THUNDERSHOCK, MOVE_EFFECT_PARALYSIS));
ASSUME(MoveHasAdditionalEffect(MOVE_POISON_STING, MOVE_EFFECT_POISON));
ASSUME(MoveHasAdditionalEffect(MOVE_POISON_FANG, MOVE_EFFECT_TOXIC));
PLAYER(SPECIES_SHAYMIN_SKY);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -400,6 +400,7 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves deal 1/4 damage through protect", s16 da
}
}
// This test will fail if it's the first test a thread runs
SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't bypass Max Guard")
{
GIVEN {
@ -1463,8 +1464,8 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't execute effects on fainted battler
SINGLE_BATTLE_TEST("(DYNAMAX) Moxie clones can be triggered by Max Moves fainting opponents")
{
ASSUME(gMovesInfo[MOVE_WATERFALL].power > 0);
GIVEN {
ASSUME(gMovesInfo[MOVE_WATERFALL].power > 0);
PLAYER(SPECIES_GYARADOS) { Ability(ABILITY_MOXIE); }
OPPONENT(SPECIES_WOBBUFFET) { HP(1); }
OPPONENT(SPECIES_WYNAUT);
@ -1476,3 +1477,54 @@ SINGLE_BATTLE_TEST("(DYNAMAX) Moxie clones can be triggered by Max Moves faintin
MESSAGE("Gyarados's Moxie raised its Attack!");
}
}
// This test will fail if it's the first test a thread runs
SINGLE_BATTLE_TEST("(DYNAMAX) Max Attacks prints a message when hitting into Max Guard")
{
GIVEN {
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
TURN { MOVE(player, MOVE_GROWL, gimmick: GIMMICK_DYNAMAX); MOVE(opponent, MOVE_TACKLE, gimmick: GIMMICK_DYNAMAX); }
} SCENE {
MESSAGE("Wobbuffet used Max Guard!");
MESSAGE("Foe Wobbuffet used Max Strike!");
}
}
SINGLE_BATTLE_TEST("(DYNAMAX) Max Moves don't bypass absorbing abilities")
{
u32 move, ability, species;
PARAMETRIZE { move = MOVE_SPARK; ability = ABILITY_VOLT_ABSORB; species = SPECIES_LANTURN; }
PARAMETRIZE { move = MOVE_WATER_GUN; ability = ABILITY_WATER_ABSORB; species = SPECIES_LANTURN; }
PARAMETRIZE { move = MOVE_EMBER; ability = ABILITY_FLASH_FIRE; species = SPECIES_HEATRAN; }
PARAMETRIZE { move = MOVE_SPARK; ability = ABILITY_LIGHTNING_ROD; species = SPECIES_PIKACHU; }
PARAMETRIZE { move = MOVE_WATER_GUN; ability = ABILITY_STORM_DRAIN; species = SPECIES_GASTRODON; }
PARAMETRIZE { move = MOVE_EMBER; ability = ABILITY_WELL_BAKED_BODY; species = SPECIES_DACHSBUN; }
PARAMETRIZE { move = MOVE_SPARK; ability = ABILITY_MOTOR_DRIVE; species = SPECIES_ELECTIVIRE; }
PARAMETRIZE { move = MOVE_WATER_GUN; ability = ABILITY_DRY_SKIN; species = SPECIES_PARASECT; }
PARAMETRIZE { move = MOVE_MUD_BOMB; ability = ABILITY_EARTH_EATER; species = SPECIES_ORTHWORM; }
PARAMETRIZE { move = MOVE_VINE_WHIP; ability = ABILITY_SAP_SIPPER; species = SPECIES_MILTANK; }
GIVEN {
ASSUME(gMovesInfo[MOVE_WATER_GUN].type == TYPE_WATER);
ASSUME(gMovesInfo[MOVE_SPARK].type == TYPE_ELECTRIC);
ASSUME(gMovesInfo[MOVE_EMBER].type == TYPE_FIRE);
ASSUME(gMovesInfo[MOVE_MUD_BOMB].type == TYPE_GROUND);
ASSUME(gMovesInfo[MOVE_VINE_WHIP].type == TYPE_GRASS);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(species) { Ability(ability); }
} WHEN {
TURN { MOVE(player, move, gimmick: GIMMICK_DYNAMAX); }
} SCENE {
NONE_OF {
ANIMATION(ANIM_TYPE_MOVE, MOVE_MAX_LIGHTNING, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_MAX_FLARE, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_MAX_GEYSER, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_MAX_QUAKE, player);
ANIMATION(ANIM_TYPE_MOVE, MOVE_MAX_OVERGROWTH, player);
HP_BAR(opponent);
}
ABILITY_POPUP(opponent, ability);
}
}

View File

@ -468,4 +468,4 @@ SINGLE_BATTLE_TEST("Red Card does not activate if holder is switched in mid-turn
}
}
// SINGLE_BATTLE_TEST("Red Card activates but fails if the attacker has Dynamaxed")
TO_DO_BATTLE_TEST("Red Card activates but fails if the attacker has Dynamaxed");

View File

@ -85,11 +85,11 @@ DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie
PARAMETRIZE {} // Hack to make permutations legal.
PASSES_RANDOMLY(24, 24, RNG_SPEED_TIE);
ASSUME(gMovesInfo[MOVE_ENDEAVOR].effect == EFFECT_ENDEAVOR);
ASSUME(gMovesInfo[MOVE_LIFE_DEW].effect == EFFECT_JUNGLE_HEALING);
ASSUME(gMovesInfo[MOVE_CRUSH_GRIP].effect == EFFECT_VARY_POWER_BASED_ON_HP);
ASSUME(gMovesInfo[MOVE_SUPER_FANG].effect == EFFECT_SUPER_FANG);
GIVEN {
ASSUME(gMovesInfo[MOVE_ENDEAVOR].effect == EFFECT_ENDEAVOR);
ASSUME(gMovesInfo[MOVE_LIFE_DEW].effect == EFFECT_JUNGLE_HEALING);
ASSUME(gMovesInfo[MOVE_CRUSH_GRIP].effect == EFFECT_VARY_POWER_BASED_ON_HP);
ASSUME(gMovesInfo[MOVE_SUPER_FANG].effect == EFFECT_SUPER_FANG);
PLAYER(SPECIES_WOBBUFFET) { MaxHP(480); HP(360); Defense(100); Speed(1); }
PLAYER(SPECIES_WYNAUT) { Speed(1); }
OPPONENT(SPECIES_WOBBUFFET) { Attack(100); Speed(1); }
@ -136,9 +136,9 @@ DOUBLE_BATTLE_TEST("Turn order is determined randomly if priority and Speed tie
SINGLE_BATTLE_TEST("Critical hits occur at a 1/24 rate")
{
ASSUME(B_CRIT_CHANCE >= GEN_7);
PASSES_RANDOMLY(1, 24, RNG_CRITICAL_HIT);
GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {
@ -150,10 +150,10 @@ SINGLE_BATTLE_TEST("Critical hits occur at a 1/24 rate")
SINGLE_BATTLE_TEST("Slash's critical hits occur at a 1/8 rate")
{
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
PASSES_RANDOMLY(1, 8, RNG_CRITICAL_HIT);
GIVEN {
ASSUME(B_CRIT_CHANCE >= GEN_7);
ASSUME(gMovesInfo[MOVE_SLASH].criticalHitStage == 1);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -26,8 +26,8 @@ SINGLE_BATTLE_TEST("Absorb recovers 50% of the damage dealt")
SINGLE_BATTLE_TEST("Absorb fails if Heal Block applies")
{
ASSUME(B_HEAL_BLOCKING >= GEN_6);
GIVEN {
ASSUME(B_HEAL_BLOCKING >= GEN_6);
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -8,9 +8,9 @@ ASSUMPTIONS
SINGLE_BATTLE_TEST("Sand Attack lowers Accuracy by 1 stage")
{
ASSUME(gMovesInfo[MOVE_SCRATCH].accuracy == 100);
PASSES_RANDOMLY(gMovesInfo[MOVE_SCRATCH].accuracy * 3 / 4, 100, RNG_ACCURACY);
GIVEN {
ASSUME(gMovesInfo[MOVE_SCRATCH].accuracy == 100);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -39,8 +39,8 @@ SINGLE_BATTLE_TEST("Dream Eater fails on awake targets")
SINGLE_BATTLE_TEST("Dream Eater fails if Heal Block applies")
{
ASSUME(B_HEAL_BLOCKING >= GEN_6);
GIVEN {
ASSUME(B_HEAL_BLOCKING >= GEN_6);
PLAYER(SPECIES_WOBBUFFET) { HP(1); }
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -8,9 +8,9 @@ ASSUMPTIONS
SINGLE_BATTLE_TEST("Double Team raises Evasion")
{
ASSUME(gMovesInfo[MOVE_SCRATCH].accuracy == 100);
PASSES_RANDOMLY(gMovesInfo[MOVE_SCRATCH].accuracy * 3 / 4, 100, RNG_ACCURACY);
GIVEN {
ASSUME(gMovesInfo[MOVE_SCRATCH].accuracy == 100);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_WOBBUFFET);
} WHEN {

View File

@ -158,9 +158,9 @@ SINGLE_BATTLE_TEST("Future Sight will miss timing if target faints by residual d
SINGLE_BATTLE_TEST("Future Sight breaks Focus Sash and doesn't make the holder endure another move")
{
ASSUME(gMovesInfo[MOVE_PSYCHIC].power > 0);
ASSUME(gItemsInfo[ITEM_FOCUS_SASH].holdEffect == HOLD_EFFECT_FOCUS_SASH);
GIVEN {
ASSUME(gMovesInfo[MOVE_PSYCHIC].power > 0);
ASSUME(gItemsInfo[ITEM_FOCUS_SASH].holdEffect == HOLD_EFFECT_FOCUS_SASH);
PLAYER(SPECIES_WOBBUFFET);
OPPONENT(SPECIES_PIDGEY) { Level(1); Item(ITEM_FOCUS_SASH); }
} WHEN {

View File

@ -88,9 +88,8 @@ SINGLE_BATTLE_TEST("Heal Bell cures inactive soundproof Pokemon")
SINGLE_BATTLE_TEST("Heal Bell cures a soundproof user")
{
ASSUME(B_HEAL_BELL_SOUNDPROOF == GEN_5 || B_HEAL_BELL_SOUNDPROOF >= GEN_8);
GIVEN {
ASSUME(B_HEAL_BELL_SOUNDPROOF == GEN_5 || B_HEAL_BELL_SOUNDPROOF >= GEN_8);
PLAYER(SPECIES_EXPLOUD) { Ability(ABILITY_SOUNDPROOF); Status1(STATUS1_POISON); }
OPPONENT(SPECIES_WYNAUT);
} WHEN {

View File

@ -23,8 +23,8 @@ DOUBLE_BATTLE_TEST("Instruct fails if target hasn't made a move")
DOUBLE_BATTLE_TEST("Instruct fails if move is banned by Instruct")
{
ASSUME(gMovesInfo[MOVE_BIDE].instructBanned == TRUE);
GIVEN {
ASSUME(gMovesInfo[MOVE_BIDE].instructBanned == TRUE);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_BIDE); }
OPPONENT(SPECIES_WOBBUFFET);
@ -59,8 +59,8 @@ DOUBLE_BATTLE_TEST("Instruct-called move targets the target of the move picked o
DOUBLE_BATTLE_TEST("Instruct doesn't bypass sleep")
{
ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP);
GIVEN {
ASSUME(gMovesInfo[MOVE_SPORE].effect == EFFECT_SLEEP);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); }
OPPONENT(SPECIES_WOBBUFFET);
@ -78,8 +78,8 @@ DOUBLE_BATTLE_TEST("Instruct doesn't bypass sleep")
DOUBLE_BATTLE_TEST("Instruct fails if target doesn't know the last move it used")
{
ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE);
GIVEN {
ASSUME(gMovesInfo[MOVE_DRAGON_DANCE].danceMove == TRUE);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_ORICORIO) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_CELEBRATE); }
OPPONENT(SPECIES_WOBBUFFET);
@ -99,8 +99,8 @@ DOUBLE_BATTLE_TEST("Instruct fails if target doesn't know the last move it used"
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 {
ASSUME(gMovesInfo[MOVE_FAKE_OUT].effect == EFFECT_FIRST_TURN_ONLY);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_FAKE_OUT); }
OPPONENT(SPECIES_WOBBUFFET);
@ -118,8 +118,8 @@ DOUBLE_BATTLE_TEST("Instruct-called move fails if it can only be used on the fir
DOUBLE_BATTLE_TEST("Instruct-called move doesn't fail if tormented")
{
ASSUME(gMovesInfo[MOVE_TORMENT].effect == EFFECT_TORMENT);
GIVEN {
ASSUME(gMovesInfo[MOVE_TORMENT].effect == EFFECT_TORMENT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_FAKE_OUT); }
OPPONENT(SPECIES_WOBBUFFET);
@ -136,9 +136,9 @@ DOUBLE_BATTLE_TEST("Instruct-called move doesn't fail if tormented")
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 {
ASSUME(gItemsInfo[ITEM_ASSAULT_VEST].holdEffect == HOLD_EFFECT_ASSAULT_VEST);
ASSUME(gMovesInfo[MOVE_TRICK].effect == EFFECT_TRICK);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_TRICK); }
OPPONENT(SPECIES_WOBBUFFET) { Item(ITEM_ASSAULT_VEST); }
@ -154,8 +154,8 @@ DOUBLE_BATTLE_TEST("Instruct-called status moves don't fail if holding Assault V
DOUBLE_BATTLE_TEST("Instruct-called status move fails if taunted")
{
ASSUME(gMovesInfo[MOVE_TAUNT].effect == EFFECT_TAUNT);
GIVEN {
ASSUME(gMovesInfo[MOVE_TAUNT].effect == EFFECT_TAUNT);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); }
OPPONENT(SPECIES_WOBBUFFET);
@ -180,8 +180,8 @@ DOUBLE_BATTLE_TEST("Instruct-called status move fails if taunted")
DOUBLE_BATTLE_TEST("Instruct-called moves fail if disabled")
{
ASSUME(gMovesInfo[MOVE_DISABLE].effect == EFFECT_DISABLE);
GIVEN {
ASSUME(gMovesInfo[MOVE_DISABLE].effect == EFFECT_DISABLE);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_GROWL); }
OPPONENT(SPECIES_WOBBUFFET);
@ -200,9 +200,9 @@ DOUBLE_BATTLE_TEST("Instruct-called moves fail if disabled")
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 {
ASSUME(gMovesInfo[MOVE_QUICK_ATTACK].priority == 1);
ASSUME(gMovesInfo[MOVE_PSYCHIC_TERRAIN].effect == EFFECT_PSYCHIC_TERRAIN);
PLAYER(SPECIES_WOBBUFFET);
PLAYER(SPECIES_WOBBUFFET) { Moves(MOVE_TACKLE, MOVE_POUND, MOVE_SCRATCH, MOVE_QUICK_ATTACK); }
OPPONENT(SPECIES_WOBBUFFET);

Some files were not shown because too many files have changed in this diff Show More