mirror of
https://github.com/rh-hideout/pokeemerald-expansion.git
synced 2026-03-21 18:04:50 -05:00
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.
117 lines
3.1 KiB
C
117 lines
3.1 KiB
C
#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));
|
|
}
|