Arbitrary trainer scripts + map script/trigger softlock prevention (#5033)
Script_RunImmediatelyUntilEffect runs a script until either a specified effect may occur or it reaches an end. All existing script commands and natives, and some specials, call Script_RequestEffects which allows us to analyze them. Any downstream script commands/natives/specials will be statically known not to call Script_RequestEffects and treated as if they have all effects. Manually tagging them with requests_effects=1 and calling Script_RequestEffects will make them analyzable. Using these, we're able to execute scripts until they either exit with no effect, or would possibly have an effect. This allows us to: 1. Not run on frame map scripts or triggers if they would have no effect. 2. Immediately run triggers if they only affect flags/vars. This removes the lag frames when biking into the Cycling Road, for example. 3. Migrate on load/on transition/on resume/on return to field/on dive warp scripts onto the global script context if they would block (approximated via SCREFF_HARDWARE). 4. Support arbitrary control flow in trainer scripts. The trainer does not see the player if the script has no effect, and the trainer will use whichever trainerbattle command is branched to. 5. Support arbitrary scripts in trainer scripts. cant_see and cant_see_if_* commands have been introduced so that scripts are able to do something when the player interacts with the trainer even if that trainer wouldn't see them.
This commit is contained in:
parent
5391b451ae
commit
bb781f21a1
@ -251,15 +251,26 @@
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Calls the native C function stored at func.
|
@ Calls the native C function stored at func.
|
||||||
.macro callnative func:req
|
@ 'callnative's should set 'requests_effects=1' if the native
|
||||||
|
@ contains a call to 'Script_RequestEffects', which allows them
|
||||||
|
@ to be analyzed by 'RunScriptImmediatelyUntilEffect'.
|
||||||
|
.macro callnative func:req, requests_effects=0
|
||||||
.byte 0x23
|
.byte 0x23
|
||||||
|
.if \requests_effects == 0
|
||||||
.4byte \func
|
.4byte \func
|
||||||
|
.else
|
||||||
|
.4byte \func + ROM_SIZE
|
||||||
|
.endif
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Replaces the script with the function stored at func. Execution returns to the bytecode script when func returns TRUE.
|
@ Replaces the script with the function stored at func. Execution returns to the bytecode script when func returns TRUE.
|
||||||
.macro gotonative func:req
|
.macro gotonative func:req, requests_effects=0
|
||||||
.byte 0x24
|
.byte 0x24
|
||||||
|
.if \requests_effects == 0
|
||||||
.4byte \func
|
.4byte \func
|
||||||
|
.else
|
||||||
|
.4byte \func + ROM_SIZE
|
||||||
|
.endif
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Calls a function listed in the table in data/specials.inc.
|
@ Calls a function listed in the table in data/specials.inc.
|
||||||
@ -997,9 +1008,9 @@
|
|||||||
@ Gives the player a Pokémon of the specified species and level, and allows to customize extra parameters.
|
@ Gives the player a Pokémon of the specified species and level, and allows to customize extra parameters.
|
||||||
@ VAR_RESULT will be set to MON_GIVEN_TO_PARTY, MON_GIVEN_TO_PC, or MON_CANT_GIVE depending on the outcome.
|
@ VAR_RESULT will be set to MON_GIVEN_TO_PARTY, MON_GIVEN_TO_PC, or MON_CANT_GIVE depending on the outcome.
|
||||||
.macro givemon species:req, level:req, item, ball, nature, abilityNum, gender, hpEv, atkEv, defEv, speedEv, spAtkEv, spDefEv, hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv, move1, move2, move3, move4, isShiny, ggMaxFactor, teraType
|
.macro givemon species:req, level:req, item, ball, nature, abilityNum, gender, hpEv, atkEv, defEv, speedEv, spAtkEv, spDefEv, hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv, move1, move2, move3, move4, isShiny, ggMaxFactor, teraType
|
||||||
callnative ScrCmd_createmon
|
callnative ScrCmd_createmon, requests_effects=1
|
||||||
.byte 0
|
.byte 0
|
||||||
.byte 6 @ PARTY_SIZE - assign to first empty slot
|
.byte PARTY_SIZE @ assign to first empty slot
|
||||||
.set givemon_flags, 0
|
.set givemon_flags, 0
|
||||||
.2byte \species
|
.2byte \species
|
||||||
.2byte \level
|
.2byte \level
|
||||||
@ -1057,7 +1068,7 @@
|
|||||||
@ creates a mon for a given party and slot
|
@ creates a mon for a given party and slot
|
||||||
@ otherwise
|
@ otherwise
|
||||||
.macro createmon side:req, slot:req, species:req, level:req, item, ball, nature, abilityNum, gender, hpEv, atkEv, defEv, speedEv, spAtkEv, spDefEv, hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv, move1, move2, move3, move4, isShiny, ggMaxFactor, teraType
|
.macro createmon side:req, slot:req, species:req, level:req, item, ball, nature, abilityNum, gender, hpEv, atkEv, defEv, speedEv, spAtkEv, spDefEv, hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv, move1, move2, move3, move4, isShiny, ggMaxFactor, teraType
|
||||||
callnative ScrCmd_createmon
|
callnative ScrCmd_createmon, requests_effects=1
|
||||||
.byte \side @ 0 - player, 1 - opponent
|
.byte \side @ 0 - player, 1 - opponent
|
||||||
.byte \slot @ 0-5
|
.byte \slot @ 0-5
|
||||||
.set givemon_flags, 0
|
.set givemon_flags, 0
|
||||||
@ -2103,7 +2114,7 @@
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro setdynamicaifunc func:req
|
.macro setdynamicaifunc func:req
|
||||||
callnative ScriptSetDynamicAiFunc
|
callnative ScriptSetDynamicAiFunc, requests_effects=1
|
||||||
.4byte \func
|
.4byte \func
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ -2112,7 +2123,7 @@
|
|||||||
@ The rest of the arguments are the stat change values to each stat.
|
@ The rest of the arguments are the stat change values to each stat.
|
||||||
@ For example, giving the first opponent +1 to atk and -2 to speed would be: settotemboost B_POSITION_OPPONENT_LEFT, 1, 0, -2
|
@ For example, giving the first opponent +1 to atk and -2 to speed would be: settotemboost B_POSITION_OPPONENT_LEFT, 1, 0, -2
|
||||||
.macro settotemboost battler:req, atk=0,def=0,speed=0,spatk=0,spdef=0,acc=0,evas=0
|
.macro settotemboost battler:req, atk=0,def=0,speed=0,spatk=0,spdef=0,acc=0,evas=0
|
||||||
callnative ScriptSetTotemBoost
|
callnative ScriptSetTotemBoost, requests_effects=1
|
||||||
.2byte \battler
|
.2byte \battler
|
||||||
.2byte \atk
|
.2byte \atk
|
||||||
.2byte \def
|
.2byte \def
|
||||||
@ -2183,21 +2194,21 @@
|
|||||||
.macro ai_vs_ai_battle trainer1:req, trainer2:req
|
.macro ai_vs_ai_battle trainer1:req, trainer2:req
|
||||||
setflag B_FLAG_AI_VS_AI_BATTLE
|
setflag B_FLAG_AI_VS_AI_BATTLE
|
||||||
setvar VAR_0x8004, \trainer1
|
setvar VAR_0x8004, \trainer1
|
||||||
callnative CreateTrainerPartyForPlayer
|
callnative CreateTrainerPartyForPlayer, requests_effects=1
|
||||||
trainerbattle_no_intro \trainer2, NULL
|
trainerbattle_no_intro \trainer2, NULL
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Sets VAR_RESULT to TRUE if stat can be hyper trained, or to
|
@ Sets VAR_RESULT to TRUE if stat can be hyper trained, or to
|
||||||
@ FALSE otherwise.
|
@ FALSE otherwise.
|
||||||
.macro canhypertrain stat:req, slot:req
|
.macro canhypertrain stat:req, slot:req
|
||||||
callnative CanHyperTrain
|
callnative CanHyperTrain, requests_effects=1
|
||||||
.byte \stat
|
.byte \stat
|
||||||
.2byte \slot
|
.2byte \slot
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Hyper Trains a stat.
|
@ Hyper Trains a stat.
|
||||||
.macro hypertrain stat:req, slot:req
|
.macro hypertrain stat:req, slot:req
|
||||||
callnative HyperTrain
|
callnative HyperTrain, requests_effects=1
|
||||||
.byte \stat
|
.byte \stat
|
||||||
.2byte \slot
|
.2byte \slot
|
||||||
.endm
|
.endm
|
||||||
@ -2205,7 +2216,7 @@
|
|||||||
@ Sets VAR_RESULT to TRUE if the Pokemon has the Gigantamax Factor,
|
@ Sets VAR_RESULT to TRUE if the Pokemon has the Gigantamax Factor,
|
||||||
@ or to FALSE otherwise.
|
@ or to FALSE otherwise.
|
||||||
.macro hasgigantamaxfactor slot:req
|
.macro hasgigantamaxfactor slot:req
|
||||||
callnative HasGigantamaxFactor
|
callnative HasGigantamaxFactor, requests_effects=1
|
||||||
.2byte \slot
|
.2byte \slot
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ -2213,7 +2224,7 @@
|
|||||||
@ Fails for Melmetal (vanilla behavior).
|
@ Fails for Melmetal (vanilla behavior).
|
||||||
@ Sets VAR_RESULT to TRUE if it succeeds, and FALSE otherwise.
|
@ Sets VAR_RESULT to TRUE if it succeeds, and FALSE otherwise.
|
||||||
.macro togglegigantamaxfactor slot:req
|
.macro togglegigantamaxfactor slot:req
|
||||||
callnative ToggleGigantamaxFactor
|
callnative ToggleGigantamaxFactor, requests_effects=1
|
||||||
.2byte \slot
|
.2byte \slot
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ -2251,27 +2262,27 @@
|
|||||||
@ Inflicts \status1 to the Pokémon in \slot.
|
@ Inflicts \status1 to the Pokémon in \slot.
|
||||||
@ If \slot is greater or equal than PARTY_SIZE, the status is inflicted on each of the Player's Pokémon.
|
@ If \slot is greater or equal than PARTY_SIZE, the status is inflicted on each of the Player's Pokémon.
|
||||||
.macro setstatus1 status1:req, slot:req
|
.macro setstatus1 status1:req, slot:req
|
||||||
callnative Script_SetStatus1
|
callnative Script_SetStatus1, requests_effects=1
|
||||||
.2byte \status1
|
.2byte \status1
|
||||||
.2byte \slot
|
.2byte \slot
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Sets VAR_RESULT to the Pokémon in \slot's Tera Type
|
@ Sets VAR_RESULT to the Pokémon in \slot's Tera Type
|
||||||
.macro checkteratype slot:req
|
.macro checkteratype slot:req
|
||||||
callnative CheckTeraType
|
callnative CheckTeraType, requests_effects=1
|
||||||
.2byte \slot
|
.2byte \slot
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Sets the Pokémon in \slot's Tera Type
|
@ Sets the Pokémon in \slot's Tera Type
|
||||||
.macro setteratype type:req, slot:req
|
.macro setteratype type:req, slot:req
|
||||||
callnative SetTeraType
|
callnative SetTeraType, requests_effects=1
|
||||||
.byte \type
|
.byte \type
|
||||||
.2byte \slot
|
.2byte \slot
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Saves species and forms of Daycare Pokémon to specific vars. Saves the amount of Daycare mon to VAR_RESULT.
|
@ Saves species and forms of Daycare Pokémon to specific vars. Saves the amount of Daycare mon to VAR_RESULT.
|
||||||
.macro getdaycaregfx varSpecies1:req varSpecies2:req varForm1:req varForm2:req
|
.macro getdaycaregfx varSpecies1:req varSpecies2:req varForm1:req varForm2:req
|
||||||
callnative GetDaycareGraphics
|
callnative GetDaycareGraphics, requests_effects=1
|
||||||
.2byte \varSpecies1
|
.2byte \varSpecies1
|
||||||
.2byte \varSpecies2
|
.2byte \varSpecies2
|
||||||
.2byte \varForm1
|
.2byte \varForm1
|
||||||
@ -2280,12 +2291,12 @@
|
|||||||
|
|
||||||
@ Plays the cry of the first alive party member.
|
@ Plays the cry of the first alive party member.
|
||||||
.macro playfirstmoncry
|
.macro playfirstmoncry
|
||||||
callnative PlayFirstMonCry
|
callnative PlayFirstMonCry, requests_effects=1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Buffers the nickname of the first alive party member.
|
@ Buffers the nickname of the first alive party member.
|
||||||
.macro bufferlivemonnickname out:req
|
.macro bufferlivemonnickname out:req
|
||||||
callnative BufferFirstLiveMonNickname
|
callnative BufferFirstLiveMonNickname, requests_effects=1
|
||||||
.byte \out
|
.byte \out
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ -2296,13 +2307,13 @@
|
|||||||
|
|
||||||
@ Checks if Field move is being used by the current follower.
|
@ Checks if Field move is being used by the current follower.
|
||||||
.macro isfollowerfieldmoveuser var:req
|
.macro isfollowerfieldmoveuser var:req
|
||||||
callnative IsFollowerFieldMoveUser
|
callnative IsFollowerFieldMoveUser, requests_effects=1
|
||||||
.2byte \var
|
.2byte \var
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Saves the direction from where source object event would need to turn to to face the target into the specified var.
|
@ Saves the direction from where source object event would need to turn to to face the target into the specified var.
|
||||||
.macro getdirectiontoface var:req, sourceId:req, targetId:req
|
.macro getdirectiontoface var:req, sourceId:req, targetId:req
|
||||||
callnative GetDirectionToFaceScript
|
callnative GetDirectionToFaceScript, requests_effects=1
|
||||||
.2byte \var
|
.2byte \var
|
||||||
.byte \sourceId
|
.byte \sourceId
|
||||||
.byte \targetId
|
.byte \targetId
|
||||||
@ -2311,50 +2322,50 @@
|
|||||||
@ set the wild double battle flag
|
@ set the wild double battle flag
|
||||||
@ can be used in conjunection with createmon to set up a wild battle with 2 player mons vs. 1 enemy mon
|
@ can be used in conjunection with createmon to set up a wild battle with 2 player mons vs. 1 enemy mon
|
||||||
.macro setwilddoubleflag
|
.macro setwilddoubleflag
|
||||||
callnative ScriptSetDoubleBattleFlag
|
callnative ScriptSetDoubleBattleFlag, requests_effects=1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ When OW_USE_FAKE_RTC and OW_FLAG_PAUSE_TIME is assigned, this macro will stop the flow of time.
|
@ When OW_USE_FAKE_RTC and OW_FLAG_PAUSE_TIME is assigned, this macro will stop the flow of time.
|
||||||
.macro pausefakertc
|
.macro pausefakertc
|
||||||
callnative Script_PauseFakeRtc
|
callnative Script_PauseFakeRtc, requests_effects=1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ When OW_USE_FAKE_RTC and OW_FLAG_PAUSE_TIME is assigned, this macro will resume the flow of time.
|
@ When OW_USE_FAKE_RTC and OW_FLAG_PAUSE_TIME is assigned, this macro will resume the flow of time.
|
||||||
.macro resumefakertc
|
.macro resumefakertc
|
||||||
callnative Script_ResumeFakeRtc
|
callnative Script_ResumeFakeRtc, requests_effects=1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ When OW_USE_FAKE_RTC and OW_FLAG_PAUSE_TIME is assigned, this macro will resume the flow of time if paused, and stop the flow of time otherwise.
|
@ When OW_USE_FAKE_RTC and OW_FLAG_PAUSE_TIME is assigned, this macro will resume the flow of time if paused, and stop the flow of time otherwise.
|
||||||
.macro togglefakertc
|
.macro togglefakertc
|
||||||
callnative Script_ToggleFakeRtc
|
callnative Script_ToggleFakeRtc, requests_effects=1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ ============================ @
|
@ ============================ @
|
||||||
@ ITEM DESCRIPTION HEADER MACROS
|
@ ITEM DESCRIPTION HEADER MACROS
|
||||||
@ Used with OW_SHOW_ITEM_DESCRIPTIONS config
|
@ Used with OW_SHOW_ITEM_DESCRIPTIONS config
|
||||||
.macro showitemdescription
|
.macro showitemdescription
|
||||||
callnative ScriptShowItemDescription
|
callnative ScriptShowItemDescription, requests_effects=1
|
||||||
.byte 0
|
.byte 0
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro showberrydescription
|
.macro showberrydescription
|
||||||
callnative ScriptShowItemDescription
|
callnative ScriptShowItemDescription, requests_effects=1
|
||||||
.byte 1
|
.byte 1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro hideitemdescription
|
.macro hideitemdescription
|
||||||
callnative ScriptHideItemDescription
|
callnative ScriptHideItemDescription, requests_effects=1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Remove all of specified item from the player's bag and return the number of removed items to VAR_RESULT
|
@ Remove all of specified item from the player's bag and return the number of removed items to VAR_RESULT
|
||||||
.macro removeallitem itemId:req
|
.macro removeallitem itemId:req
|
||||||
callnative ScrCmd_removeallitem
|
callnative ScrCmd_removeallitem, requests_effects=1
|
||||||
.2byte \itemId
|
.2byte \itemId
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Stores the position of the given object in destX and destY. Mode CURRENT_POSITION will take the object's current position. Mode TEMPLATE_POSITION will take the object's template position.
|
@ Stores the position of the given object in destX and destY. Mode CURRENT_POSITION will take the object's current position. Mode TEMPLATE_POSITION will take the object's template position.
|
||||||
.macro getobjectxy localId:req, posType:req, destX:req, destY:req
|
.macro getobjectxy localId:req, posType:req, destX:req, destY:req
|
||||||
callnative ScrCmd_getobjectxy
|
callnative ScrCmd_getobjectxy, request_effects=1
|
||||||
.2byte \localId
|
.2byte \localId
|
||||||
.2byte \posType
|
.2byte \posType
|
||||||
.2byte \destX
|
.2byte \destX
|
||||||
@ -2362,7 +2373,7 @@
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro getobjecttemplatexy localId:req, posType = TEMPLATE_POSITION, destX:req, destY:req
|
.macro getobjecttemplatexy localId:req, posType = TEMPLATE_POSITION, destX:req, destY:req
|
||||||
callnative ScrCmd_getobjectxy
|
callnative ScrCmd_getobjectxy, request_effects=1
|
||||||
.2byte \localId
|
.2byte \localId
|
||||||
.2byte \posType
|
.2byte \posType
|
||||||
.2byte \destX
|
.2byte \destX
|
||||||
@ -2370,7 +2381,7 @@
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro getobjectcurrentxy localId:req, posType = CURRENT_POSITION, destX:req, destY:req
|
.macro getobjectcurrentxy localId:req, posType = CURRENT_POSITION, destX:req, destY:req
|
||||||
callnative ScrCmd_getobjectxy
|
callnative ScrCmd_getobjectxy, request_effects=1
|
||||||
.2byte \localId
|
.2byte \localId
|
||||||
.2byte \posType
|
.2byte \posType
|
||||||
.2byte \destX
|
.2byte \destX
|
||||||
@ -2379,7 +2390,7 @@
|
|||||||
|
|
||||||
@ Return TRUE to dest if there is an object at the position x and y.
|
@ Return TRUE to dest if there is an object at the position x and y.
|
||||||
.macro checkobjectat x:req, y:req, dest = VAR_RESULT
|
.macro checkobjectat x:req, y:req, dest = VAR_RESULT
|
||||||
callnative ScrCmd_checkobjectat
|
callnative ScrCmd_checkobjectat, request_effects=1
|
||||||
.2byte \x
|
.2byte \x
|
||||||
.2byte \y
|
.2byte \y
|
||||||
.2byte \dest
|
.2byte \dest
|
||||||
@ -2387,28 +2398,28 @@
|
|||||||
|
|
||||||
@ Returns the state of the Pokedex Seen Flag to VAR_RESULT for the Pokemon with speciesId
|
@ Returns the state of the Pokedex Seen Flag to VAR_RESULT for the Pokemon with speciesId
|
||||||
.macro getseenmon species:req
|
.macro getseenmon species:req
|
||||||
callnative Scrcmd_getsetpokedexflag
|
callnative Scrcmd_getsetpokedexflag, request_effects=1
|
||||||
.2byte \species
|
.2byte \species
|
||||||
.2byte FLAG_GET_SEEN
|
.2byte FLAG_GET_SEEN
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Returns the state of the Pokedex Caught Flag to VAR_RESULT for the Pokemon with speciesId
|
@ Returns the state of the Pokedex Caught Flag to VAR_RESULT for the Pokemon with speciesId
|
||||||
.macro getcaughtmon species:req
|
.macro getcaughtmon species:req
|
||||||
callnative Scrcmd_getsetpokedexflag
|
callnative Scrcmd_getsetpokedexflag, request_effects=1
|
||||||
.2byte \species
|
.2byte \species
|
||||||
.2byte FLAG_GET_CAUGHT
|
.2byte FLAG_GET_CAUGHT
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Sets the Pokedex Seen Flag for the Pokemon with speciesId
|
@ Sets the Pokedex Seen Flag for the Pokemon with speciesId
|
||||||
.macro setseenmon species:req
|
.macro setseenmon species:req
|
||||||
callnative Scrcmd_getsetpokedexflag
|
callnative Scrcmd_getsetpokedexflag, request_effects=1
|
||||||
.2byte \species
|
.2byte \species
|
||||||
.2byte FLAG_SET_SEEN
|
.2byte FLAG_SET_SEEN
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ Sets the Pokedex Caught Flag for the Pokemon with speciesId
|
@ Sets the Pokedex Caught Flag for the Pokemon with speciesId
|
||||||
.macro setcaughtmon species:req
|
.macro setcaughtmon species:req
|
||||||
callnative Scrcmd_getsetpokedexflag
|
callnative Scrcmd_getsetpokedexflag, request_effects=1
|
||||||
.2byte \species
|
.2byte \species
|
||||||
.2byte FLAG_SET_CAUGHT
|
.2byte FLAG_SET_CAUGHT
|
||||||
.endm
|
.endm
|
||||||
@ -2418,10 +2429,10 @@
|
|||||||
.if \mode == OPEN_PARTY_SCREEN
|
.if \mode == OPEN_PARTY_SCREEN
|
||||||
special ChoosePartyMon
|
special ChoosePartyMon
|
||||||
waitstate
|
waitstate
|
||||||
callnative Scrcmd_checkspecies_choose
|
callnative Scrcmd_checkspecies_choose, request_effects=1
|
||||||
.2byte \speciesId
|
.2byte \speciesId
|
||||||
.else
|
.else
|
||||||
callnative Scrcmd_checkspecies
|
callnative Scrcmd_checkspecies, request_effects=1
|
||||||
.2byte \speciesId
|
.2byte \speciesId
|
||||||
.endif
|
.endif
|
||||||
.endm
|
.endm
|
||||||
@ -2432,24 +2443,85 @@
|
|||||||
|
|
||||||
@ Gets the facing direction of a given event object and stores it in the variable dest.
|
@ Gets the facing direction of a given event object and stores it in the variable dest.
|
||||||
.macro getobjectfacingdirection localId:req, dest:req
|
.macro getobjectfacingdirection localId:req, dest:req
|
||||||
callnative Scrcmd_getobjectfacingdirection
|
callnative Scrcmd_getobjectfacingdirection, request_effects=1
|
||||||
.2byte \localId
|
.2byte \localId
|
||||||
.2byte \dest
|
.2byte \dest
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro increasedifficulty
|
.macro increasedifficulty
|
||||||
callnative Script_IncreaseDifficulty
|
callnative Script_IncreaseDifficulty, requests_effects=1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro decreasedifficulty
|
.macro decreasedifficulty
|
||||||
callnative Script_DecreaseDifficulty
|
callnative Script_DecreaseDifficulty, requests_effects=1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro getdifficulty var:req
|
.macro getdifficulty var:req
|
||||||
callnative Script_GetDifficulty
|
callnative Script_GetDifficulty, requests_effects=1
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro setdifficulty difficulty:req
|
.macro setdifficulty difficulty:req
|
||||||
callnative Script_SetDifficulty
|
callnative Script_SetDifficulty, requests_effects=1
|
||||||
.byte \difficulty
|
.byte \difficulty
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
|
@ Makes the trainer unable to see the player if executed.
|
||||||
|
@ This is a no-op if the player interacts with the trainer.
|
||||||
|
.macro cant_see_if, condition:req
|
||||||
|
callnative Script_EndTrainerCanSeeIf, requests_effects=1
|
||||||
|
.byte \condition
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro cant_see
|
||||||
|
cant_see_if_unset 0 @ flag 0 is always FALSE.
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro cant_see_if_unset, flag:req
|
||||||
|
checkflag \flag
|
||||||
|
cant_see_if FALSE
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro cant_see_if_set, flag:req
|
||||||
|
checkflag \flag
|
||||||
|
cant_see_if TRUE
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro cant_see_if_trainerflag_unset, trainer:req
|
||||||
|
checktrainerflag \trainer
|
||||||
|
cant_see_if FALSE
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro cant_see_if_trainerflag_set, trainer:req
|
||||||
|
checktrainerflag \trainer
|
||||||
|
cant_see_if TRUE
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro cant_see_if_lt, a:req, b:req
|
||||||
|
compare \a, \b
|
||||||
|
cant_see_if 0
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro cant_see_if_eq, a:req, b:req
|
||||||
|
compare \a, \b
|
||||||
|
cant_see_if 1
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro cant_see_if_gt, a:req, b:req
|
||||||
|
compare \a, \b
|
||||||
|
cant_see_if 2
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro cant_see_if_le, a:req, b:req
|
||||||
|
compare \a, \b
|
||||||
|
cant_see_if 3
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro cant_see_if_ge, a:req, b:req
|
||||||
|
compare \a, \b
|
||||||
|
cant_see_if 4
|
||||||
|
.endm
|
||||||
|
|
||||||
|
.macro cant_see_if_ne, a:req, b:req
|
||||||
|
compare \a, \b
|
||||||
|
cant_see_if 5
|
||||||
|
.endm
|
||||||
|
|||||||
@ -29,6 +29,9 @@
|
|||||||
|
|
||||||
.set OAM, 0x7000000
|
.set OAM, 0x7000000
|
||||||
|
|
||||||
|
.set ROM, 0x8000000
|
||||||
|
.set ROM_SIZE, 0x2000000
|
||||||
|
|
||||||
.set SOUND_INFO_PTR, 0x3007FF0
|
.set SOUND_INFO_PTR, 0x3007FF0
|
||||||
.set INTR_CHECK, 0x3007FF8
|
.set INTR_CHECK, 0x3007FF8
|
||||||
.set INTR_VECTOR, 0x3007FFC
|
.set INTR_VECTOR, 0x3007FFC
|
||||||
|
|||||||
@ -11,6 +11,7 @@ Route110_MapScripts::
|
|||||||
|
|
||||||
Route110_OnResume:
|
Route110_OnResume:
|
||||||
special UpdateCyclingRoadState
|
special UpdateCyclingRoadState
|
||||||
|
msgbox Route110_Text_WeCantTalkAboutAquaActivities, MSGBOX_SIGN
|
||||||
end
|
end
|
||||||
|
|
||||||
Route110_OnTransition:
|
Route110_OnTransition:
|
||||||
|
|||||||
@ -1,234 +1,245 @@
|
|||||||
|
@ 'requests_effects' should be set to 1 if the command contains a call
|
||||||
|
@ to 'Script_RequestEffects', which allows it to be analyzed with
|
||||||
|
@ 'RunScriptImmediatelyUntilEffect'.
|
||||||
|
.macro cmd func:req, requests_effects=0
|
||||||
|
.if \requests_effects == 0
|
||||||
|
.4byte \func
|
||||||
|
.else
|
||||||
|
.4byte \func + ROM_SIZE
|
||||||
|
.endif
|
||||||
|
.endm
|
||||||
|
|
||||||
.align 2
|
.align 2
|
||||||
gScriptCmdTable::
|
gScriptCmdTable::
|
||||||
.4byte ScrCmd_nop @ 0x00
|
cmd ScrCmd_nop, requests_effects=1 @ 0x00
|
||||||
.4byte ScrCmd_nop1 @ 0x01
|
cmd ScrCmd_nop1, requests_effects=1 @ 0x01
|
||||||
.4byte ScrCmd_end @ 0x02
|
cmd ScrCmd_end, requests_effects=1 @ 0x02
|
||||||
.4byte ScrCmd_return @ 0x03
|
cmd ScrCmd_return, requests_effects=1 @ 0x03
|
||||||
.4byte ScrCmd_call @ 0x04
|
cmd ScrCmd_call, requests_effects=1 @ 0x04
|
||||||
.4byte ScrCmd_goto @ 0x05
|
cmd ScrCmd_goto, requests_effects=1 @ 0x05
|
||||||
.4byte ScrCmd_goto_if @ 0x06
|
cmd ScrCmd_goto_if, requests_effects=1 @ 0x06
|
||||||
.4byte ScrCmd_call_if @ 0x07
|
cmd ScrCmd_call_if, requests_effects=1 @ 0x07
|
||||||
.4byte ScrCmd_gotostd @ 0x08
|
cmd ScrCmd_gotostd, requests_effects=1 @ 0x08
|
||||||
.4byte ScrCmd_callstd @ 0x09
|
cmd ScrCmd_callstd, requests_effects=1 @ 0x09
|
||||||
.4byte ScrCmd_gotostd_if @ 0x0a
|
cmd ScrCmd_gotostd_if, requests_effects=1 @ 0x0a
|
||||||
.4byte ScrCmd_callstd_if @ 0x0b
|
cmd ScrCmd_callstd_if, requests_effects=1 @ 0x0b
|
||||||
.4byte ScrCmd_returnram @ 0x0c
|
cmd ScrCmd_returnram, requests_effects=1 @ 0x0c
|
||||||
.4byte ScrCmd_endram @ 0x0d
|
cmd ScrCmd_endram, requests_effects=1 @ 0x0d
|
||||||
.4byte ScrCmd_setmysteryeventstatus @ 0x0e
|
cmd ScrCmd_setmysteryeventstatus, requests_effects=1 @ 0x0e
|
||||||
.4byte ScrCmd_loadword @ 0x0f
|
cmd ScrCmd_loadword, requests_effects=1 @ 0x0f
|
||||||
.4byte ScrCmd_loadbyte @ 0x10
|
cmd ScrCmd_loadbyte, requests_effects=1 @ 0x10
|
||||||
.4byte ScrCmd_setptr @ 0x11
|
cmd ScrCmd_setptr, requests_effects=1 @ 0x11
|
||||||
.4byte ScrCmd_loadbytefromptr @ 0x12
|
cmd ScrCmd_loadbytefromptr, requests_effects=1 @ 0x12
|
||||||
.4byte ScrCmd_setptrbyte @ 0x13
|
cmd ScrCmd_setptrbyte, requests_effects=1 @ 0x13
|
||||||
.4byte ScrCmd_copylocal @ 0x14
|
cmd ScrCmd_copylocal, requests_effects=1 @ 0x14
|
||||||
.4byte ScrCmd_copybyte @ 0x15
|
cmd ScrCmd_copybyte, requests_effects=1 @ 0x15
|
||||||
.4byte ScrCmd_setvar @ 0x16
|
cmd ScrCmd_setvar, requests_effects=1 @ 0x16
|
||||||
.4byte ScrCmd_addvar @ 0x17
|
cmd ScrCmd_addvar, requests_effects=1 @ 0x17
|
||||||
.4byte ScrCmd_subvar @ 0x18
|
cmd ScrCmd_subvar, requests_effects=1 @ 0x18
|
||||||
.4byte ScrCmd_copyvar @ 0x19
|
cmd ScrCmd_copyvar, requests_effects=1 @ 0x19
|
||||||
.4byte ScrCmd_setorcopyvar @ 0x1a
|
cmd ScrCmd_setorcopyvar, requests_effects=1 @ 0x1a
|
||||||
.4byte ScrCmd_compare_local_to_local @ 0x1b
|
cmd ScrCmd_compare_local_to_local, requests_effects=1 @ 0x1b
|
||||||
.4byte ScrCmd_compare_local_to_value @ 0x1c
|
cmd ScrCmd_compare_local_to_value, requests_effects=1 @ 0x1c
|
||||||
.4byte ScrCmd_compare_local_to_ptr @ 0x1d
|
cmd ScrCmd_compare_local_to_ptr, requests_effects=1 @ 0x1d
|
||||||
.4byte ScrCmd_compare_ptr_to_local @ 0x1e
|
cmd ScrCmd_compare_ptr_to_local, requests_effects=1 @ 0x1e
|
||||||
.4byte ScrCmd_compare_ptr_to_value @ 0x1f
|
cmd ScrCmd_compare_ptr_to_value, requests_effects=1 @ 0x1f
|
||||||
.4byte ScrCmd_compare_ptr_to_ptr @ 0x20
|
cmd ScrCmd_compare_ptr_to_ptr, requests_effects=1 @ 0x20
|
||||||
.4byte ScrCmd_compare_var_to_value @ 0x21
|
cmd ScrCmd_compare_var_to_value, requests_effects=1 @ 0x21
|
||||||
.4byte ScrCmd_compare_var_to_var @ 0x22
|
cmd ScrCmd_compare_var_to_var, requests_effects=1 @ 0x22
|
||||||
.4byte ScrCmd_callnative @ 0x23
|
cmd ScrCmd_callnative, requests_effects=1 @ 0x23
|
||||||
.4byte ScrCmd_gotonative @ 0x24
|
cmd ScrCmd_gotonative, requests_effects=1 @ 0x24
|
||||||
.4byte ScrCmd_special @ 0x25
|
cmd ScrCmd_special, requests_effects=1 @ 0x25
|
||||||
.4byte ScrCmd_specialvar @ 0x26
|
cmd ScrCmd_specialvar, requests_effects=1 @ 0x26
|
||||||
.4byte ScrCmd_waitstate @ 0x27
|
cmd ScrCmd_waitstate, requests_effects=1 @ 0x27
|
||||||
.4byte ScrCmd_delay @ 0x28
|
cmd ScrCmd_delay, requests_effects=1 @ 0x28
|
||||||
.4byte ScrCmd_setflag @ 0x29
|
cmd ScrCmd_setflag, requests_effects=1 @ 0x29
|
||||||
.4byte ScrCmd_clearflag @ 0x2a
|
cmd ScrCmd_clearflag, requests_effects=1 @ 0x2a
|
||||||
.4byte ScrCmd_checkflag @ 0x2b
|
cmd ScrCmd_checkflag, requests_effects=1 @ 0x2b
|
||||||
.4byte ScrCmd_initclock @ 0x2c
|
cmd ScrCmd_initclock, requests_effects=1 @ 0x2c
|
||||||
.4byte ScrCmd_dotimebasedevents @ 0x2d
|
cmd ScrCmd_dotimebasedevents, requests_effects=1 @ 0x2d
|
||||||
.4byte ScrCmd_gettime @ 0x2e
|
cmd ScrCmd_gettime, requests_effects=1 @ 0x2e
|
||||||
.4byte ScrCmd_playse @ 0x2f
|
cmd ScrCmd_playse, requests_effects=1 @ 0x2f
|
||||||
.4byte ScrCmd_waitse @ 0x30
|
cmd ScrCmd_waitse, requests_effects=1 @ 0x30
|
||||||
.4byte ScrCmd_playfanfare @ 0x31
|
cmd ScrCmd_playfanfare, requests_effects=1 @ 0x31
|
||||||
.4byte ScrCmd_waitfanfare @ 0x32
|
cmd ScrCmd_waitfanfare, requests_effects=1 @ 0x32
|
||||||
.4byte ScrCmd_playbgm @ 0x33
|
cmd ScrCmd_playbgm, requests_effects=1 @ 0x33
|
||||||
.4byte ScrCmd_savebgm @ 0x34
|
cmd ScrCmd_savebgm, requests_effects=1 @ 0x34
|
||||||
.4byte ScrCmd_fadedefaultbgm @ 0x35
|
cmd ScrCmd_fadedefaultbgm, requests_effects=1 @ 0x35
|
||||||
.4byte ScrCmd_fadenewbgm @ 0x36
|
cmd ScrCmd_fadenewbgm, requests_effects=1 @ 0x36
|
||||||
.4byte ScrCmd_fadeoutbgm @ 0x37
|
cmd ScrCmd_fadeoutbgm, requests_effects=1 @ 0x37
|
||||||
.4byte ScrCmd_fadeinbgm @ 0x38
|
cmd ScrCmd_fadeinbgm, requests_effects=1 @ 0x38
|
||||||
.4byte ScrCmd_warp @ 0x39
|
cmd ScrCmd_warp, requests_effects=1 @ 0x39
|
||||||
.4byte ScrCmd_warpsilent @ 0x3a
|
cmd ScrCmd_warpsilent, requests_effects=1 @ 0x3a
|
||||||
.4byte ScrCmd_warpdoor @ 0x3b
|
cmd ScrCmd_warpdoor, requests_effects=1 @ 0x3b
|
||||||
.4byte ScrCmd_warphole @ 0x3c
|
cmd ScrCmd_warphole, requests_effects=1 @ 0x3c
|
||||||
.4byte ScrCmd_warpteleport @ 0x3d
|
cmd ScrCmd_warpteleport, requests_effects=1 @ 0x3d
|
||||||
.4byte ScrCmd_setwarp @ 0x3e
|
cmd ScrCmd_setwarp, requests_effects=1 @ 0x3e
|
||||||
.4byte ScrCmd_setdynamicwarp @ 0x3f
|
cmd ScrCmd_setdynamicwarp, requests_effects=1 @ 0x3f
|
||||||
.4byte ScrCmd_setdivewarp @ 0x40
|
cmd ScrCmd_setdivewarp, requests_effects=1 @ 0x40
|
||||||
.4byte ScrCmd_setholewarp @ 0x41
|
cmd ScrCmd_setholewarp, requests_effects=1 @ 0x41
|
||||||
.4byte ScrCmd_getplayerxy @ 0x42
|
cmd ScrCmd_getplayerxy, requests_effects=1 @ 0x42
|
||||||
.4byte ScrCmd_getpartysize @ 0x43
|
cmd ScrCmd_getpartysize, requests_effects=1 @ 0x43
|
||||||
.4byte ScrCmd_additem @ 0x44
|
cmd ScrCmd_additem, requests_effects=1 @ 0x44
|
||||||
.4byte ScrCmd_removeitem @ 0x45
|
cmd ScrCmd_removeitem, requests_effects=1 @ 0x45
|
||||||
.4byte ScrCmd_checkitemspace @ 0x46
|
cmd ScrCmd_checkitemspace, requests_effects=1 @ 0x46
|
||||||
.4byte ScrCmd_checkitem @ 0x47
|
cmd ScrCmd_checkitem, requests_effects=1 @ 0x47
|
||||||
.4byte ScrCmd_checkitemtype @ 0x48
|
cmd ScrCmd_checkitemtype, requests_effects=1 @ 0x48
|
||||||
.4byte ScrCmd_addpcitem @ 0x49
|
cmd ScrCmd_addpcitem, requests_effects=1 @ 0x49
|
||||||
.4byte ScrCmd_checkpcitem @ 0x4a
|
cmd ScrCmd_checkpcitem, requests_effects=1 @ 0x4a
|
||||||
.4byte ScrCmd_adddecoration @ 0x4b
|
cmd ScrCmd_adddecoration, requests_effects=1 @ 0x4b
|
||||||
.4byte ScrCmd_removedecoration @ 0x4c
|
cmd ScrCmd_removedecoration, requests_effects=1 @ 0x4c
|
||||||
.4byte ScrCmd_checkdecor @ 0x4d
|
cmd ScrCmd_checkdecor, requests_effects=1 @ 0x4d
|
||||||
.4byte ScrCmd_checkdecorspace @ 0x4e
|
cmd ScrCmd_checkdecorspace, requests_effects=1 @ 0x4e
|
||||||
.4byte ScrCmd_applymovement @ 0x4f
|
cmd ScrCmd_applymovement, requests_effects=1 @ 0x4f
|
||||||
.4byte ScrCmd_applymovementat @ 0x50
|
cmd ScrCmd_applymovementat, requests_effects=1 @ 0x50
|
||||||
.4byte ScrCmd_waitmovement @ 0x51
|
cmd ScrCmd_waitmovement, requests_effects=1 @ 0x51
|
||||||
.4byte ScrCmd_waitmovementat @ 0x52
|
cmd ScrCmd_waitmovementat, requests_effects=1 @ 0x52
|
||||||
.4byte ScrCmd_removeobject @ 0x53
|
cmd ScrCmd_removeobject, requests_effects=1 @ 0x53
|
||||||
.4byte ScrCmd_removeobjectat @ 0x54
|
cmd ScrCmd_removeobjectat, requests_effects=1 @ 0x54
|
||||||
.4byte ScrCmd_addobject @ 0x55
|
cmd ScrCmd_addobject, requests_effects=1 @ 0x55
|
||||||
.4byte ScrCmd_addobjectat @ 0x56
|
cmd ScrCmd_addobjectat, requests_effects=1 @ 0x56
|
||||||
.4byte ScrCmd_setobjectxy @ 0x57
|
cmd ScrCmd_setobjectxy, requests_effects=1 @ 0x57
|
||||||
.4byte ScrCmd_showobjectat @ 0x58
|
cmd ScrCmd_showobjectat, requests_effects=1 @ 0x58
|
||||||
.4byte ScrCmd_hideobjectat @ 0x59
|
cmd ScrCmd_hideobjectat, requests_effects=1 @ 0x59
|
||||||
.4byte ScrCmd_faceplayer @ 0x5a
|
cmd ScrCmd_faceplayer, requests_effects=1 @ 0x5a
|
||||||
.4byte ScrCmd_turnobject @ 0x5b
|
cmd ScrCmd_turnobject, requests_effects=1 @ 0x5b
|
||||||
.4byte ScrCmd_trainerbattle @ 0x5c
|
cmd ScrCmd_trainerbattle, requests_effects=1 @ 0x5c
|
||||||
.4byte ScrCmd_dotrainerbattle @ 0x5d
|
cmd ScrCmd_dotrainerbattle, requests_effects=1 @ 0x5d
|
||||||
.4byte ScrCmd_gotopostbattlescript @ 0x5e
|
cmd ScrCmd_gotopostbattlescript, requests_effects=1 @ 0x5e
|
||||||
.4byte ScrCmd_gotobeatenscript @ 0x5f
|
cmd ScrCmd_gotobeatenscript, requests_effects=1 @ 0x5f
|
||||||
.4byte ScrCmd_checktrainerflag @ 0x60
|
cmd ScrCmd_checktrainerflag, requests_effects=1 @ 0x60
|
||||||
.4byte ScrCmd_settrainerflag @ 0x61
|
cmd ScrCmd_settrainerflag, requests_effects=1 @ 0x61
|
||||||
.4byte ScrCmd_cleartrainerflag @ 0x62
|
cmd ScrCmd_cleartrainerflag, requests_effects=1 @ 0x62
|
||||||
.4byte ScrCmd_setobjectxyperm @ 0x63
|
cmd ScrCmd_setobjectxyperm, requests_effects=1 @ 0x63
|
||||||
.4byte ScrCmd_copyobjectxytoperm @ 0x64
|
cmd ScrCmd_copyobjectxytoperm, requests_effects=1 @ 0x64
|
||||||
.4byte ScrCmd_setobjectmovementtype @ 0x65
|
cmd ScrCmd_setobjectmovementtype, requests_effects=1 @ 0x65
|
||||||
.4byte ScrCmd_waitmessage @ 0x66
|
cmd ScrCmd_waitmessage, requests_effects=1 @ 0x66
|
||||||
.4byte ScrCmd_message @ 0x67
|
cmd ScrCmd_message, requests_effects=1 @ 0x67
|
||||||
.4byte ScrCmd_closemessage @ 0x68
|
cmd ScrCmd_closemessage, requests_effects=1 @ 0x68
|
||||||
.4byte ScrCmd_lockall @ 0x69
|
cmd ScrCmd_lockall, requests_effects=1 @ 0x69
|
||||||
.4byte ScrCmd_lock @ 0x6a
|
cmd ScrCmd_lock, requests_effects=1 @ 0x6a
|
||||||
.4byte ScrCmd_releaseall @ 0x6b
|
cmd ScrCmd_releaseall, requests_effects=1 @ 0x6b
|
||||||
.4byte ScrCmd_release @ 0x6c
|
cmd ScrCmd_release, requests_effects=1 @ 0x6c
|
||||||
.4byte ScrCmd_waitbuttonpress @ 0x6d
|
cmd ScrCmd_waitbuttonpress, requests_effects=1 @ 0x6d
|
||||||
.4byte ScrCmd_yesnobox @ 0x6e
|
cmd ScrCmd_yesnobox, requests_effects=1 @ 0x6e
|
||||||
.4byte ScrCmd_multichoice @ 0x6f
|
cmd ScrCmd_multichoice, requests_effects=1 @ 0x6f
|
||||||
.4byte ScrCmd_multichoicedefault @ 0x70
|
cmd ScrCmd_multichoicedefault, requests_effects=1 @ 0x70
|
||||||
.4byte ScrCmd_multichoicegrid @ 0x71
|
cmd ScrCmd_multichoicegrid, requests_effects=1 @ 0x71
|
||||||
.4byte ScrCmd_drawbox @ 0x72
|
cmd ScrCmd_drawbox, requests_effects=1 @ 0x72
|
||||||
.4byte ScrCmd_erasebox @ 0x73
|
cmd ScrCmd_erasebox, requests_effects=1 @ 0x73
|
||||||
.4byte ScrCmd_drawboxtext @ 0x74
|
cmd ScrCmd_drawboxtext, requests_effects=1 @ 0x74
|
||||||
.4byte ScrCmd_showmonpic @ 0x75
|
cmd ScrCmd_showmonpic, requests_effects=1 @ 0x75
|
||||||
.4byte ScrCmd_hidemonpic @ 0x76
|
cmd ScrCmd_hidemonpic, requests_effects=1 @ 0x76
|
||||||
.4byte ScrCmd_showcontestpainting @ 0x77
|
cmd ScrCmd_showcontestpainting, requests_effects=1 @ 0x77
|
||||||
.4byte ScrCmd_braillemessage @ 0x78
|
cmd ScrCmd_braillemessage, requests_effects=1 @ 0x78
|
||||||
.4byte ScrCmd_nop1 @ 0x79
|
cmd ScrCmd_nop1, requests_effects=1 @ 0x79
|
||||||
.4byte ScrCmd_giveegg @ 0x7a
|
cmd ScrCmd_giveegg, requests_effects=1 @ 0x7a
|
||||||
.4byte ScrCmd_setmonmove @ 0x7b
|
cmd ScrCmd_setmonmove, requests_effects=1 @ 0x7b
|
||||||
.4byte ScrCmd_checkpartymove @ 0x7c
|
cmd ScrCmd_checkpartymove, requests_effects=1 @ 0x7c
|
||||||
.4byte ScrCmd_bufferspeciesname @ 0x7d
|
cmd ScrCmd_bufferspeciesname, requests_effects=1 @ 0x7d
|
||||||
.4byte ScrCmd_bufferleadmonspeciesname @ 0x7e
|
cmd ScrCmd_bufferleadmonspeciesname, requests_effects=1 @ 0x7e
|
||||||
.4byte ScrCmd_bufferpartymonnick @ 0x7f
|
cmd ScrCmd_bufferpartymonnick, requests_effects=1 @ 0x7f
|
||||||
.4byte ScrCmd_bufferitemname @ 0x80
|
cmd ScrCmd_bufferitemname, requests_effects=1 @ 0x80
|
||||||
.4byte ScrCmd_bufferdecorationname @ 0x81
|
cmd ScrCmd_bufferdecorationname, requests_effects=1 @ 0x81
|
||||||
.4byte ScrCmd_buffermovename @ 0x82
|
cmd ScrCmd_buffermovename, requests_effects=1 @ 0x82
|
||||||
.4byte ScrCmd_buffernumberstring @ 0x83
|
cmd ScrCmd_buffernumberstring, requests_effects=1 @ 0x83
|
||||||
.4byte ScrCmd_bufferstdstring @ 0x84
|
cmd ScrCmd_bufferstdstring, requests_effects=1 @ 0x84
|
||||||
.4byte ScrCmd_bufferstring @ 0x85
|
cmd ScrCmd_bufferstring, requests_effects=1 @ 0x85
|
||||||
.4byte ScrCmd_pokemart @ 0x86
|
cmd ScrCmd_pokemart, requests_effects=1 @ 0x86
|
||||||
.4byte ScrCmd_pokemartdecoration @ 0x87
|
cmd ScrCmd_pokemartdecoration, requests_effects=1 @ 0x87
|
||||||
.4byte ScrCmd_pokemartdecoration2 @ 0x88
|
cmd ScrCmd_pokemartdecoration2, requests_effects=1 @ 0x88
|
||||||
.4byte ScrCmd_playslotmachine @ 0x89
|
cmd ScrCmd_playslotmachine, requests_effects=1 @ 0x89
|
||||||
.4byte ScrCmd_setberrytree @ 0x8a
|
cmd ScrCmd_setberrytree, requests_effects=1 @ 0x8a
|
||||||
.4byte ScrCmd_choosecontestmon @ 0x8b
|
cmd ScrCmd_choosecontestmon, requests_effects=1 @ 0x8b
|
||||||
.4byte ScrCmd_startcontest @ 0x8c
|
cmd ScrCmd_startcontest, requests_effects=1 @ 0x8c
|
||||||
.4byte ScrCmd_showcontestresults @ 0x8d
|
cmd ScrCmd_showcontestresults, requests_effects=1 @ 0x8d
|
||||||
.4byte ScrCmd_contestlinktransfer @ 0x8e
|
cmd ScrCmd_contestlinktransfer, requests_effects=1 @ 0x8e
|
||||||
.4byte ScrCmd_random @ 0x8f
|
cmd ScrCmd_random, requests_effects=1 @ 0x8f
|
||||||
.4byte ScrCmd_addmoney @ 0x90
|
cmd ScrCmd_addmoney, requests_effects=1 @ 0x90
|
||||||
.4byte ScrCmd_removemoney @ 0x91
|
cmd ScrCmd_removemoney, requests_effects=1 @ 0x91
|
||||||
.4byte ScrCmd_checkmoney @ 0x92
|
cmd ScrCmd_checkmoney, requests_effects=1 @ 0x92
|
||||||
.4byte ScrCmd_showmoneybox @ 0x93
|
cmd ScrCmd_showmoneybox, requests_effects=1 @ 0x93
|
||||||
.4byte ScrCmd_hidemoneybox @ 0x94
|
cmd ScrCmd_hidemoneybox, requests_effects=1 @ 0x94
|
||||||
.4byte ScrCmd_updatemoneybox @ 0x95
|
cmd ScrCmd_updatemoneybox, requests_effects=1 @ 0x95
|
||||||
.4byte ScrCmd_getpokenewsactive @ 0x96
|
cmd ScrCmd_getpokenewsactive, requests_effects=1 @ 0x96
|
||||||
.4byte ScrCmd_fadescreen @ 0x97
|
cmd ScrCmd_fadescreen, requests_effects=1 @ 0x97
|
||||||
.4byte ScrCmd_fadescreenspeed @ 0x98
|
cmd ScrCmd_fadescreenspeed, requests_effects=1 @ 0x98
|
||||||
.4byte ScrCmd_setflashlevel @ 0x99
|
cmd ScrCmd_setflashlevel, requests_effects=1 @ 0x99
|
||||||
.4byte ScrCmd_animateflash @ 0x9a
|
cmd ScrCmd_animateflash, requests_effects=1 @ 0x9a
|
||||||
.4byte ScrCmd_messageautoscroll @ 0x9b
|
cmd ScrCmd_messageautoscroll, requests_effects=1 @ 0x9b
|
||||||
.4byte ScrCmd_dofieldeffect @ 0x9c
|
cmd ScrCmd_dofieldeffect, requests_effects=1 @ 0x9c
|
||||||
.4byte ScrCmd_setfieldeffectargument @ 0x9d
|
cmd ScrCmd_setfieldeffectargument, requests_effects=1 @ 0x9d
|
||||||
.4byte ScrCmd_waitfieldeffect @ 0x9e
|
cmd ScrCmd_waitfieldeffect, requests_effects=1 @ 0x9e
|
||||||
.4byte ScrCmd_setrespawn @ 0x9f
|
cmd ScrCmd_setrespawn, requests_effects=1 @ 0x9f
|
||||||
.4byte ScrCmd_checkplayergender @ 0xa0
|
cmd ScrCmd_checkplayergender, requests_effects=1 @ 0xa0
|
||||||
.4byte ScrCmd_playmoncry @ 0xa1
|
cmd ScrCmd_playmoncry, requests_effects=1 @ 0xa1
|
||||||
.4byte ScrCmd_setmetatile @ 0xa2
|
cmd ScrCmd_setmetatile, requests_effects=1 @ 0xa2
|
||||||
.4byte ScrCmd_resetweather @ 0xa3
|
cmd ScrCmd_resetweather, requests_effects=1 @ 0xa3
|
||||||
.4byte ScrCmd_setweather @ 0xa4
|
cmd ScrCmd_setweather, requests_effects=1 @ 0xa4
|
||||||
.4byte ScrCmd_doweather @ 0xa5
|
cmd ScrCmd_doweather, requests_effects=1 @ 0xa5
|
||||||
.4byte ScrCmd_setstepcallback @ 0xa6
|
cmd ScrCmd_setstepcallback, requests_effects=1 @ 0xa6
|
||||||
.4byte ScrCmd_setmaplayoutindex @ 0xa7
|
cmd ScrCmd_setmaplayoutindex, requests_effects=1 @ 0xa7
|
||||||
.4byte ScrCmd_setobjectsubpriority @ 0xa8
|
cmd ScrCmd_setobjectsubpriority, requests_effects=1 @ 0xa8
|
||||||
.4byte ScrCmd_resetobjectsubpriority @ 0xa9
|
cmd ScrCmd_resetobjectsubpriority, requests_effects=1 @ 0xa9
|
||||||
.4byte ScrCmd_createvobject @ 0xaa
|
cmd ScrCmd_createvobject, requests_effects=1 @ 0xaa
|
||||||
.4byte ScrCmd_turnvobject @ 0xab
|
cmd ScrCmd_turnvobject, requests_effects=1 @ 0xab
|
||||||
.4byte ScrCmd_opendoor @ 0xac
|
cmd ScrCmd_opendoor, requests_effects=1 @ 0xac
|
||||||
.4byte ScrCmd_closedoor @ 0xad
|
cmd ScrCmd_closedoor, requests_effects=1 @ 0xad
|
||||||
.4byte ScrCmd_waitdooranim @ 0xae
|
cmd ScrCmd_waitdooranim, requests_effects=1 @ 0xae
|
||||||
.4byte ScrCmd_setdooropen @ 0xaf
|
cmd ScrCmd_setdooropen, requests_effects=1 @ 0xaf
|
||||||
.4byte ScrCmd_setdoorclosed @ 0xb0
|
cmd ScrCmd_setdoorclosed, requests_effects=1 @ 0xb0
|
||||||
.4byte ScrCmd_addelevmenuitem @ 0xb1
|
cmd ScrCmd_addelevmenuitem, requests_effects=1 @ 0xb1
|
||||||
.4byte ScrCmd_showelevmenu @ 0xb2
|
cmd ScrCmd_showelevmenu, requests_effects=1 @ 0xb2
|
||||||
.4byte ScrCmd_checkcoins @ 0xb3
|
cmd ScrCmd_checkcoins, requests_effects=1 @ 0xb3
|
||||||
.4byte ScrCmd_addcoins @ 0xb4
|
cmd ScrCmd_addcoins, requests_effects=1 @ 0xb4
|
||||||
.4byte ScrCmd_removecoins @ 0xb5
|
cmd ScrCmd_removecoins, requests_effects=1 @ 0xb5
|
||||||
.4byte ScrCmd_setwildbattle @ 0xb6
|
cmd ScrCmd_setwildbattle, requests_effects=1 @ 0xb6
|
||||||
.4byte ScrCmd_dowildbattle @ 0xb7
|
cmd ScrCmd_dowildbattle, requests_effects=1 @ 0xb7
|
||||||
.4byte ScrCmd_setvaddress @ 0xb8
|
cmd ScrCmd_setvaddress, requests_effects=1 @ 0xb8
|
||||||
.4byte ScrCmd_vgoto @ 0xb9
|
cmd ScrCmd_vgoto, requests_effects=1 @ 0xb9
|
||||||
.4byte ScrCmd_vcall @ 0xba
|
cmd ScrCmd_vcall, requests_effects=1 @ 0xba
|
||||||
.4byte ScrCmd_vgoto_if @ 0xbb
|
cmd ScrCmd_vgoto_if, requests_effects=1 @ 0xbb
|
||||||
.4byte ScrCmd_vcall_if @ 0xbc
|
cmd ScrCmd_vcall_if, requests_effects=1 @ 0xbc
|
||||||
.4byte ScrCmd_vmessage @ 0xbd
|
cmd ScrCmd_vmessage, requests_effects=1 @ 0xbd
|
||||||
.4byte ScrCmd_vbuffermessage @ 0xbe
|
cmd ScrCmd_vbuffermessage, requests_effects=1 @ 0xbe
|
||||||
.4byte ScrCmd_vbufferstring @ 0xbf
|
cmd ScrCmd_vbufferstring, requests_effects=1 @ 0xbf
|
||||||
.4byte ScrCmd_showcoinsbox @ 0xc0
|
cmd ScrCmd_showcoinsbox, requests_effects=1 @ 0xc0
|
||||||
.4byte ScrCmd_hidecoinsbox @ 0xc1
|
cmd ScrCmd_hidecoinsbox, requests_effects=1 @ 0xc1
|
||||||
.4byte ScrCmd_updatecoinsbox @ 0xc2
|
cmd ScrCmd_updatecoinsbox, requests_effects=1 @ 0xc2
|
||||||
.4byte ScrCmd_incrementgamestat @ 0xc3
|
cmd ScrCmd_incrementgamestat, requests_effects=1 @ 0xc3
|
||||||
.4byte ScrCmd_setescapewarp @ 0xc4
|
cmd ScrCmd_setescapewarp, requests_effects=1 @ 0xc4
|
||||||
.4byte ScrCmd_waitmoncry @ 0xc5
|
cmd ScrCmd_waitmoncry, requests_effects=1 @ 0xc5
|
||||||
.4byte ScrCmd_bufferboxname @ 0xc6
|
cmd ScrCmd_bufferboxname, requests_effects=1 @ 0xc6
|
||||||
.4byte ScrCmd_nop1 @ 0xc7
|
cmd ScrCmd_nop1, requests_effects=1 @ 0xc7
|
||||||
.4byte ScrCmd_nop1 @ 0xc8
|
cmd ScrCmd_nop1, requests_effects=1 @ 0xc8
|
||||||
.4byte ScrCmd_nop1 @ 0xc9
|
cmd ScrCmd_nop1, requests_effects=1 @ 0xc9
|
||||||
.4byte ScrCmd_nop1 @ 0xca
|
cmd ScrCmd_nop1, requests_effects=1 @ 0xca
|
||||||
.4byte ScrCmd_nop1 @ 0xcb
|
cmd ScrCmd_nop1, requests_effects=1 @ 0xcb
|
||||||
.4byte ScrCmd_nop1 @ 0xcc
|
cmd ScrCmd_nop1, requests_effects=1 @ 0xcc
|
||||||
.4byte ScrCmd_setmodernfatefulencounter @ 0xcd
|
cmd ScrCmd_setmodernfatefulencounter, requests_effects=1 @ 0xcd
|
||||||
.4byte ScrCmd_checkmodernfatefulencounter @ 0xce
|
cmd ScrCmd_checkmodernfatefulencounter, requests_effects=1 @ 0xce
|
||||||
.4byte ScrCmd_trywondercardscript @ 0xcf
|
cmd ScrCmd_trywondercardscript, requests_effects=1 @ 0xcf
|
||||||
.4byte ScrCmd_nop1 @ 0xd0
|
cmd ScrCmd_nop1, requests_effects=1 @ 0xd0
|
||||||
.4byte ScrCmd_warpspinenter @ 0xd1
|
cmd ScrCmd_warpspinenter, requests_effects=1 @ 0xd1
|
||||||
.4byte ScrCmd_setmonmetlocation @ 0xd2
|
cmd ScrCmd_setmonmetlocation, requests_effects=1 @ 0xd2
|
||||||
.4byte ScrCmd_moverotatingtileobjects @ 0xd3
|
cmd ScrCmd_moverotatingtileobjects, requests_effects=1 @ 0xd3
|
||||||
.4byte ScrCmd_turnrotatingtileobjects @ 0xd4
|
cmd ScrCmd_turnrotatingtileobjects, requests_effects=1 @ 0xd4
|
||||||
.4byte ScrCmd_initrotatingtilepuzzle @ 0xd5
|
cmd ScrCmd_initrotatingtilepuzzle, requests_effects=1 @ 0xd5
|
||||||
.4byte ScrCmd_freerotatingtilepuzzle @ 0xd6
|
cmd ScrCmd_freerotatingtilepuzzle, requests_effects=1 @ 0xd6
|
||||||
.4byte ScrCmd_warpmossdeepgym @ 0xd7
|
cmd ScrCmd_warpmossdeepgym, requests_effects=1 @ 0xd7
|
||||||
.4byte ScrCmd_selectapproachingtrainer @ 0xd8
|
cmd ScrCmd_selectapproachingtrainer, requests_effects=1 @ 0xd8
|
||||||
.4byte ScrCmd_lockfortrainer @ 0xd9
|
cmd ScrCmd_lockfortrainer, requests_effects=1 @ 0xd9
|
||||||
.4byte ScrCmd_closebraillemessage @ 0xda
|
cmd ScrCmd_closebraillemessage, requests_effects=1 @ 0xda
|
||||||
.4byte ScrCmd_messageinstant @ 0xdb
|
cmd ScrCmd_messageinstant, requests_effects=1 @ 0xdb
|
||||||
.4byte ScrCmd_fadescreenswapbuffers @ 0xdc
|
cmd ScrCmd_fadescreenswapbuffers, requests_effects=1 @ 0xdc
|
||||||
.4byte ScrCmd_buffertrainerclassname @ 0xdd
|
cmd ScrCmd_buffertrainerclassname, requests_effects=1 @ 0xdd
|
||||||
.4byte ScrCmd_buffertrainername @ 0xde
|
cmd ScrCmd_buffertrainername, requests_effects=1 @ 0xde
|
||||||
.4byte ScrCmd_pokenavcall @ 0xdf
|
cmd ScrCmd_pokenavcall, requests_effects=1 @ 0xdf
|
||||||
.4byte ScrCmd_warpwhitefade @ 0xe0
|
cmd ScrCmd_warpwhitefade, requests_effects=1 @ 0xe0
|
||||||
.4byte ScrCmd_buffercontestname @ 0xe1
|
cmd ScrCmd_buffercontestname, requests_effects=1 @ 0xe1
|
||||||
.4byte ScrCmd_bufferitemnameplural @ 0xe2
|
cmd ScrCmd_bufferitemnameplural, requests_effects=1 @ 0xe2
|
||||||
.4byte ScrCmd_dynmultichoice @ 0xe3
|
cmd ScrCmd_dynmultichoice, requests_effects=1 @ 0xe3
|
||||||
.4byte ScrCmd_dynmultipush @ 0xe4
|
cmd ScrCmd_dynmultipush, requests_effects=1 @ 0xe4
|
||||||
|
|
||||||
gScriptCmdTableEnd::
|
gScriptCmdTableEnd::
|
||||||
.4byte ScrCmd_nop
|
.4byte ScrCmd_nop
|
||||||
|
|||||||
@ -20,3 +20,9 @@ EventScript_GotoTrainerScript::
|
|||||||
gotobeatenscript
|
gotobeatenscript
|
||||||
releaseall
|
releaseall
|
||||||
end
|
end
|
||||||
|
|
||||||
|
EventScript_ObjectApproachPlayer::
|
||||||
|
lock
|
||||||
|
special DoTrainerApproach
|
||||||
|
waitstate
|
||||||
|
gotonative LoadTrainerObjectScript
|
||||||
|
|||||||
@ -1,9 +1,16 @@
|
|||||||
.macro def_special ptr
|
@ 'requests_effects' should be set to 1 if the special contains a call
|
||||||
|
@ to 'Script_RequestEffects', which allows it to be analyzed with
|
||||||
|
@ 'RunScriptImmediatelyUntilEffect'.
|
||||||
|
.macro def_special ptr:req, requests_effects=0
|
||||||
.global SPECIAL_\ptr
|
.global SPECIAL_\ptr
|
||||||
.set SPECIAL_\ptr, __special__
|
.set SPECIAL_\ptr, __special__
|
||||||
.set __special__, __special__ + 1
|
.set __special__, __special__ + 1
|
||||||
|
.if \requests_effects == 0
|
||||||
.4byte \ptr
|
.4byte \ptr
|
||||||
.endm
|
.else
|
||||||
|
.4byte \ptr + ROM_SIZE
|
||||||
|
.endif
|
||||||
|
.endm
|
||||||
|
|
||||||
.set __special__, 0
|
.set __special__, 0
|
||||||
.align 2
|
.align 2
|
||||||
@ -297,7 +304,7 @@ gSpecials::
|
|||||||
def_special WaitWeather
|
def_special WaitWeather
|
||||||
def_special BufferEReaderTrainerName
|
def_special BufferEReaderTrainerName
|
||||||
def_special GetSlotMachineId
|
def_special GetSlotMachineId
|
||||||
def_special GetPlayerFacingDirection
|
def_special GetPlayerFacingDirection, requests_effects=TRUE
|
||||||
def_special FoundAbandonedShipRoom1Key
|
def_special FoundAbandonedShipRoom1Key
|
||||||
def_special FoundAbandonedShipRoom2Key
|
def_special FoundAbandonedShipRoom2Key
|
||||||
def_special FoundAbandonedShipRoom4Key
|
def_special FoundAbandonedShipRoom4Key
|
||||||
|
|||||||
@ -36,6 +36,7 @@ extern const u8 EventScript_TryDoDoubleTrainerBattle[];
|
|||||||
extern const u8 EventScript_TryDoNormalTrainerBattle[];
|
extern const u8 EventScript_TryDoNormalTrainerBattle[];
|
||||||
extern const u8 EventScript_TryDoDoubleRematchBattle[];
|
extern const u8 EventScript_TryDoDoubleRematchBattle[];
|
||||||
extern const u8 EventScript_TryDoRematchBattle[];
|
extern const u8 EventScript_TryDoRematchBattle[];
|
||||||
|
extern const u8 EventScript_ObjectApproachPlayer[];
|
||||||
|
|
||||||
extern const u8 BerryTreeScript[];
|
extern const u8 BerryTreeScript[];
|
||||||
|
|
||||||
|
|||||||
112
include/script.h
112
include/script.h
@ -1,6 +1,8 @@
|
|||||||
#ifndef GUARD_SCRIPT_H
|
#ifndef GUARD_SCRIPT_H
|
||||||
#define GUARD_SCRIPT_H
|
#define GUARD_SCRIPT_H
|
||||||
|
|
||||||
|
#include <setjmp.h>
|
||||||
|
|
||||||
struct ScriptContext;
|
struct ScriptContext;
|
||||||
|
|
||||||
typedef bool8 (*ScrCmdFunc)(struct ScriptContext *);
|
typedef bool8 (*ScrCmdFunc)(struct ScriptContext *);
|
||||||
@ -11,6 +13,7 @@ struct ScriptContext
|
|||||||
u8 stackDepth;
|
u8 stackDepth;
|
||||||
u8 mode;
|
u8 mode;
|
||||||
u8 comparisonResult;
|
u8 comparisonResult;
|
||||||
|
bool8 breakOnTrainerBattle;
|
||||||
u8 (*nativePtr)(void);
|
u8 (*nativePtr)(void);
|
||||||
const u8 *scriptPtr;
|
const u8 *scriptPtr;
|
||||||
const u8 *stack[20];
|
const u8 *stack[20];
|
||||||
@ -39,12 +42,13 @@ void ScriptContext_Init(void);
|
|||||||
bool8 ScriptContext_IsEnabled(void);
|
bool8 ScriptContext_IsEnabled(void);
|
||||||
bool8 ScriptContext_RunScript(void);
|
bool8 ScriptContext_RunScript(void);
|
||||||
void ScriptContext_SetupScript(const u8 *ptr);
|
void ScriptContext_SetupScript(const u8 *ptr);
|
||||||
|
void ScriptContext_ContinueScript(struct ScriptContext *ctx);
|
||||||
void ScriptContext_Stop(void);
|
void ScriptContext_Stop(void);
|
||||||
void ScriptContext_Enable(void);
|
void ScriptContext_Enable(void);
|
||||||
void RunScriptImmediately(const u8 *ptr);
|
void RunScriptImmediately(const u8 *ptr);
|
||||||
u8 *MapHeaderGetScriptTable(u8 tag);
|
const u8 *MapHeaderGetScriptTable(u8 tag);
|
||||||
void MapHeaderRunScriptType(u8 tag);
|
void MapHeaderRunScriptType(u8 tag);
|
||||||
u8 *MapHeaderCheckScriptTable(u8 tag);
|
const u8 *MapHeaderCheckScriptTable(u8 tag);
|
||||||
void RunOnLoadMapScript(void);
|
void RunOnLoadMapScript(void);
|
||||||
void RunOnTransitionMapScript(void);
|
void RunOnTransitionMapScript(void);
|
||||||
void RunOnResumeMapScript(void);
|
void RunOnResumeMapScript(void);
|
||||||
@ -66,4 +70,108 @@ void SetMovingNpcId(u16 npcId);
|
|||||||
extern u8 gMsgIsSignPost;
|
extern u8 gMsgIsSignPost;
|
||||||
extern u8 gMsgBoxIsCancelable;
|
extern u8 gMsgBoxIsCancelable;
|
||||||
|
|
||||||
|
/* Script effects analysis.
|
||||||
|
*
|
||||||
|
* 'RunScriptImmediatelyUntilEffect' executes a script until it reaches
|
||||||
|
* the first command which calls 'Script_RequestEffects' with an
|
||||||
|
* effect in 'effects' in which case it returns 'TRUE' and stores the
|
||||||
|
* current state in 'ctx'; or until it reaches an 'end'/'return' in
|
||||||
|
* which case it returns 'FALSE'.
|
||||||
|
*
|
||||||
|
* 'Script_HasNoEffect' wraps 'RunScriptImmediatelyUntilEffect' and
|
||||||
|
* returns 'TRUE' if the script exits without an effect on the save or
|
||||||
|
* the hardware, or 'FALSE' if it would have an effect (the effect is
|
||||||
|
* not performed).
|
||||||
|
*
|
||||||
|
* Commands, natives, and specials which call 'Script_RequestEffects'
|
||||||
|
* must be explicitly tagged with 'requests_effects=1', and must call
|
||||||
|
* the function before any of those effects occur. An untagged function
|
||||||
|
* could cause any effect, so execution is stopped to be safe. If the
|
||||||
|
* code has no effects it must call 'Script_RequestEffects(SCREFF_V1)'
|
||||||
|
* to note that explicitly.
|
||||||
|
*
|
||||||
|
* Regular variables are in the save (so should use 'SCREFF_SAVE'), but
|
||||||
|
* special variables are not in the save, so 'Script_RequestWriteVar' is
|
||||||
|
* provided to only request the 'SCREFF_SAVE' effect for a non-special
|
||||||
|
* variable.
|
||||||
|
*
|
||||||
|
* The 'effects' parameter to 'RunScriptImmediatelyUntilEffect' and
|
||||||
|
* 'Script_RequestEffects' must be the bitwise or of an effects version
|
||||||
|
* (currently 'SCREFF_V1') and any number of effects. For example
|
||||||
|
* 'Script_RequestEffects(SCREFF_V1 | SCREFF_SAVE)'. */
|
||||||
|
|
||||||
|
enum // effects
|
||||||
|
{
|
||||||
|
SCREFF_SAVE = 1 << 0, // writes to the save.
|
||||||
|
SCREFF_HARDWARE = 1 << 1, // writes to a hardware register.
|
||||||
|
SCREFF_TRAINERBATTLE = 1 << 2, // 'trainerbattle' command.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum // effects versions
|
||||||
|
{
|
||||||
|
SCREFF_V1 = ~7,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct ScriptEffectContext *gScriptEffectContext;
|
||||||
|
|
||||||
|
bool32 RunScriptImmediatelyUntilEffect_Internal(u32 effects, const u8 *ptr, struct ScriptContext *ctx);
|
||||||
|
bool32 Script_HasNoEffect(const u8 *ptr);
|
||||||
|
void Script_GotoBreak_Internal(void);
|
||||||
|
void Script_RequestEffects_Internal(u32 effects);
|
||||||
|
void Script_RequestWriteVar_Internal(u32 varId);
|
||||||
|
|
||||||
|
static inline bool32 Script_IsAnalyzingEffects(void)
|
||||||
|
{
|
||||||
|
return gScriptEffectContext != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RunScriptImmediatelyUntilEffect(effects, ptr, ctx) \
|
||||||
|
({ \
|
||||||
|
_Static_assert((effects) & 0x80000000, "RunScriptImmediatelyUntilEffect requires an effects version"); \
|
||||||
|
RunScriptImmediatelyUntilEffect_Internal(effects, ptr, ctx); \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Optimize 'Script_RequestEffects' to a no-op if it would have no
|
||||||
|
* effect. 'Script_RequestEffects' must be called in all commands and
|
||||||
|
* natives/specials with 'request_effects=TRUE' even if it would have
|
||||||
|
* no effect to future-proof against new effects. */
|
||||||
|
#define Script_RequestEffects(effects) \
|
||||||
|
({ \
|
||||||
|
_Static_assert((effects) & 0x80000000, "Script_RequestEffects requires an effects version"); \
|
||||||
|
if ((effects) != SCREFF_V1) \
|
||||||
|
if (Script_IsAnalyzingEffects()) \
|
||||||
|
Script_RequestEffects_Internal(effects); \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Optimize 'Script_RequestWriteVar' to a no-op if it would have no
|
||||||
|
* effect. */
|
||||||
|
#define Script_RequestWriteVar(varId) \
|
||||||
|
({ \
|
||||||
|
if (Script_IsAnalyzingEffects()) \
|
||||||
|
Script_RequestWriteVar_Internal(varId); \
|
||||||
|
})
|
||||||
|
|
||||||
|
static inline void Script_CheckEffectInstrumentedSpecial(u32 specialId)
|
||||||
|
{
|
||||||
|
typedef u16 (*SpecialFunc)(void);
|
||||||
|
extern const SpecialFunc gSpecials[];
|
||||||
|
// In ROM mirror 1.
|
||||||
|
if (Script_IsAnalyzingEffects() && (((uintptr_t)gSpecials[specialId]) & 0xE000000) != 0xA000000)
|
||||||
|
Script_GotoBreak_Internal();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Script_CheckEffectInstrumentedGotoNative(bool8 (*func)(void))
|
||||||
|
{
|
||||||
|
// In ROM mirror 1.
|
||||||
|
if (Script_IsAnalyzingEffects() && (((uintptr_t)func) & 0xE000000) != 0xA000000)
|
||||||
|
Script_GotoBreak_Internal();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void Script_CheckEffectInstrumentedCallNative(void (*func)(struct ScriptContext *))
|
||||||
|
{
|
||||||
|
// In ROM mirror 1.
|
||||||
|
if (Script_IsAnalyzingEffects() && (((uintptr_t)func) & 0xE000000) != 0xA000000)
|
||||||
|
Script_GotoBreak_Internal();
|
||||||
|
}
|
||||||
|
|
||||||
#endif // GUARD_SCRIPT_H
|
#endif // GUARD_SCRIPT_H
|
||||||
|
|||||||
@ -42,6 +42,17 @@
|
|||||||
|
|
||||||
#define RUN_OVERWORLD_SCRIPT(...) RunScriptImmediately(OVERWORLD_SCRIPT(__VA_ARGS__))
|
#define RUN_OVERWORLD_SCRIPT(...) RunScriptImmediately(OVERWORLD_SCRIPT(__VA_ARGS__))
|
||||||
|
|
||||||
|
// Make important constants available.
|
||||||
|
// TODO: Find a better approach to this.
|
||||||
|
asm(".set FALSE, 0\n"
|
||||||
|
".set TRUE, 1\n"
|
||||||
|
".set PARTY_SIZE, " STR(PARTY_SIZE) "\n"
|
||||||
|
".set VARS_START, " STR(VARS_START) "\n"
|
||||||
|
".set VARS_END, " STR(VARS_END) "\n"
|
||||||
|
".set SPECIAL_VARS_START, " STR(SPECIAL_VARS_START) "\n"
|
||||||
|
".set SPECIAL_VARS_END, " STR(SPECIAL_VARS_END) "\n");
|
||||||
|
asm(".include \"constants/gba_constants.inc\"\n");
|
||||||
|
|
||||||
// Make overworld script macros available.
|
// Make overworld script macros available.
|
||||||
asm(".include \"asm/macros/event.inc\"\n");
|
asm(".include \"asm/macros/event.inc\"\n");
|
||||||
|
|
||||||
|
|||||||
@ -5353,6 +5353,8 @@ static s32 AI_DynamicFunc(u32 battlerAtk, u32 battlerDef, u32 move, s32 score)
|
|||||||
|
|
||||||
void ScriptSetDynamicAiFunc(struct ScriptContext *ctx)
|
void ScriptSetDynamicAiFunc(struct ScriptContext *ctx)
|
||||||
{
|
{
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
|
||||||
AiScoreFunc func = (AiScoreFunc)ScriptReadWord(ctx);
|
AiScoreFunc func = (AiScoreFunc)ScriptReadWord(ctx);
|
||||||
sDynamicAiFunc = func;
|
sDynamicAiFunc = func;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2060,6 +2060,8 @@ static u8 CreateNPCTrainerParty(struct Pokemon *party, u16 trainerNum, bool8 fir
|
|||||||
|
|
||||||
void CreateTrainerPartyForPlayer(void)
|
void CreateTrainerPartyForPlayer(void)
|
||||||
{
|
{
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
|
||||||
ZeroPlayerPartyMons();
|
ZeroPlayerPartyMons();
|
||||||
gPartnerTrainerId = gSpecialVar_0x8004;
|
gPartnerTrainerId = gSpecialVar_0x8004;
|
||||||
CreateNPCTrainerPartyFromTrainer(gPlayerParty, GetTrainerStructFromId(gSpecialVar_0x8004), TRUE, BATTLE_TYPE_TRAINER);
|
CreateNPCTrainerPartyFromTrainer(gPlayerParty, GetTrainerStructFromId(gSpecialVar_0x8004), TRUE, BATTLE_TYPE_TRAINER);
|
||||||
@ -6135,6 +6137,8 @@ void ScriptSetTotemBoost(struct ScriptContext *ctx)
|
|||||||
u32 stat;
|
u32 stat;
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
|
||||||
for (i = 0; i < (NUM_BATTLE_STATS - 1); i++)
|
for (i = 0; i < (NUM_BATTLE_STATS - 1); i++)
|
||||||
{
|
{
|
||||||
stat = VarGet(ScriptReadHalfword(ctx));
|
stat = VarGet(ScriptReadHalfword(ctx));
|
||||||
|
|||||||
@ -64,6 +64,9 @@ void Script_IncreaseDifficulty(void)
|
|||||||
if (currentDifficulty++ > DIFFICULTY_MAX)
|
if (currentDifficulty++ > DIFFICULTY_MAX)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
Script_RequestWriteVar(B_VAR_DIFFICULTY);
|
||||||
|
|
||||||
SetCurrentDifficultyLevel(currentDifficulty);
|
SetCurrentDifficultyLevel(currentDifficulty);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,11 +82,15 @@ void Script_DecreaseDifficulty(void)
|
|||||||
if (!currentDifficulty)
|
if (!currentDifficulty)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
Script_RequestWriteVar(B_VAR_DIFFICULTY);
|
||||||
|
|
||||||
SetCurrentDifficultyLevel(--currentDifficulty);
|
SetCurrentDifficultyLevel(--currentDifficulty);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script_GetDifficulty(void)
|
void Script_GetDifficulty(void)
|
||||||
{
|
{
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
gSpecialVar_Result = GetCurrentDifficultyLevel();
|
gSpecialVar_Result = GetCurrentDifficultyLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,5 +98,8 @@ void Script_SetDifficulty(struct ScriptContext *ctx)
|
|||||||
{
|
{
|
||||||
enum DifficultyLevel desiredDifficulty = ScriptReadByte(ctx);
|
enum DifficultyLevel desiredDifficulty = ScriptReadByte(ctx);
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
Script_RequestWriteVar(B_VAR_DIFFICULTY);
|
||||||
|
|
||||||
SetCurrentDifficultyLevel(desiredDifficulty);
|
SetCurrentDifficultyLevel(desiredDifficulty);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6012,9 +6012,15 @@ u8 GetDirectionToFace(s16 x, s16 y, s16 targetX, s16 targetY)
|
|||||||
// Uses the above, but script accessible, and uses localIds
|
// Uses the above, but script accessible, and uses localIds
|
||||||
void GetDirectionToFaceScript(struct ScriptContext *ctx)
|
void GetDirectionToFaceScript(struct ScriptContext *ctx)
|
||||||
{
|
{
|
||||||
u16 *var = GetVarPointer(ScriptReadHalfword(ctx));
|
u32 varId = ScriptReadHalfword(ctx);
|
||||||
u8 sourceId = GetObjectEventIdByLocalId(ScriptReadByte(ctx));
|
u8 sourceId = GetObjectEventIdByLocalId(ScriptReadByte(ctx));
|
||||||
u8 targetId = GetObjectEventIdByLocalId(ScriptReadByte(ctx));
|
u8 targetId = GetObjectEventIdByLocalId(ScriptReadByte(ctx));
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
Script_RequestWriteVar(varId);
|
||||||
|
|
||||||
|
u16 *var = GetVarPointer(varId);
|
||||||
|
|
||||||
if (var == NULL)
|
if (var == NULL)
|
||||||
return;
|
return;
|
||||||
if (sourceId >= OBJECT_EVENTS_COUNT || targetId >= OBJECT_EVENTS_COUNT)
|
if (sourceId >= OBJECT_EVENTS_COUNT || targetId >= OBJECT_EVENTS_COUNT)
|
||||||
@ -6030,7 +6036,12 @@ void GetDirectionToFaceScript(struct ScriptContext *ctx)
|
|||||||
// Intended to be called before the field effect itself
|
// Intended to be called before the field effect itself
|
||||||
void IsFollowerFieldMoveUser(struct ScriptContext *ctx)
|
void IsFollowerFieldMoveUser(struct ScriptContext *ctx)
|
||||||
{
|
{
|
||||||
u16 *var = GetVarPointer(ScriptReadHalfword(ctx));
|
u32 varId = ScriptReadHalfword(ctx);
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
Script_RequestWriteVar(varId);
|
||||||
|
|
||||||
|
u16 *var = GetVarPointer(varId);
|
||||||
u16 userIndex = gFieldEffectArguments[0]; // field move user index
|
u16 userIndex = gFieldEffectArguments[0]; // field move user index
|
||||||
struct Pokemon *follower = GetFirstLiveMon();
|
struct Pokemon *follower = GetFirstLiveMon();
|
||||||
struct ObjectEvent *obj = GetFollowerObject();
|
struct ObjectEvent *obj = GetFollowerObject();
|
||||||
@ -10995,6 +11006,13 @@ void GetDaycareGraphics(struct ScriptContext *ctx)
|
|||||||
u8 form;
|
u8 form;
|
||||||
u8 shiny;
|
u8 shiny;
|
||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
Script_RequestWriteVar(varGfx[0]);
|
||||||
|
Script_RequestWriteVar(varGfx[1]);
|
||||||
|
Script_RequestWriteVar(varForm[0]);
|
||||||
|
Script_RequestWriteVar(varForm[1]);
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
GetMonInfo((struct Pokemon *) &gSaveBlock1Ptr->daycare.mons[i].mon, &specGfx, &form, &shiny);
|
GetMonInfo((struct Pokemon *) &gSaveBlock1Ptr->daycare.mons[i].mon, &specGfx, &form, &shiny);
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
#include "fake_rtc.h"
|
#include "fake_rtc.h"
|
||||||
#include "event_data.h"
|
#include "event_data.h"
|
||||||
|
#include "script.h"
|
||||||
|
|
||||||
struct Time *FakeRtc_GetCurrentTime(void)
|
struct Time *FakeRtc_GetCurrentTime(void)
|
||||||
{
|
{
|
||||||
@ -90,15 +91,21 @@ STATIC_ASSERT((OW_FLAG_PAUSE_TIME == 0 || OW_USE_FAKE_RTC == TRUE), FakeRtcMustB
|
|||||||
|
|
||||||
void Script_PauseFakeRtc(void)
|
void Script_PauseFakeRtc(void)
|
||||||
{
|
{
|
||||||
|
Script_RequestEffects(SCREFF_V1 | SCREFF_SAVE);
|
||||||
|
|
||||||
FlagSet(OW_FLAG_PAUSE_TIME);
|
FlagSet(OW_FLAG_PAUSE_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script_ResumeFakeRtc(void)
|
void Script_ResumeFakeRtc(void)
|
||||||
{
|
{
|
||||||
|
Script_RequestEffects(SCREFF_V1 | SCREFF_SAVE);
|
||||||
|
|
||||||
FlagClear(OW_FLAG_PAUSE_TIME);
|
FlagClear(OW_FLAG_PAUSE_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script_ToggleFakeRtc(void)
|
void Script_ToggleFakeRtc(void)
|
||||||
{
|
{
|
||||||
|
Script_RequestEffects(SCREFF_V1 | SCREFF_SAVE);
|
||||||
|
|
||||||
FlagToggle(OW_FLAG_PAUSE_TIME);
|
FlagToggle(OW_FLAG_PAUSE_TIME);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -275,7 +275,7 @@ static u16 GetPlayerCurMetatileBehavior(int runningState)
|
|||||||
static bool8 TryStartInteractionScript(struct MapPosition *position, u16 metatileBehavior, u8 direction)
|
static bool8 TryStartInteractionScript(struct MapPosition *position, u16 metatileBehavior, u8 direction)
|
||||||
{
|
{
|
||||||
const u8 *script = GetInteractionScript(position, metatileBehavior, direction);
|
const u8 *script = GetInteractionScript(position, metatileBehavior, direction);
|
||||||
if (script == NULL)
|
if (script == NULL || Script_HasNoEffect(script))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
// Don't play interaction sound for certain scripts.
|
// Don't play interaction sound for certain scripts.
|
||||||
@ -590,7 +590,12 @@ static bool8 TryStartCoordEventScript(struct MapPosition *position)
|
|||||||
|
|
||||||
if (script == NULL)
|
if (script == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
ScriptContext_SetupScript(script);
|
|
||||||
|
struct ScriptContext ctx;
|
||||||
|
if (!RunScriptImmediatelyUntilEffect(SCREFF_V1 | SCREFF_HARDWARE, script, &ctx))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
ScriptContext_ContinueScript(&ctx);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1236,6 +1236,8 @@ u8 player_get_pos_including_state_based_drift(s16 *x, s16 *y)
|
|||||||
|
|
||||||
u8 GetPlayerFacingDirection(void)
|
u8 GetPlayerFacingDirection(void)
|
||||||
{
|
{
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
|
||||||
return gObjectEvents[gPlayerAvatar.objectEventId].facingDirection;
|
return gObjectEvents[gPlayerAvatar.objectEventId].facingDirection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -93,7 +93,9 @@ void AgbMain()
|
|||||||
{
|
{
|
||||||
*(vu16 *)BG_PLTT = RGB_WHITE; // Set the backdrop to white on startup
|
*(vu16 *)BG_PLTT = RGB_WHITE; // Set the backdrop to white on startup
|
||||||
InitGpuRegManager();
|
InitGpuRegManager();
|
||||||
REG_WAITCNT = WAITCNT_PREFETCH_ENABLE | WAITCNT_WS0_S_1 | WAITCNT_WS0_N_3;
|
REG_WAITCNT = WAITCNT_PREFETCH_ENABLE
|
||||||
|
| WAITCNT_WS0_S_1 | WAITCNT_WS0_N_3
|
||||||
|
| WAITCNT_WS1_S_1 | WAITCNT_WS1_N_3;
|
||||||
InitKeys();
|
InitKeys();
|
||||||
InitIntrHandlers();
|
InitIntrHandlers();
|
||||||
m4aSoundInit();
|
m4aSoundInit();
|
||||||
|
|||||||
@ -3386,6 +3386,9 @@ static u8 ReformatItemDescription(u16 item, u8 *dest)
|
|||||||
void ScriptShowItemDescription(struct ScriptContext *ctx)
|
void ScriptShowItemDescription(struct ScriptContext *ctx)
|
||||||
{
|
{
|
||||||
u8 headerType = ScriptReadByte(ctx);
|
u8 headerType = ScriptReadByte(ctx);
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1 | SCREFF_HARDWARE);
|
||||||
|
|
||||||
struct WindowTemplate template;
|
struct WindowTemplate template;
|
||||||
u16 item = gSpecialVar_0x8006;
|
u16 item = gSpecialVar_0x8006;
|
||||||
u8 textY;
|
u8 textY;
|
||||||
@ -3425,6 +3428,8 @@ void ScriptShowItemDescription(struct ScriptContext *ctx)
|
|||||||
|
|
||||||
void ScriptHideItemDescription(struct ScriptContext *ctx)
|
void ScriptHideItemDescription(struct ScriptContext *ctx)
|
||||||
{
|
{
|
||||||
|
Script_RequestEffects(SCREFF_V1 | SCREFF_SAVE | SCREFF_HARDWARE);
|
||||||
|
|
||||||
DestroyItemIconSprite();
|
DestroyItemIconSprite();
|
||||||
|
|
||||||
if (!GetSetItemObtained(gSpecialVar_0x8006, FLAG_GET_ITEM_OBTAINED))
|
if (!GetSetItemObtained(gSpecialVar_0x8006, FLAG_GET_ITEM_OBTAINED))
|
||||||
|
|||||||
613
src/scrcmd.c
613
src/scrcmd.c
File diff suppressed because it is too large
Load Diff
150
src/script.c
150
src/script.c
@ -2,6 +2,8 @@
|
|||||||
#include "script.h"
|
#include "script.h"
|
||||||
#include "event_data.h"
|
#include "event_data.h"
|
||||||
#include "mystery_gift.h"
|
#include "mystery_gift.h"
|
||||||
|
#include "random.h"
|
||||||
|
#include "trainer_see.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "constants/event_objects.h"
|
#include "constants/event_objects.h"
|
||||||
#include "constants/map_scripts.h"
|
#include "constants/map_scripts.h"
|
||||||
@ -50,6 +52,8 @@ void InitScriptContext(struct ScriptContext *ctx, void *cmdTable, void *cmdTable
|
|||||||
|
|
||||||
for (i = 0; i < (int)ARRAY_COUNT(ctx->stack); i++)
|
for (i = 0; i < (int)ARRAY_COUNT(ctx->stack); i++)
|
||||||
ctx->stack[i] = NULL;
|
ctx->stack[i] = NULL;
|
||||||
|
|
||||||
|
ctx->breakOnTrainerBattle = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 SetupBytecodeScript(struct ScriptContext *ctx, const u8 *ptr)
|
u8 SetupBytecodeScript(struct ScriptContext *ctx, const u8 *ptr)
|
||||||
@ -258,6 +262,14 @@ void ScriptContext_SetupScript(const u8 *ptr)
|
|||||||
sGlobalScriptContextStatus = CONTEXT_RUNNING;
|
sGlobalScriptContextStatus = CONTEXT_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Moves a script from a local context to the global context and enables it.
|
||||||
|
void ScriptContext_ContinueScript(struct ScriptContext *ctx)
|
||||||
|
{
|
||||||
|
sGlobalScriptContext = *ctx;
|
||||||
|
LockPlayerFieldControls();
|
||||||
|
sGlobalScriptContextStatus = CONTEXT_RUNNING;
|
||||||
|
}
|
||||||
|
|
||||||
// Puts the script into waiting mode; usually called from a wait* script command.
|
// Puts the script into waiting mode; usually called from a wait* script command.
|
||||||
void ScriptContext_Stop(void)
|
void ScriptContext_Stop(void)
|
||||||
{
|
{
|
||||||
@ -281,7 +293,7 @@ void RunScriptImmediately(const u8 *ptr)
|
|||||||
while (RunScriptCommand(&sImmediateScriptContext) == TRUE);
|
while (RunScriptCommand(&sImmediateScriptContext) == TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *MapHeaderGetScriptTable(u8 tag)
|
const u8 *MapHeaderGetScriptTable(u8 tag)
|
||||||
{
|
{
|
||||||
const u8 *mapScripts = gMapHeader.mapScripts;
|
const u8 *mapScripts = gMapHeader.mapScripts;
|
||||||
|
|
||||||
@ -303,14 +315,18 @@ u8 *MapHeaderGetScriptTable(u8 tag)
|
|||||||
|
|
||||||
void MapHeaderRunScriptType(u8 tag)
|
void MapHeaderRunScriptType(u8 tag)
|
||||||
{
|
{
|
||||||
u8 *ptr = MapHeaderGetScriptTable(tag);
|
const u8 *ptr = MapHeaderGetScriptTable(tag);
|
||||||
if (ptr)
|
if (ptr)
|
||||||
RunScriptImmediately(ptr);
|
{
|
||||||
|
struct ScriptContext ctx;
|
||||||
|
if (RunScriptImmediatelyUntilEffect(SCREFF_V1 | SCREFF_HARDWARE, ptr, &ctx))
|
||||||
|
ScriptContext_ContinueScript(&ctx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 *MapHeaderCheckScriptTable(u8 tag)
|
const u8 *MapHeaderCheckScriptTable(u8 tag)
|
||||||
{
|
{
|
||||||
u8 *ptr = MapHeaderGetScriptTable(tag);
|
const u8 *ptr = MapHeaderGetScriptTable(tag);
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -332,7 +348,12 @@ u8 *MapHeaderCheckScriptTable(u8 tag)
|
|||||||
|
|
||||||
// Run map script if vars are equal
|
// Run map script if vars are equal
|
||||||
if (VarGet(varIndex1) == VarGet(varIndex2))
|
if (VarGet(varIndex1) == VarGet(varIndex2))
|
||||||
return T2_READ_PTR(ptr);
|
{
|
||||||
|
const u8 *mapScript = T2_READ_PTR(ptr);
|
||||||
|
if (!Script_HasNoEffect(mapScript))
|
||||||
|
return mapScript;
|
||||||
|
}
|
||||||
|
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -364,7 +385,7 @@ void RunOnDiveWarpMapScript(void)
|
|||||||
|
|
||||||
bool8 TryRunOnFrameMapScript(void)
|
bool8 TryRunOnFrameMapScript(void)
|
||||||
{
|
{
|
||||||
u8 *ptr = MapHeaderCheckScriptTable(MAP_SCRIPT_ON_FRAME_TABLE);
|
const u8 *ptr = MapHeaderCheckScriptTable(MAP_SCRIPT_ON_FRAME_TABLE);
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -375,7 +396,7 @@ bool8 TryRunOnFrameMapScript(void)
|
|||||||
|
|
||||||
void TryRunOnWarpIntoMapScript(void)
|
void TryRunOnWarpIntoMapScript(void)
|
||||||
{
|
{
|
||||||
u8 *ptr = MapHeaderCheckScriptTable(MAP_SCRIPT_ON_WARP_INTO_MAP_TABLE);
|
const u8 *ptr = MapHeaderCheckScriptTable(MAP_SCRIPT_ON_WARP_INTO_MAP_TABLE);
|
||||||
if (ptr)
|
if (ptr)
|
||||||
RunScriptImmediately(ptr);
|
RunScriptImmediately(ptr);
|
||||||
}
|
}
|
||||||
@ -504,3 +525,116 @@ void InitRamScript_NoObjectEvent(u8 *script, u16 scriptSize)
|
|||||||
InitRamScript(script, scriptSize, MAP_GROUP(UNDEFINED), MAP_NUM(UNDEFINED), NO_OBJECT);
|
InitRamScript(script, scriptSize, MAP_GROUP(UNDEFINED), MAP_NUM(UNDEFINED), NO_OBJECT);
|
||||||
#endif //FREE_MYSTERY_EVENT_BUFFERS
|
#endif //FREE_MYSTERY_EVENT_BUFFERS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool8 LoadTrainerObjectScript(void)
|
||||||
|
{
|
||||||
|
sGlobalScriptContext.scriptPtr = gApproachingTrainers[gNoOfApproachingTrainers - 1].trainerScriptPtr;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ScriptEffectContext {
|
||||||
|
u32 breakOn;
|
||||||
|
intptr_t breakTo[5];
|
||||||
|
const u8 *nextCmd;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ScriptEffectContext *gScriptEffectContext = NULL;
|
||||||
|
|
||||||
|
static bool32 Script_IsEffectInstrumentedCommand(ScrCmdFunc func)
|
||||||
|
{
|
||||||
|
// In ROM mirror 1.
|
||||||
|
return (((uintptr_t)func) & 0xE000000) == 0xA000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 'setjmp' and 'longjmp' cause link errors, so we use
|
||||||
|
* '__builtin_setjmp' and '__builtin_longjmp' instead.
|
||||||
|
* See https://gcc.gnu.org/onlinedocs/gcc/Nonlocal-Gotos.html */
|
||||||
|
static bool32 RunScriptImmediatelyUntilEffect_InternalLoop(struct ScriptContext *ctx)
|
||||||
|
{
|
||||||
|
if (__builtin_setjmp(gScriptEffectContext->breakTo) == 0)
|
||||||
|
{
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
u32 cmdCode;
|
||||||
|
ScrCmdFunc *func;
|
||||||
|
|
||||||
|
gScriptEffectContext->nextCmd = ctx->scriptPtr;
|
||||||
|
|
||||||
|
if (!ctx->scriptPtr)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
cmdCode = *ctx->scriptPtr;
|
||||||
|
ctx->scriptPtr++;
|
||||||
|
func = &ctx->cmdTable[cmdCode];
|
||||||
|
|
||||||
|
// Invalid script command.
|
||||||
|
if (func >= ctx->cmdTableEnd)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (!Script_IsEffectInstrumentedCommand(*func))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
// Command which waits for a frame.
|
||||||
|
if ((*func)(ctx))
|
||||||
|
{
|
||||||
|
gScriptEffectContext->nextCmd = ctx->scriptPtr;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script_GotoBreak_Internal(void)
|
||||||
|
{
|
||||||
|
__builtin_longjmp(gScriptEffectContext->breakTo, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool32 RunScriptImmediatelyUntilEffect_Internal(u32 effects, const u8 *ptr, struct ScriptContext *ctx)
|
||||||
|
{
|
||||||
|
bool32 result;
|
||||||
|
struct ScriptEffectContext seCtx;
|
||||||
|
seCtx.breakOn = effects & 0x7FFFFFFF;
|
||||||
|
|
||||||
|
if (ctx == NULL)
|
||||||
|
ctx = &sImmediateScriptContext;
|
||||||
|
|
||||||
|
InitScriptContext(ctx, gScriptCmdTable, gScriptCmdTableEnd);
|
||||||
|
if (effects & SCREFF_TRAINERBATTLE)
|
||||||
|
ctx->breakOnTrainerBattle = TRUE;
|
||||||
|
SetupBytecodeScript(ctx, ptr);
|
||||||
|
|
||||||
|
rng_value_t rngValue = gRngValue;
|
||||||
|
gScriptEffectContext = &seCtx;
|
||||||
|
result = RunScriptImmediatelyUntilEffect_InternalLoop(ctx);
|
||||||
|
gScriptEffectContext = NULL;
|
||||||
|
gRngValue = rngValue;
|
||||||
|
|
||||||
|
if (result)
|
||||||
|
ctx->scriptPtr = seCtx.nextCmd;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool32 Script_HasNoEffect(const u8 *ptr)
|
||||||
|
{
|
||||||
|
return !RunScriptImmediatelyUntilEffect(SCREFF_V1 | SCREFF_SAVE | SCREFF_HARDWARE, ptr, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script_RequestEffects_Internal(u32 effects)
|
||||||
|
{
|
||||||
|
if (gScriptEffectContext->breakOn & effects)
|
||||||
|
__builtin_longjmp(gScriptEffectContext->breakTo, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script_RequestWriteVar_Internal(u32 varId)
|
||||||
|
{
|
||||||
|
if (varId == 0)
|
||||||
|
return;
|
||||||
|
if (SPECIAL_VARS_START <= varId && varId <= SPECIAL_VARS_END)
|
||||||
|
return;
|
||||||
|
Script_RequestEffects(SCREFF_V1 | SCREFF_SAVE);
|
||||||
|
}
|
||||||
|
|||||||
@ -240,6 +240,9 @@ void CanHyperTrain(struct ScriptContext *ctx)
|
|||||||
{
|
{
|
||||||
u32 stat = ScriptReadByte(ctx);
|
u32 stat = ScriptReadByte(ctx);
|
||||||
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
|
||||||
if (stat < NUM_STATS
|
if (stat < NUM_STATS
|
||||||
&& partyIndex < PARTY_SIZE
|
&& partyIndex < PARTY_SIZE
|
||||||
&& !GetMonData(&gPlayerParty[partyIndex], MON_DATA_HYPER_TRAINED_HP + stat)
|
&& !GetMonData(&gPlayerParty[partyIndex], MON_DATA_HYPER_TRAINED_HP + stat)
|
||||||
@ -257,6 +260,9 @@ void HyperTrain(struct ScriptContext *ctx)
|
|||||||
{
|
{
|
||||||
u32 stat = ScriptReadByte(ctx);
|
u32 stat = ScriptReadByte(ctx);
|
||||||
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1 | SCREFF_SAVE);
|
||||||
|
|
||||||
if (stat < NUM_STATS && partyIndex < PARTY_SIZE)
|
if (stat < NUM_STATS && partyIndex < PARTY_SIZE)
|
||||||
{
|
{
|
||||||
bool32 data = TRUE;
|
bool32 data = TRUE;
|
||||||
@ -268,6 +274,9 @@ void HyperTrain(struct ScriptContext *ctx)
|
|||||||
void HasGigantamaxFactor(struct ScriptContext *ctx)
|
void HasGigantamaxFactor(struct ScriptContext *ctx)
|
||||||
{
|
{
|
||||||
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
|
||||||
if (partyIndex < PARTY_SIZE)
|
if (partyIndex < PARTY_SIZE)
|
||||||
gSpecialVar_Result = GetMonData(&gPlayerParty[partyIndex], MON_DATA_GIGANTAMAX_FACTOR);
|
gSpecialVar_Result = GetMonData(&gPlayerParty[partyIndex], MON_DATA_GIGANTAMAX_FACTOR);
|
||||||
else
|
else
|
||||||
@ -278,6 +287,8 @@ void ToggleGigantamaxFactor(struct ScriptContext *ctx)
|
|||||||
{
|
{
|
||||||
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1 | SCREFF_SAVE);
|
||||||
|
|
||||||
gSpecialVar_Result = FALSE;
|
gSpecialVar_Result = FALSE;
|
||||||
|
|
||||||
if (partyIndex < PARTY_SIZE)
|
if (partyIndex < PARTY_SIZE)
|
||||||
@ -298,6 +309,8 @@ void CheckTeraType(struct ScriptContext *ctx)
|
|||||||
{
|
{
|
||||||
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
|
||||||
gSpecialVar_Result = TYPE_NONE;
|
gSpecialVar_Result = TYPE_NONE;
|
||||||
|
|
||||||
if (partyIndex < PARTY_SIZE)
|
if (partyIndex < PARTY_SIZE)
|
||||||
@ -309,6 +322,8 @@ void SetTeraType(struct ScriptContext *ctx)
|
|||||||
u32 type = ScriptReadByte(ctx);
|
u32 type = ScriptReadByte(ctx);
|
||||||
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
u32 partyIndex = VarGet(ScriptReadHalfword(ctx));
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1 | SCREFF_SAVE);
|
||||||
|
|
||||||
if (type < NUMBER_OF_MON_TYPES && partyIndex < PARTY_SIZE)
|
if (type < NUMBER_OF_MON_TYPES && partyIndex < PARTY_SIZE)
|
||||||
SetMonData(&gPlayerParty[partyIndex], MON_DATA_TERA_TYPE, &type);
|
SetMonData(&gPlayerParty[partyIndex], MON_DATA_TERA_TYPE, &type);
|
||||||
}
|
}
|
||||||
@ -542,6 +557,11 @@ void ScrCmd_createmon(struct ScriptContext *ctx)
|
|||||||
u8 ivs[NUM_STATS] = {hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv};
|
u8 ivs[NUM_STATS] = {hpIv, atkIv, defIv, speedIv, spAtkIv, spDefIv};
|
||||||
u16 moves[MAX_MON_MOVES] = {move1, move2, move3, move4};
|
u16 moves[MAX_MON_MOVES] = {move1, move2, move3, move4};
|
||||||
|
|
||||||
|
if (side == 0)
|
||||||
|
Script_RequestEffects(SCREFF_V1 | SCREFF_SAVE);
|
||||||
|
else
|
||||||
|
Script_RequestEffects(SCREFF_V1);
|
||||||
|
|
||||||
gSpecialVar_Result = ScriptGiveMonParameterized(side, slot, species, level, item, ball, nature, abilityNum, gender, evs, ivs, moves, isShiny, ggMaxFactor, teraType);
|
gSpecialVar_Result = ScriptGiveMonParameterized(side, slot, species, level, item, ball, nature, abilityNum, gender, evs, ivs, moves, isShiny, ggMaxFactor, teraType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -580,6 +600,8 @@ void Script_SetStatus1(struct ScriptContext *ctx)
|
|||||||
u32 status1 = VarGet(ScriptReadHalfword(ctx));
|
u32 status1 = VarGet(ScriptReadHalfword(ctx));
|
||||||
u32 slot = VarGet(ScriptReadHalfword(ctx));
|
u32 slot = VarGet(ScriptReadHalfword(ctx));
|
||||||
|
|
||||||
|
Script_RequestEffects(SCREFF_V1 | SCREFF_SAVE);
|
||||||
|
|
||||||
if (slot >= PARTY_SIZE)
|
if (slot >= PARTY_SIZE)
|
||||||
{
|
{
|
||||||
u16 species;
|
u16 species;
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include "battle_setup.h"
|
#include "battle_setup.h"
|
||||||
#include "event_data.h"
|
#include "event_data.h"
|
||||||
#include "event_object_movement.h"
|
#include "event_object_movement.h"
|
||||||
|
#include "event_scripts.h"
|
||||||
#include "field_effect.h"
|
#include "field_effect.h"
|
||||||
#include "field_player_avatar.h"
|
#include "field_player_avatar.h"
|
||||||
#include "pokemon.h"
|
#include "pokemon.h"
|
||||||
@ -375,6 +376,16 @@ bool8 CheckForTrainersWantingBattle(void)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
numTrainers = CheckTrainer(i);
|
numTrainers = CheckTrainer(i);
|
||||||
|
if (numTrainers == 0xFF) // non-trainerbatle script
|
||||||
|
{
|
||||||
|
u32 objectEventId = gApproachingTrainers[gNoOfApproachingTrainers - 1].objectEventId;
|
||||||
|
gSelectedObjectEvent = objectEventId;
|
||||||
|
gSpecialVar_LastTalked = gObjectEvents[objectEventId].localId;
|
||||||
|
ScriptContext_SetupScript(EventScript_ObjectApproachPlayer);
|
||||||
|
LockPlayerFieldControls();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (numTrainers == 2)
|
if (numTrainers == 2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -417,14 +428,33 @@ bool8 CheckForTrainersWantingBattle(void)
|
|||||||
|
|
||||||
static u8 CheckTrainer(u8 objectEventId)
|
static u8 CheckTrainer(u8 objectEventId)
|
||||||
{
|
{
|
||||||
const u8 *scriptPtr;
|
const u8 *scriptPtr, *trainerBattlePtr;
|
||||||
u8 numTrainers = 1;
|
u8 numTrainers = 1;
|
||||||
u8 approachDistance;
|
|
||||||
|
u8 approachDistance = GetTrainerApproachDistance(&gObjectEvents[objectEventId]);
|
||||||
|
if (approachDistance == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (InTrainerHill() == TRUE)
|
if (InTrainerHill() == TRUE)
|
||||||
scriptPtr = GetTrainerHillTrainerScript();
|
{
|
||||||
|
trainerBattlePtr = scriptPtr = GetTrainerHillTrainerScript();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
scriptPtr = GetObjectEventScriptPointerByObjectEventId(objectEventId);
|
{
|
||||||
|
trainerBattlePtr = scriptPtr = GetObjectEventScriptPointerByObjectEventId(objectEventId);
|
||||||
|
struct ScriptContext ctx;
|
||||||
|
if (RunScriptImmediatelyUntilEffect(SCREFF_V1 | SCREFF_SAVE | SCREFF_HARDWARE | SCREFF_TRAINERBATTLE, scriptPtr, &ctx))
|
||||||
|
{
|
||||||
|
if (*ctx.scriptPtr == 0x5c) // trainerbattle
|
||||||
|
trainerBattlePtr = ctx.scriptPtr;
|
||||||
|
else
|
||||||
|
trainerBattlePtr = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0; // no effect
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (InBattlePyramid())
|
if (InBattlePyramid())
|
||||||
{
|
{
|
||||||
@ -436,25 +466,28 @@ static u8 CheckTrainer(u8 objectEventId)
|
|||||||
if (GetHillTrainerFlag(objectEventId))
|
if (GetHillTrainerFlag(objectEventId))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else
|
else if (trainerBattlePtr)
|
||||||
{
|
{
|
||||||
if (GetTrainerFlagFromScriptPointer(scriptPtr))
|
if (GetTrainerFlagFromScriptPointer(trainerBattlePtr))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
approachDistance = GetTrainerApproachDistance(&gObjectEvents[objectEventId]);
|
|
||||||
|
|
||||||
if (approachDistance != 0)
|
|
||||||
{
|
{
|
||||||
if (scriptPtr[1] == TRAINER_BATTLE_DOUBLE
|
numTrainers = 0xFF;
|
||||||
|| scriptPtr[1] == TRAINER_BATTLE_REMATCH_DOUBLE
|
}
|
||||||
|| scriptPtr[1] == TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE)
|
|
||||||
|
if (trainerBattlePtr)
|
||||||
|
{
|
||||||
|
if (trainerBattlePtr[1] == TRAINER_BATTLE_DOUBLE
|
||||||
|
|| trainerBattlePtr[1] == TRAINER_BATTLE_REMATCH_DOUBLE
|
||||||
|
|| trainerBattlePtr[1] == TRAINER_BATTLE_CONTINUE_SCRIPT_DOUBLE)
|
||||||
{
|
{
|
||||||
if (GetMonsStateToDoubles_2() != PLAYER_HAS_TWO_USABLE_MONS)
|
if (GetMonsStateToDoubles_2() != PLAYER_HAS_TWO_USABLE_MONS)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
numTrainers = 2;
|
numTrainers = 2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gApproachingTrainers[gNoOfApproachingTrainers].objectEventId = objectEventId;
|
gApproachingTrainers[gNoOfApproachingTrainers].objectEventId = objectEventId;
|
||||||
gApproachingTrainers[gNoOfApproachingTrainers].trainerScriptPtr = scriptPtr;
|
gApproachingTrainers[gNoOfApproachingTrainers].trainerScriptPtr = scriptPtr;
|
||||||
@ -463,9 +496,6 @@ static u8 CheckTrainer(u8 objectEventId)
|
|||||||
gNoOfApproachingTrainers++;
|
gNoOfApproachingTrainers++;
|
||||||
|
|
||||||
return numTrainers;
|
return numTrainers;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 GetTrainerApproachDistance(struct ObjectEvent *trainerObj)
|
static u8 GetTrainerApproachDistance(struct ObjectEvent *trainerObj)
|
||||||
|
|||||||
116
test/script.c
Normal file
116
test/script.c
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#include "global.h"
|
||||||
|
#include "test/test.h"
|
||||||
|
#include "test/overworld_script.h"
|
||||||
|
#include "script.h"
|
||||||
|
#include "constants/decorations.h"
|
||||||
|
#include "constants/moves.h"
|
||||||
|
|
||||||
|
TEST("Script_HasNoEffect control flow")
|
||||||
|
{
|
||||||
|
const u8 *script = OVERWORLD_SCRIPT(
|
||||||
|
nop;
|
||||||
|
nop1;
|
||||||
|
checkflag FLAG_TEMP_1;
|
||||||
|
checktrainerflag 0;
|
||||||
|
compare VAR_TEMP_0, 0;
|
||||||
|
goto_if_eq GoneTo;
|
||||||
|
GoneTo:
|
||||||
|
call Sub;
|
||||||
|
call_if_eq Sub;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Sub:
|
||||||
|
goto SubRet;
|
||||||
|
SubRet:
|
||||||
|
return;
|
||||||
|
);
|
||||||
|
EXPECT(Script_HasNoEffect(script));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST("Script_HasNoEffect variables")
|
||||||
|
{
|
||||||
|
// Writes to special variables are not considered player-visible
|
||||||
|
// because their values are indeterminate if the player has control.
|
||||||
|
const u8 *writeSpecial = OVERWORLD_SCRIPT(
|
||||||
|
setvar VAR_0x8000, 1;
|
||||||
|
addvar VAR_0x8000, 1;
|
||||||
|
subvar VAR_0x8000, VAR_TEMP_0;
|
||||||
|
copyvar VAR_0x8000, VAR_TEMP_0;
|
||||||
|
setorcopyvar VAR_0x8000, VAR_TEMP_0;
|
||||||
|
specialvar VAR_RESULT, GetPlayerFacingDirection;
|
||||||
|
getplayerxy VAR_0x8000, VAR_0x8001;
|
||||||
|
getpartysize;
|
||||||
|
checkitemspace ITEM_POTION, 1;
|
||||||
|
checkitem ITEM_POTION, 1;
|
||||||
|
checkitemtype ITEM_POTION;
|
||||||
|
checkpcitem ITEM_POTION, 1;
|
||||||
|
checkdecorspace DECOR_SNORLAX_DOLL;
|
||||||
|
checkdecor DECOR_SNORLAX_DOLL;
|
||||||
|
checkpartymove MOVE_CELEBRATE;
|
||||||
|
random 2;
|
||||||
|
checkmoney 5000;
|
||||||
|
getpokenewsactive POKENEWS_LILYCOVE;
|
||||||
|
checkplayergender;
|
||||||
|
checkcoins VAR_RESULT;
|
||||||
|
checkmodernfatefulencounter 0;
|
||||||
|
end;
|
||||||
|
);
|
||||||
|
|
||||||
|
// Writes to other variables are considered player-visible because
|
||||||
|
// their values are preserved even while the player has control.
|
||||||
|
const u8 *setVariable = OVERWORLD_SCRIPT(
|
||||||
|
setvar VAR_TEMP_0, 1;
|
||||||
|
end;
|
||||||
|
);
|
||||||
|
|
||||||
|
const u8 *addVariable = OVERWORLD_SCRIPT(
|
||||||
|
addvar VAR_TEMP_0, 1;
|
||||||
|
end;
|
||||||
|
);
|
||||||
|
|
||||||
|
const u8 *subVariable = OVERWORLD_SCRIPT(
|
||||||
|
subvar VAR_TEMP_0, 1;
|
||||||
|
end;
|
||||||
|
);
|
||||||
|
|
||||||
|
const u8 *copyVariable = OVERWORLD_SCRIPT(
|
||||||
|
copyvar VAR_TEMP_0, VAR_RESULT;
|
||||||
|
end;
|
||||||
|
);
|
||||||
|
|
||||||
|
const u8 *setorcopyVariable = OVERWORLD_SCRIPT(
|
||||||
|
setorcopyvar VAR_TEMP_0, VAR_RESULT;
|
||||||
|
end;
|
||||||
|
);
|
||||||
|
|
||||||
|
const u8 *specialvarVariable = OVERWORLD_SCRIPT(
|
||||||
|
specialvar VAR_TEMP_0, GetPlayerFacingDirection;
|
||||||
|
end;
|
||||||
|
);
|
||||||
|
|
||||||
|
const u8 *getPlayerXYVariable1 = OVERWORLD_SCRIPT(
|
||||||
|
getplayerxy VAR_TEMP_0, VAR_RESULT;
|
||||||
|
end;
|
||||||
|
);
|
||||||
|
|
||||||
|
const u8 *getPlayerXYVariable2 = OVERWORLD_SCRIPT(
|
||||||
|
getplayerxy VAR_RESULT, VAR_TEMP_0;
|
||||||
|
end;
|
||||||
|
);
|
||||||
|
|
||||||
|
const u8 *checkCoinsVariable = OVERWORLD_SCRIPT(
|
||||||
|
checkcoins VAR_TEMP_0;
|
||||||
|
end;
|
||||||
|
);
|
||||||
|
|
||||||
|
EXPECT(Script_HasNoEffect(writeSpecial));
|
||||||
|
EXPECT(!Script_HasNoEffect(setVariable));
|
||||||
|
EXPECT(!Script_HasNoEffect(addVariable));
|
||||||
|
EXPECT(!Script_HasNoEffect(subVariable));
|
||||||
|
EXPECT(!Script_HasNoEffect(copyVariable));
|
||||||
|
EXPECT(!Script_HasNoEffect(setorcopyVariable));
|
||||||
|
EXPECT(!Script_HasNoEffect(specialvarVariable));
|
||||||
|
EXPECT(!Script_HasNoEffect(getPlayerXYVariable1));
|
||||||
|
EXPECT(!Script_HasNoEffect(getPlayerXYVariable2));
|
||||||
|
EXPECT(!Script_HasNoEffect(checkCoinsVariable));
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user