diff --git a/extras/conf/RingRacers_ACS.cfg b/extras/conf/RingRacers_ACS.cfg index 9a669635d..1e8351dfe 100644 --- a/extras/conf/RingRacers_ACS.cfg +++ b/extras/conf/RingRacers_ACS.cfg @@ -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; diff --git a/extras/gdcc/inc/ACS/rrspecial.acs b/extras/gdcc/inc/ACS/rrspecial.acs index 46d0f6e4f..246067ad2 100644 --- a/extras/gdcc/inc/ACS/rrspecial.acs +++ b/extras/gdcc/inc/ACS/rrspecial.acs @@ -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, diff --git a/extras/gdcc/rroptions b/extras/gdcc/rroptions deleted file mode 100644 index 2fa0bcbce..000000000 --- a/extras/gdcc/rroptions +++ /dev/null @@ -1,2 +0,0 @@ -# Define custom script type names here. ---bc-zdacs-script-type lap 5 diff --git a/src/acs/interface.cpp b/src/acs/interface.cpp index 6094c430c..7331613a9 100644 --- a/src/acs/interface.cpp +++ b/src/acs/interface.cpp @@ -27,6 +27,7 @@ extern "C" { #include #include +#include #include #include #include @@ -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(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(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(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) diff --git a/src/acs/interface.h b/src/acs/interface.h index 96ca834fa..78c68d575 100644 --- a/src/acs/interface.h +++ b/src/acs/interface.h @@ -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); diff --git a/src/acs/thread.hpp b/src/acs/thread.hpp index 0658f8eed..cb036e057 100644 --- a/src/acs/thread.hpp +++ b/src/acs/thread.hpp @@ -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 @@ -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(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; diff --git a/src/p_spec.c b/src/p_spec.c index 3c431b762..27da1745f 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -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;