Improve compiling, add ACS_Execute

Arbritrary ACS scripts can now be run from linedef executors. I will be implementing more, non-linedef-executor-related methods in the future.
This commit is contained in:
Sally Coolatta 2022-12-27 17:04:06 -05:00
parent 3135d14387
commit 4ffa63a9c8
7 changed files with 507 additions and 170 deletions

View file

@ -4,7 +4,7 @@
// Compiler settings
compiler = "ringracers_gdcc";
parameters = "@rroptions -I \"%PT\" -I \"%PS\" %FI %FO";
parameters = "--error-file \"acs.err\" --bc-zdacs-script-type lap 5 --include \"%PT\" --include \"%PS\" --output %FO %FI";
resultlump = "BEHAVIOR";
// Editor settings
@ -29,87 +29,228 @@ scripttype = 1; //0 = unknown script, 1 = acc, 2 = modeldef, 3 = decorate
keywords
{
#define = "#Define identifier expression";
#encryptstrings = "#EncryptStrings";
#import = "#Import";
#include = "#Include";
#libdefine = "#LibDefine identifier expression";
#library = "#Library";
#NoCompact = "#NoCompact";
#NoWadAuthor = "#NoWadAuthor";
#WadAuthor = "#WadAuthor";
#region = "#region block";
#endregion = "end of #region block";
ACS_Execute = "ACS_Execute(int script, int arg1, int arg2, int arg3)";
ACS_ExecuteAlways = "ACS_ExecuteAlways(int script, int arg1, int arg2, int arg3)";
ACS_ExecuteWait = "ACS_ExecuteWait(int script, int arg1, int arg2, int arg3)";
ACS_ExecuteWithResult = "ACS_ExecuteWithResult(int script, int arg1, int arg2, int arg3)";
ACS_Suspend = "ACS_Suspend(int script)";
ACS_Terminate = "ACS_Terminate(int script)";
ACS_NamedExecute = "ACS_NamedExecute(str script, int arg1, int arg2, int arg3)";
ACS_NamedExecuteAlways = "ACS_NamedExecuteAlways(str script, int arg1, int arg2, int arg3)";
ACS_NamedExecuteWait = "ACS_NamedExecuteWait(str script, int arg1, int arg2, int arg3)";
ACS_NamedExecuteWithResult = "ACS_ExecuteWithResult(str script, int arg1, int arg2, int arg3)";
ACS_NamedSuspend = "ACS_NamedSuspend(str script)";
ACS_NamedTerminate = "ACS_NamedTerminate(str script)";
ActivatorSound = "ActivatorSound(str name, int volume)";
ActivatorTID = "ActivatorTID()";
Bool = "Bool expression";
Break = "Break";
Return = "Return";
Case = "Case expression:";
Const = "Const";
Continue = "Continue";
Death = "Script expression Death";
Default = "Default:";
Delay = "void Delay(int tics)";
Disconnect = "Script expression Disconnect";
Do = "Do";
Else = "Else";
Enter = "Script expression Enter";
For = "For(initialization, condition, iteration)";
Function = "Function Void expression (Void)";
If = "if(expression)";
Int = "int expression";
Open = "Script expression Open";
PolyWait = "void PolyWait(int polyid)";
Print = "void Print(type:expression)\nPrint will print something to the screen.\nPrint will only display for the activator of the script\nFor printing to all players, use PrintBold.";
PrintBold = "void PrintBold(type:expression)\nThis is exactly the same as Print, except all players will see the printed text\non the screen instead of just the activator of the script.";
Random = "int Random(int min, int max)";
Restart = "Restart";
Script = "Script expression";
ScriptWait = "void ScriptWait(int script)";
Special = "Special";
str = "str expression";
Suspend = "Suspend";
Switch = "Switch(expression)";
TagWait = "void TagWait(int tag)";
Terminate = "Terminate";
Timer = "int Timer(void)";
Unloading = "Script expression Unloading";
Until = "Until(expression)";
Void = "Void";
While = "While(expression)";
World = "World Int expression:identifier";
// Directives
#define = "#define [identifier] [expression]\n"
"Defines a preprocessor macro. Defines can be\n"
"used to create a constant variable which can't\n"
"be changed during run-time.";
#include = "#include [file]"
"Defines a preprocessor macro. Defines can be\n"
"used to create a constant variable which can't\n"
"be changed during run-time.";
#library = "#library [name]\n"
"Defines this file as a library. Other files can\n"
"use #import to include all of this file's scripts,\n"
"functions, and libdefines, without needing to\n"
"compile it into their file.";
#import = "#import [file]\n"
"Adds the scripts, functions, and libdefines from\n"
"an ACS library. Unlike #include, libraries do not\n"
"get compiled directly into your file.\n";
#libdefine = "#libdefine [identifier] [expression]\n"
"Defines a preprocessor macro for a library. Unlike\n"
"normal defines, other files can access this value\n"
"if they import this file as a library.";
#encryptstrings = "#encryptstrings\n"
"Strings will be scrambled when compiling, so that\n"
"they aren't directly readable in a hex editor.";
#nocompact = "#nocompact\n"
"Disables compiler compression.";
#region = "#region\n"
"Starts a collaspable text region for the Script\n"
"Editor. Ignored by the compiler.";
#endregion = "#endregion\n"
"Ends a collaspable text region. See: #region\n"
"Ignored by the compiler.";
// Keywords
if = "if ([expression])";
else = "else";
for = "for ([initialize], [condition], [iterate])";
do = "do";
while = "while ([expression])";
until = "until ([expression])";
break = "break";
continue = "continue";
switch = "switch ([expression])";
case = "case [expression]:";
default = "default:";
const = "const";
function = "function [return type] [identifier] ([arg], [...])";
script = "script [identifier] ([arg], [...])";
return = "return [value]\n"
"Return value for functions.\n"
"Does not work for scripts.";
restart = "restart\n"
"Restarts the current script from the beginning.\n"
"Does not work for functions.";
suspend = "suspend\n"
"Pauses the current script. It can be resumed by\n"
"activating the same script again.\n"
"Does not work for functions.";
terminate = "terminate\n"
"Ends the current script early.\n"
"Does not work for functions.";
special = "special";
world = "world [type] [index]:[identifier]\n"
"Sets a wrapper for a hub scope variable.\n"
"Unused in Ring Racers.";
global = "global [type] [index]:[identifier]\n"
"Sets a wrapper for a global scope variable.\n"
"Unused in Ring Racers.";
// Types
void = "void";
bool = "bool";
int = "int";
str = "str";
// Script modifiers
OPEN = "script [identifier] OPEN\n"
"This script will run when the level is initially loaded.";
ENTER = "script [identifier] ENTER\n"
"Makes this script run whenever a player enters the game.\n"
"The activator is set to said player for this script.";
RESPAWN = "script [identifier] RESPAWN\n"
"Makes this script run whenever a player respawns.\n"
"The activator is set to said player for this script.";
DEATH = "script [identifier] DEATH\n"
"Makes this script run whenever any player dies.\n"
"The activator is set to said player for this script.";
LAP = "script [identifier] LAP\n"
"Makes this script run whenever a player crosses the finish line.\n"
"The activator is set to said player for this script.";
// Specials
// Functions
Delay = "void Delay(int tics)\n"
"Pauses the current script for a period of time.\n"
"Does not work for functions.";
TagWait = "void TagWait(int tag)\n"
"Pauses the current script until the tagged sectors finish moving.\n"
"Does not work for functions.";
PolyWait = "void PolyWait(int polyID)\n"
"Pauses the current script until a PolyObject finishes moving.\n"
"Does not work for functions.";
ScriptWait = "void ScriptWait(str script)\n"
"Pauses the current script until another script finishes.\n"
"Does not work for functions.";
ACS_Execute = "void ACS_Execute(str script, int arg1, ...)\n"
"Run a script. If the script is already running, it will not run again.";
ACS_ExecuteAlways = "void ACS_ExecuteAlways(str script, int arg1, ...)\n"
"Run a script. Unlike ACS_Execute, multiple copies of a script can be run,\n"
"but ACS_Suspend and ACS_Terminate cannot be used on it.";
ACS_ExecuteWait = "void ACS_ExecuteWait(str script, int arg1, ...)\n"
"Run a script, and then pause the current script until it finishes.";
ACS_ExecuteWithResult = "int ACS_ExecuteWithResult(str script, int arg1, ...)\n"
"Run a script, and then returns the special result value.\n"
"The special result value can be set by using SetResultValue().";
ACS_Suspend = "void ACS_Suspend(str script)\n"
"Pauses another script by its numerical ID.\n"
"It can be resumed by activating the same script again.";
ACS_Terminate = "void ACS_Terminate(str script)\n"
"Ends another script early by its numerical ID.";
Random = "int Random(int min, int max)\n"
"Generates a random number between min and max.";
ThingCount = "int ThingCount(str type, int tag)\n"
"Returns the number of objects of the specified type in the map.";
ChangeFloor = "void ChangeFloor(int tag, str texture)\n"
"Changes the floor texture of all of the tagged sectors.";
ChangeCeiling = "void ChangeCeiling(int tag, str texture)\n"
"Changes the ceiling texture of all of the tagged sectors.";
LineSide = "int LineSide(void)\n"
"Returns either LINE_FRONT or LINE_BACK depending on the\n"
"side of the line that activated the script.\n"
"Always returns LINE_FRONT if the line doesn't exist.";
ClearLineSpecial = "void ClearLineSpecial(void)\n"
"Sets the activating line's special to 0, for one-time effects.";
Print = "void Print([type]:[expression], [...])\n"
"Print will display a message to the screen.\n"
"It will only display for the activator of the script.\n"
"For printing to all players, use PrintBold.";
PlayerCount = "int PlayerCount(void)\n"
"Counts the number of players currently playing.";
GameType = "int GameType(void)\n"
"Returns the current gametype ID.";
GameSpeed = "int GameSpeed(void)\n"
"Returns the current game speed.";
Timer = "int Timer(void)\n"
"Returns the number of tics elapsed since the level started.";
SectorSound = "void SectorSound(str sound, int volume)\n"
"Plays a sound effect in the activating sector.";
AmbientSound = "void AmbientSound(str sound, int volume)\n"
"Plays a sound effect globally.";
SetLineTexture = "void SetLineTexture(int tag, int side, int part, str texture)\n"
"Changes the texture for the tagged lines.\n"
"side is either SIDE_FRONT or SIDE_BACK.\n"
"part is either TEXTURE_TOP, TEXTURE_MIDDLE, or TEXTURE_BOTTOM.";
SetLineSpecial = "void SetLineSpecial(int tag, int special, int arg1, ...)\n"
"Changes the special and arguments for the tagged lines.\n"
"special can be set to the actual name of the special.\n"
"Any number of args can be set.";
ThingSound = "void ThingSound(int tag, str sound, int volume)\n"
"Plays a sound effect on the tagged things.";
PrintBold = "void PrintBold([type]:[expression], [...])\n"
"Print will display a message to the screen.\n"
"It will display for all players in the game.\n"
"For printing to only the activator, use Print.";
Log = "void Log([type]:[expression], [...])\n"
"Log will display a message in the console.\n"
"It will display for only the activating player.";
}
constants
{
TRUE;
FALSE;
ON;
OFF;
YES;
NO;
LINE_FRONT;
LINE_BACK;
SIDE_FRONT;
SIDE_BACK;
TEXTURE_TOP;
TEXTURE_MIDDLE;
TEXTURE_BOTTOM;
GAMETYPE_RACE;
GAMETYPE_BATTLE;
GAMESPEED_EASY;
GAMESPEED_NORMAL;
GAMESPEED_HARD;

View file

@ -72,94 +72,97 @@
// [type] [ID]:[function name]([required args], [optional args])
// Currently just implements linedef executors.
// Ideally would implement as many as possible.
special
int 400:Floor_SetHeightTexture(3),
int 400:Sector_CopyHeights(3, 4),
int 402:Light_Copy(2),
int 403:Floor_Move(5),
int 402:Light_Copy(2, 3),
int 403:Sector_CopyHeightsMove(4, 6),
int 405:Floor_MoveByOffset(5),
int 405:Sector_MovePlanes(4, 5),
int 408:Sector_SetFlats(2),
int 409:Sector_ChangeTag(3),
int 410:Line_ChangeFrontSectorTag(2),
int 408:Sector_CopyTextures(3),
int 409:Sector_ChangeTag(2, 3),
int 410:Line_ChangeFrontSectorTag(2, 3),
int 411:Sector_StopMovement(1),
int 412:Thing_Teleport(5),
int 413:Level_SetMusic(1, 7),
int 414:Thing_PlaySound(4),
int 412:Thing_Teleport(1, 5),
int 413:Level_SetMusic(2, 8),
int 414:PlaySFX(1, 4),
int 415:Console_Execute(1),
int 416:Light_Flicker(5),
int 417:Light_Pulse(5),
int 418:Light_BlinkUnsynced(6),
int 419:Light_Blink(6),
int 420:Light_Fade(4),
int 416:Light_Flicker(3, 5),
int 417:Light_Pulse(3, 5),
int 418:Light_Blink(4, 6),
int 420:Light_Fade(3, 4),
int 421:Light_Stop(1),
int 422:Player_CutAwayView(2, 3),
int 422:Camera_CutAwayView(2),
int 423:Level_SetSky(1, 2),
int 424:Level_SetWeather(1, 2),
int 425:Thing_SetState(1),
int 426:Thing_Stop(0, 1),
int 427:Player_AddScore(1),
int 428:FOF_StartMovement(2, 5),
int 429:Sector_Crush(4),
int 429:Sector_Crush(3),
// int 432:Thing_Set2D(1),
int 433:Thing_SetFlip(1),
// int 434:Player_CustomPower(2),
int 435:Scroll_Change(2),
int 435:Sector_ChangeScroll(3),
int 436:FOF_Shatter(2),
int 437:Player_DisableControl(1, 2),
int 438:Thing_SetScale(1),
int 439:Line_CopyTextures(1, 3),
// int 440:Level_StartMetalSonicRace(0),
int 439:Line_CopyTextures(3, 4),
int 440:Level_StartMetalSonicRace(0),
int 441:SetUnlockableTrigger(1),
int 442:Sector_NextThingState(4),
int 443:Lua_Execute(1, 8),
int 442:Sector_NextThingState(3, 4),
int 443:Lua_Execute(1, 12),
int 444:Earthquake(1, 3),
int 445:FOF_SetExists(2, 3),
int 446:FOF_Crumble(2, 3),
int 447:Sector_SetColormap(2, 3),
int 448:SetSkyboxViewpoint(3, 4),
int 449:SetBossActive(1, 2),
int 448:SetSkyboxViewpoints(3, 4),
int 449:SetBossActive(2),
int 450:Line_Execute(1),
int 451:Line_ExecuteRandom(2),
int 452:FOF_SetAlpha(4),
int 453:FOF_Fade(5),
int 452:FOF_SetAlpha(3, 4),
int 453:FOF_Fade(4, 5),
int 454:FOF_StopFade(2, 3),
int 455:Sector_FadeColormap(4),
int 455:Sector_FadeColormap(2, 4),
int 456:Sector_StopColormapFade(1),
int 457:Thing_StartTracking(3, 5),
int 458:Thing_StopTracking(0),
int 459:Prompt_Execute(4),
int 460:Player_AddRings(2, 3),
int 459:Prompt_Execute(2, 4),
int 460:Player_AddRings(1, 3),
int 461:Thing_Spawn(5, 9),
int 462:Level_Stopwatch(0),
int 462:Level_StopClock(0),
int 463:Thing_Dye(1), // color
// int 464:TriggerEggCapsule(1, 2),
int 464:TriggerEggCapsule(1, 2),
int 466:Level_SetFailed(1),
int 467:Sector_SetLight(2, 4),
int 468:Line_SetArg(2, 4),
int 469:Sector_SetGravity(2, 4),
int 475:ACS_Execute(1, 11),
int 476:ACS_ExecuteAlways(1, 11),
int 477:ACS_Suspend(1),
int 478:ACS_Terminate(1),
int 480:Polyobj_DoorSlide(4, 5),
int 481:Polyobj_DoorSwing(3, 4),
int 482:Polyobj_Move(4, 5),
int 484:Polyobj_Rotate(3, 4),
int 488:Polyobj_MoveByWaypoints(3, 5),
int 489:Polyobj_SetVisibilityTangibility(3),
int 480:Polyobj_DoorSlide(5),
int 481:Polyobj_DoorSwing(4),
int 482:Polyobj_Move(4),
int 483:Polyobj_OR_Move(4),
int 484:Polyobj_RotateRight(3),
int 485:Polyobj_OR_RotateRight(3),
int 486:Polyobj_RotateLeft(3),
int 487:Polyobj_OR_RotateLeft(3),
int 488:Polyobj_MoveByWaypoints(4),
int 489:Polyobj_InvisibleIntangible(1, 2),
int 490:Polyobj_VisibleTangible(1, 2),
int 491:Polyobj_SetAlpha(2, 3),
int 492:Polyobj_FadeAlpha(2, 3),
int 492:Polyobj_FadeAlpha(3, 4),
int 499:Sector_ToggleWaypoints(1, 2),
int 499:Sector_ToggleWaypoints(2),
// internal functions have negative values
/*
int -1:GetLineUDMFInt(2, int, str),
fixed -2:GetLineUDMFFixed(2, int, str),
int -3:GetThingUDMFInt(2, int, str),
@ -168,31 +171,7 @@ special
fixed -6:GetSectorUDMFFixed(2, int, str),
int -7:GetSideUDMFInt(3, int, int, str),
fixed -8:GetSideUDMFFixed(3, int, int, str),
int -9:ACS_Execute(1, int, int, int, int),
int -10:ACS_Suspend(1, int),
int -11:ACS_Terminate(1, int),
int -12:ACS_ExecuteWithResult(1, int, int, int, int),
int -13:ACS_NamedExecute(1, str, int, int, int),
int -14:ACS_NamedSuspend(1, str),
int -15:ACS_NamedTerminate(1, str),
int -16:ACS_NamedExecuteWithResult(1, str, int, int, int),
int -17:ACS_NamedExecuteAlways(1, str, int, int, int),
int -18:UniqueTID(0, int, int),
int -19:IsTIDUsed(1, int),
int -20:Sqrt(1, int),
fixed -21:FixedSqrt(1, fixed),
fixed -22:VectorLength(2, fixed, fixed),
int -23:StrCmp(2, str, str, int),
int -24:StrICmp(2, str, str, int),
int -24:StrCaseCmp(2, str, str, int),
str -25:StrLeft(2, str, int),
str -25:StrRight(2, str, int),
str -26:StrMid(3, str, int, int),
int -27:GetChar(2, str, int),
int -28:StrArg(1, str),
fixed -29:Floor(1, fixed),
fixed -30:Round(1, fixed),
fixed -31:Ceil(1, fixed),
*/
void { 2 }:__suspend(void),
@ -230,10 +209,6 @@ special
void {100 }:ThingSound(int, str, int),
void {101 }:EndPrintBold(void),
int {118 }:IsMultiplayer(void),
int {118 }:IsNetworkGame(void),
int {135 }:SinglePlayer(void),
int {136 }:FixedMul(int, int), // 136 to 137: Implemented by ACSVM
int {137 }:FixedDiv(int, int),
@ -247,27 +222,14 @@ special
// 203 to 217: Implemented by ACSVM
fixed {220 }:Sin(fixed),
fixed {221 }:Cos(fixed),
fixed {222 }:VectorAngle(fixed, fixed),
// 225 to 243: Implemented by ACSVM
int {247 }:PlayerNumber(void),
int {248 }:ActivatorTID(void),
int {253 }:StrLen(str), // 253: Implemented by ACSVM
// 256 to 257: Implemented by ACSVM
// 263: Implemented by ACSVM
int {267 }:PlayerInGame(int),
int {268 }:PlayerIsBot(int),
void {349 }:PrintBinary(int),
void {350 }:PrintHex(int),
void {273 }:PrintModuleCharArray(int, int), // 273 to 275: Implemented by ACSVM
void {274 }:PrintWorldCharArray(int, int),
void {275 }:PrintGlobalCharArray(int, int),
@ -278,22 +240,10 @@ special
// 349 to 361: Implemented by ACSVM
str {352 }:EndStrParam(void),
void {353 }:PrintModuleCharRange(int, int, int, int),
void {354 }:PrintWorldCharRange(int, int, int, int),
void {355 }:PrintGlobalCharRange(int, int, int, int),
int {356 }:StrCpyToModuleCharRange(int, int, int, int, str, int),
int {357 }:StrCpyToWorldCharRange(int, int, int, int, str, int),
int {358 }:StrCpyToGlobalCharRange(int, int, int, int, str, int),
void {361 }:NamedScriptWait(str),
// 363 to 380: Implemented by ACSVM
void {378 }:PrintLocalCharArray(int, int),
void {379 }:PrintLocalCharRange(int, int, int, int),
int {380 }:StrCpyToLocalCharRange(int, int, int, int, str, int);
print __Print
(
(begin): BeginPrint,

View file

@ -1,2 +0,0 @@
# Define custom script type names here.
--bc-zdacs-script-type lap 5

View file

@ -27,6 +27,7 @@ extern "C" {
#include <cmath>
#include <memory>
#include <ACSVM/Action.hpp>
#include <ACSVM/Code.hpp>
#include <ACSVM/CodeData.hpp>
#include <ACSVM/Environment.hpp>
@ -233,6 +234,101 @@ void ACS_Tick(void)
}
}
/*--------------------------------------------------
boolean ACS_Execute(const char *name, const INT32 *args, size_t numArgs, activator_t *activator)
See header file for description.
--------------------------------------------------*/
boolean ACS_Execute(const char *name, const INT32 *args, size_t numArgs, activator_t *activator)
{
Environment *env = &ACSEnv;
ACSVM::GlobalScope *const global = env->getGlobalScope(0);
ACSVM::HubScope *const hub = global->getHubScope(0);
ACSVM::MapScope *const map = hub->getMapScope(0);
ACSVM::ScopeID scope{global->id, hub->id, map->id};
ThreadInfo info{activator};
ACSVM::String *script = env->getString(name, strlen(name));
return map->scriptStart(script, scope, {reinterpret_cast<const ACSVM::Word *>(args), numArgs, &info});
}
/*--------------------------------------------------
boolean ACS_ExecuteAlways(const char *name, const INT32 *args, size_t numArgs, activator_t *activator)
See header file for description.
--------------------------------------------------*/
boolean ACS_ExecuteAlways(const char *name, const INT32 *args, size_t numArgs, activator_t *activator)
{
Environment *env = &ACSEnv;
ACSVM::GlobalScope *const global = env->getGlobalScope(0);
ACSVM::HubScope *const hub = global->getHubScope(0);
ACSVM::MapScope *const map = hub->getMapScope(0);
ACSVM::ScopeID scope{global->id, hub->id, map->id};
ThreadInfo info{activator};
ACSVM::String *script = env->getString(name, strlen(name));
return map->scriptStartForced(script, scope, {reinterpret_cast<const ACSVM::Word *>(args), numArgs, &info});
}
/*--------------------------------------------------
boolean ACS_ExecuteResult(const char *name, const INT32 *args, size_t numArgs, activator_t *activator)
See header file for description.
--------------------------------------------------*/
boolean ACS_ExecuteResult(const char *name, const INT32 *args, size_t numArgs, activator_t *activator)
{
Environment *env = &ACSEnv;
ACSVM::GlobalScope *const global = env->getGlobalScope(0);
ACSVM::HubScope *const hub = global->getHubScope(0);
ACSVM::MapScope *const map = hub->getMapScope(0);
ThreadInfo info{activator};
ACSVM::String *script = env->getString(name, strlen(name));
return map->scriptStartResult(script, {reinterpret_cast<const ACSVM::Word *>(args), numArgs, &info});
}
/*--------------------------------------------------
boolean ACS_Suspend(const char *name)
See header file for description.
--------------------------------------------------*/
boolean ACS_Suspend(const char *name)
{
Environment *env = &ACSEnv;
ACSVM::GlobalScope *const global = env->getGlobalScope(0);
ACSVM::HubScope *const hub = global->getHubScope(0);
ACSVM::MapScope *const map = hub->getMapScope(0);
ACSVM::ScopeID scope{global->id, hub->id, map->id};
ACSVM::String *script = env->getString(name, strlen(name));
return map->scriptPause(script, scope);
}
/*--------------------------------------------------
boolean ACS_Terminate(const char *name)
See header file for description.
--------------------------------------------------*/
boolean ACS_Terminate(const char *name)
{
Environment *env = &ACSEnv;
ACSVM::GlobalScope *const global = env->getGlobalScope(0);
ACSVM::HubScope *const hub = global->getHubScope(0);
ACSVM::MapScope *const map = hub->getMapScope(0);
ACSVM::ScopeID scope{global->id, hub->id, map->id};
ACSVM::String *script = env->getString(name, strlen(name));
return map->scriptStop(script, scope);
}
/*--------------------------------------------------
void ACS_Archive(savebuffer_t *save)

View file

@ -113,6 +113,106 @@ void ACS_RunLapScript(mobj_t *mo, line_t *line);
void ACS_Tick(void);
/*--------------------------------------------------
boolean ACS_Execute(const char *name, const INT32 *args, size_t numArgs, activator_t *activator);
Runs an ACS script by its string name.
Only one instance of the script will run at
a time with this method.
Input Arguments:-
name: Script string to run.
args: Array of the input arguments.
Strings should be transformed into
ACSVM string IDs.
numArgs: Number of input arguments.
activator: Container for information on what
activated this script.
Return:-
true if we were able to run the script, otherwise false.
--------------------------------------------------*/
boolean ACS_Execute(const char *name, const INT32 *args, size_t numArgs, activator_t *activator);
/*--------------------------------------------------
boolean ACS_ExecuteAlways(const char *name, const INT32 *args, size_t numArgs, activator_t *activator);
Runs an ACS script by its string name.
If the script is already running, this method
will create another instance of the script.
(Suspend and Terminate cannot be used, however.)
Input Arguments:-
name: Script string to run.
args: Array of the input arguments.
Strings should be transformed into
ACSVM string IDs.
numArgs: Number of input arguments.
activator: Container for information on what
activated this script.
Return:-
true if we were able to run the script, otherwise false.
--------------------------------------------------*/
boolean ACS_ExecuteAlways(const char *name, const INT32 *args, size_t numArgs, activator_t *activator);
/*--------------------------------------------------
INT32 ACS_ExecuteResult(const char *name, const INT32 *args, size_t numArgs, activator_t *activator);
Runs an ACS script by its string name.
Will return the scripts special result
value, if set.
Input Arguments:-
name: Script string to run.
args: Array of the input arguments.
Strings should be transformed into
ACSVM string IDs.
numArgs: Number of input arguments.
activator: Container for information on what
activated this script.
Return:-
true if we were able to run the script, otherwise false.
--------------------------------------------------*/
INT32 ACS_ExecuteResult(const char *name, const INT32 *args, size_t numArgs, activator_t *activator);
/*--------------------------------------------------
boolean ACS_Suspend(const char *name);
Pauses an ACS script by its string name.
Input Arguments:-
name: Script string to pause.
Return:-
true if we were able to pause the script, otherwise false.
--------------------------------------------------*/
boolean ACS_Suspend(const char *name);
/*--------------------------------------------------
boolean ACS_Terminate(const char *name);
Stops an ACS script by its string name.
Input Arguments:-
name: Script string to stop.
Return:-
true if we were able to stop the script, otherwise false.
--------------------------------------------------*/
boolean ACS_Terminate(const char *name);
/*--------------------------------------------------
void ACS_Archive(savebuffer_t *save);

View file

@ -19,6 +19,9 @@ extern "C" {
#include "../doomdef.h"
#include "../doomstat.h"
#include "../p_tick.h"
#include "../r_defs.h"
#include "../r_state.h"
#include "../p_spec.h"
}
#include <ACSVM/Code.hpp>
@ -87,6 +90,17 @@ public:
P_SetTarget(&mo, info.mo);
}
ThreadInfo(const activator_t *activator) :
mo{ nullptr },
line{ activator->line },
side{ activator->side },
sector{ activator->sector },
po{ activator->po },
fromLineSpecial{ static_cast<bool>(activator->fromLineSpecial) }
{
P_SetTarget(&mo, activator->mo);
}
~ThreadInfo()
{
P_SetTarget(&mo, nullptr);
@ -97,6 +111,7 @@ public:
P_SetTarget(&mo, info.mo);
line = info.line;
side = info.side;
sector = info.sector;
po = info.po;
return *this;

View file

@ -2764,7 +2764,7 @@ void P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, char *
mo->player->awayviewtics = args[1];
}
aim = udmf ? altview->spawnpoint->pitch : args[2];
aim = (backwardsCompat) ? args[2] : altview->spawnpoint->pitch;
aim = (aim + 360) % 360;
aim *= (ANGLE_90>>8);
aim /= 90;
@ -3889,7 +3889,7 @@ void P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, char *
case 466: // Set level failure state
{
if (args[1])
if (args[0])
{
stagefailed = false;
CONS_Debug(DBG_GAMELOGIC, "Stage can be completed successfully!\n");
@ -3987,6 +3987,43 @@ void P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, char *
}
break;
case 475:
if (!stringargs[0])
{
CONS_Debug(DBG_GAMELOGIC, "Linedef type 475: No script name given\n");
return;
}
ACS_Execute(stringargs[0], args, NUMLINEARGS, activator);
break;
case 476:
if (!stringargs[0])
{
CONS_Debug(DBG_GAMELOGIC, "Linedef type 476: No script name given\n");
return;
}
ACS_ExecuteAlways(stringargs[0], args, NUMLINEARGS, activator);
break;
case 477:
if (!stringargs[0])
{
CONS_Debug(DBG_GAMELOGIC, "Linedef type 477: No script name given\n");
return;
}
ACS_Suspend(stringargs[0]);
break;
case 478:
if (!stringargs[0])
{
CONS_Debug(DBG_GAMELOGIC, "Linedef type 478: No script name given\n");
return;
}
ACS_Terminate(stringargs[0]);
break;
case 480: // Polyobj_DoorSlide
PolyDoor(args);
break;