mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
ACS_Execute, ACS_ExecuteAlways: handle map stringargs
This commit is contained in:
parent
e4fde7735e
commit
adb3eb7463
3 changed files with 82 additions and 37 deletions
|
|
@ -11,11 +11,14 @@
|
||||||
/// \file interface.cpp
|
/// \file interface.cpp
|
||||||
/// \brief Action Code Script: Interface for the rest of SRB2's game logic
|
/// \brief Action Code Script: Interface for the rest of SRB2's game logic
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <istream>
|
#include <istream>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include <tcb/span.hpp>
|
||||||
|
|
||||||
#include "acsvm.hpp"
|
#include "acsvm.hpp"
|
||||||
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
|
|
@ -347,31 +350,63 @@ void ACS_Tick(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
boolean ACS_Execute(const char *name, const INT32 *args, size_t numArgs, activator_t *activator)
|
static std::vector<ACSVM::Word> ACS_MixArgs(tcb::span<const INT32> args, tcb::span<const char* const> stringArgs)
|
||||||
|
|
||||||
See header file for description.
|
Convert strings to ACS arguments and position them
|
||||||
|
correctly among integer arguments.
|
||||||
|
|
||||||
|
Input Arguments:-
|
||||||
|
args: Integer arguments.
|
||||||
|
stringArgs: C string arguments.
|
||||||
|
|
||||||
|
Return:-
|
||||||
|
Final argument vector.
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
boolean ACS_Execute(const char *name, const INT32 *args, size_t numArgs, activator_t *activator)
|
static std::vector<ACSVM::Word> ACS_MixArgs(tcb::span<const INT32> args, tcb::span<const char* const> stringArgs)
|
||||||
{
|
{
|
||||||
Environment *env = &ACSEnv;
|
std::vector<ACSVM::Word> argV;
|
||||||
|
size_t first = std::min(args.size(), stringArgs.size());
|
||||||
|
|
||||||
ACSVM::GlobalScope *const global = env->getGlobalScope(0);
|
auto new_string = [env = &ACSEnv](const char* str) -> ACSVM::Word { return ~env->getString(str, strlen(str))->idx; };
|
||||||
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};
|
for (size_t i = 0; i < first; ++i)
|
||||||
|
{
|
||||||
|
// args[i] must be 0.
|
||||||
|
//
|
||||||
|
// If ACS_Execute is called from ACS, stringargs[i]
|
||||||
|
// will always be set, because there is no
|
||||||
|
// differentiation between integers and strings on
|
||||||
|
// arguments passed to a function. In this case,
|
||||||
|
// string arguments already exist in the ACS string
|
||||||
|
// table beforehand (and set in args[i]), so no
|
||||||
|
// conversion is required here.
|
||||||
|
//
|
||||||
|
// If ACS_Execute is called from a map line special,
|
||||||
|
// args[i] may be left unset (0), while stringArgs[i]
|
||||||
|
// is set. In this case, conversion to ACS string
|
||||||
|
// table is necessary.
|
||||||
|
argV.push_back(!args[i] && stringArgs[i] ? new_string(stringArgs[i]) : args[i]);
|
||||||
|
}
|
||||||
|
|
||||||
ACSVM::String *script = env->getString(name, strlen(name));
|
for (size_t i = first; i < args.size(); ++i)
|
||||||
return map->scriptStart(script, scope, {reinterpret_cast<const ACSVM::Word *>(args), numArgs, &info});
|
{
|
||||||
|
argV.push_back(args[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = first; i < stringArgs.size(); ++i)
|
||||||
|
{
|
||||||
|
argV.push_back(new_string(stringArgs[i] ? stringArgs[i] : ""));
|
||||||
|
}
|
||||||
|
|
||||||
|
return argV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
boolean ACS_ExecuteAlways(const char *name, const INT32 *args, size_t numArgs, activator_t *activator)
|
boolean ACS_Execute(const char *name, const INT32 *args, size_t numArgs, const char *const *stringArgs, size_t numStringArgs, activator_t *activator)
|
||||||
|
|
||||||
See header file for description.
|
See header file for description.
|
||||||
--------------------------------------------------*/
|
--------------------------------------------------*/
|
||||||
boolean ACS_ExecuteAlways(const char *name, const INT32 *args, size_t numArgs, activator_t *activator)
|
boolean ACS_Execute(const char *name, const INT32 *args, size_t numArgs, const char *const *stringArgs, size_t numStringArgs, activator_t *activator)
|
||||||
{
|
{
|
||||||
Environment *env = &ACSEnv;
|
Environment *env = &ACSEnv;
|
||||||
|
|
||||||
|
|
@ -383,7 +418,29 @@ boolean ACS_ExecuteAlways(const char *name, const INT32 *args, size_t numArgs, a
|
||||||
ThreadInfo info{activator};
|
ThreadInfo info{activator};
|
||||||
|
|
||||||
ACSVM::String *script = env->getString(name, strlen(name));
|
ACSVM::String *script = env->getString(name, strlen(name));
|
||||||
return map->scriptStartForced(script, scope, {reinterpret_cast<const ACSVM::Word *>(args), numArgs, &info});
|
std::vector<ACSVM::Word> argV = ACS_MixArgs(tcb::span {args, numArgs}, tcb::span {stringArgs, numStringArgs});
|
||||||
|
return map->scriptStart(script, scope, {argV.data(), argV.size(), &info});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*--------------------------------------------------
|
||||||
|
boolean ACS_ExecuteAlways(const char *name, const INT32 *args, size_t numArgs, const char *const *stringArgs, size_t numStringArgs, activator_t *activator)
|
||||||
|
|
||||||
|
See header file for description.
|
||||||
|
--------------------------------------------------*/
|
||||||
|
boolean ACS_ExecuteAlways(const char *name, const INT32 *args, size_t numArgs, const char *const *stringArgs, size_t numStringArgs, 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));
|
||||||
|
std::vector<ACSVM::Word> argV = ACS_MixArgs(tcb::span {args, numArgs}, tcb::span {stringArgs, numStringArgs});
|
||||||
|
return map->scriptStartForced(script, scope, {argV.data(), argV.size(), &info});
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,7 @@ void ACS_Tick(void);
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
boolean ACS_Execute(const char *name, const INT32 *args, size_t numArgs, activator_t *activator);
|
boolean ACS_Execute(const INT32 *args, size_t numArgs, const char *const *stringArgs, size_t numStringArgs, activator_t *activator);
|
||||||
|
|
||||||
Runs an ACS script by its string name.
|
Runs an ACS script by its string name.
|
||||||
Only one instance of the script will run at
|
Only one instance of the script will run at
|
||||||
|
|
@ -213,6 +213,8 @@ void ACS_Tick(void);
|
||||||
Strings should be transformed into
|
Strings should be transformed into
|
||||||
ACSVM string IDs.
|
ACSVM string IDs.
|
||||||
numArgs: Number of input arguments.
|
numArgs: Number of input arguments.
|
||||||
|
stringArgs: Array of input string arguments.
|
||||||
|
numStringArgs: Number of input string arguments.
|
||||||
activator: Container for information on what
|
activator: Container for information on what
|
||||||
activated this script.
|
activated this script.
|
||||||
|
|
||||||
|
|
@ -220,11 +222,11 @@ void ACS_Tick(void);
|
||||||
true if we were able to run the script, otherwise false.
|
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_Execute(const char *name, const INT32 *args, size_t numArgs, const char *const *stringArgs, size_t numStringArgs, activator_t *activator);
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
boolean ACS_ExecuteAlways(const char *name, const INT32 *args, size_t numArgs, activator_t *activator);
|
boolean ACS_ExecuteAlways(const INT32 *args, size_t numArgs, const char *const *stringArgs, size_t numStringArgs, activator_t *activator)
|
||||||
|
|
||||||
Runs an ACS script by its string name.
|
Runs an ACS script by its string name.
|
||||||
If the script is already running, this method
|
If the script is already running, this method
|
||||||
|
|
@ -237,6 +239,8 @@ boolean ACS_Execute(const char *name, const INT32 *args, size_t numArgs, activat
|
||||||
Strings should be transformed into
|
Strings should be transformed into
|
||||||
ACSVM string IDs.
|
ACSVM string IDs.
|
||||||
numArgs: Number of input arguments.
|
numArgs: Number of input arguments.
|
||||||
|
stringArgs: Array of input string arguments.
|
||||||
|
numStringArgs: Number of input string arguments.
|
||||||
activator: Container for information on what
|
activator: Container for information on what
|
||||||
activated this script.
|
activated this script.
|
||||||
|
|
||||||
|
|
@ -244,11 +248,11 @@ boolean ACS_Execute(const char *name, const INT32 *args, size_t numArgs, activat
|
||||||
true if we were able to run the script, otherwise false.
|
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);
|
boolean ACS_ExecuteAlways(const char *name, const INT32 *args, size_t numArgs, const char *const *stringArgs, size_t numStringArgs, activator_t *activator);
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------
|
/*--------------------------------------------------
|
||||||
INT32 ACS_ExecuteResult(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.
|
Runs an ACS script by its string name.
|
||||||
Will return the scripts special result
|
Will return the scripts special result
|
||||||
|
|
|
||||||
20
src/p_spec.c
20
src/p_spec.c
|
|
@ -4307,40 +4307,24 @@ boolean P_ProcessSpecial(activator_t *activator, INT16 special, INT32 *args, cha
|
||||||
|
|
||||||
case 475: // ACS_Execute
|
case 475: // ACS_Execute
|
||||||
{
|
{
|
||||||
INT32 newArgs[NUM_SCRIPT_ARGS-1] = {0};
|
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
if (!stringargs[0])
|
if (!stringargs[0])
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Special type 475: No script name given\n");
|
CONS_Debug(DBG_GAMELOGIC, "Special type 475: No script name given\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1; i < NUM_SCRIPT_ARGS; i++)
|
ACS_Execute(stringargs[0], &args[1], NUM_SCRIPT_ARGS - 1, (const char* const*)&stringargs[1], NUM_SCRIPT_STRINGARGS - 1, activator);
|
||||||
{
|
|
||||||
newArgs[i - 1] = args[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
ACS_Execute(stringargs[0], newArgs, NUM_SCRIPT_ARGS-1, activator);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 476: // ACS_ExecuteAlways
|
case 476: // ACS_ExecuteAlways
|
||||||
{
|
{
|
||||||
INT32 newArgs[NUM_SCRIPT_ARGS-1] = {0};
|
|
||||||
INT32 i;
|
|
||||||
|
|
||||||
if (!stringargs[0])
|
if (!stringargs[0])
|
||||||
{
|
{
|
||||||
CONS_Debug(DBG_GAMELOGIC, "Special type 475: No script name given\n");
|
CONS_Debug(DBG_GAMELOGIC, "Special type 475: No script name given\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 1; i < NUM_SCRIPT_ARGS; i++)
|
ACS_ExecuteAlways(stringargs[0], &args[1], NUM_SCRIPT_ARGS - 1, (const char* const*)&stringargs[1], NUM_SCRIPT_STRINGARGS - 1, activator);
|
||||||
{
|
|
||||||
newArgs[i - 1] = args[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
ACS_ExecuteAlways(stringargs[0], newArgs, NUM_SCRIPT_ARGS-1, activator);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 477: // ACS_Suspend
|
case 477: // ACS_Suspend
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue