mirror of
https://github.com/JezuzLizard/T4SP-Server-Plugin.git
synced 2025-04-19 21:22:54 +00:00
Add script errors for added builtins.
Fix generatepath() to return nodenums instead of pathnodes to workaround an obscure VM bug which is caused by sending a random origin as an argument and returning pathnodes.
This commit is contained in:
parent
bb8233cf86
commit
4135e7653a
@ -4,6 +4,7 @@
|
||||
#include <json.hpp>
|
||||
#include <utils/io.hpp>
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/string.hpp>
|
||||
|
||||
namespace gsc
|
||||
{
|
||||
@ -250,6 +251,7 @@ namespace gsc
|
||||
{
|
||||
if (ent.classnum != game::CLASS_NUM_ENTITY)
|
||||
{
|
||||
game::Scr_Error("Not an entity", game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -262,6 +264,7 @@ namespace gsc
|
||||
{
|
||||
if (ent.classnum != game::CLASS_NUM_PATHNODE)
|
||||
{
|
||||
game::Scr_Error("Not a pathnode", game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -282,6 +285,7 @@ namespace gsc
|
||||
{
|
||||
if (ent.classnum != game::CLASS_NUM_PATHNODE)
|
||||
{
|
||||
game::Scr_Error("Not a pathnode", game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -296,8 +300,15 @@ namespace gsc
|
||||
{
|
||||
auto node_num = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 0);
|
||||
|
||||
if (node_num < 0 || node_num >= game::g_path->actualNodeCount)
|
||||
if (node_num == game::g_path->actualNodeCount)
|
||||
{
|
||||
game::Scr_AddUndefined(game::SCRIPTINSTANCE_SERVER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (node_num < 0 || node_num > game::g_path->actualNodeCount)
|
||||
{
|
||||
game::Scr_Error(utils::string::va("Number %d is not valid for a node", node_num), game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -314,15 +325,39 @@ namespace gsc
|
||||
|
||||
float goal_pos[3] = {};
|
||||
|
||||
auto team = game::TEAM_ALLIES;
|
||||
auto team = "neutral"s;
|
||||
|
||||
auto allow_negotiation_links = false;
|
||||
|
||||
game::Scr_GetVector(game::SCRIPTINSTANCE_SERVER, 0, start_pos);
|
||||
game::Scr_GetVector(game::SCRIPTINSTANCE_SERVER, 1, goal_pos);
|
||||
|
||||
auto success = game::Path_FindPath(path.get(), team, start_pos, goal_pos, true);
|
||||
if (game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) >= 3)
|
||||
{
|
||||
if (game::Scr_GetType(game::SCRIPTINSTANCE_SERVER, 2) != game::VAR_UNDEFINED)
|
||||
{
|
||||
team = game::Scr_GetString(game::SCRIPTINSTANCE_SERVER, 2);
|
||||
}
|
||||
|
||||
if (game::Scr_GetNumParam(game::SCRIPTINSTANCE_SERVER) >= 4)
|
||||
{
|
||||
allow_negotiation_links = game::Scr_GetInt(game::SCRIPTINSTANCE_SERVER, 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (!game::team_map.contains(team))
|
||||
{
|
||||
game::Scr_Error(utils::string::va("Team %s is not valid", team.data()), game::SCRIPTINSTANCE_SERVER, false);
|
||||
return;
|
||||
}
|
||||
|
||||
auto eTeam = game::team_map.at(team);
|
||||
|
||||
auto success = game::Path_FindPath(path.get(), eTeam, start_pos, goal_pos, allow_negotiation_links);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
game::Scr_AddUndefined(game::SCRIPTINSTANCE_SERVER);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -330,9 +365,8 @@ namespace gsc
|
||||
|
||||
for (auto i = 0; i < path->wPathLen; i++)
|
||||
{
|
||||
auto node_in_path = &(*game::gameWorldCurrent)->path.nodes[path->pts[i].iNodeNum];
|
||||
|
||||
game::Scr_AddPathnode(game::SCRIPTINSTANCE_SERVER, node_in_path);
|
||||
//Return the number of the node instead of the node itself because of spooky GSC VM corruption
|
||||
game::Scr_AddInt(game::SCRIPTINSTANCE_SERVER, path->pts[i].iNodeNum);
|
||||
game::Scr_AddArray(game::SCRIPTINSTANCE_SERVER);
|
||||
}
|
||||
});
|
||||
|
@ -23,6 +23,15 @@ namespace game
|
||||
}
|
||||
}
|
||||
|
||||
std::map<std::string, team_t> team_map =
|
||||
{
|
||||
{ "free", TEAM_FREE },
|
||||
{ "axis", TEAM_AXIS },
|
||||
{ "allies", TEAM_ALLIES },
|
||||
{ "neutral", TEAM_NEUTRAL },
|
||||
{ "dead", TEAM_DEAD }
|
||||
};
|
||||
|
||||
int Scr_GetInt(game::scriptInstance_t inst, unsigned int arg_index)
|
||||
{
|
||||
static const auto call_addr = SELECT(0x0, 0x699C50);
|
||||
@ -252,13 +261,13 @@ namespace game
|
||||
return answer;
|
||||
}
|
||||
|
||||
void Scr_AddEntityNum(scriptInstance_t inst, unsigned short entid)
|
||||
void Scr_AddEntityNum(scriptInstance_t inst, unsigned int entid)
|
||||
{
|
||||
static const auto call_addr = SELECT(0x0, 0x69A770);
|
||||
|
||||
__asm
|
||||
{
|
||||
movzx esi, entid;
|
||||
mov esi, entid;
|
||||
mov eax, inst;
|
||||
call call_addr;
|
||||
}
|
||||
@ -282,8 +291,8 @@ namespace game
|
||||
|
||||
void Scr_AddPathnode(scriptInstance_t inst, pathnode_t* node)
|
||||
{
|
||||
int entnum = node - (*gameWorldCurrent)->path.nodes;
|
||||
int entid = Scr_GetEntityId(inst, entnum, CLASS_NUM_PATHNODE, 0);
|
||||
unsigned int entnum = node - (*gameWorldCurrent)->path.nodes;
|
||||
auto entid = Scr_GetEntityId(inst, entnum, CLASS_NUM_PATHNODE, 0);
|
||||
Scr_AddEntityNum(inst, entid);
|
||||
}
|
||||
|
||||
@ -310,6 +319,41 @@ namespace game
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int Scr_GetNumParam(scriptInstance_t inst)
|
||||
{
|
||||
return scrVmPub[inst].outparamcount;
|
||||
}
|
||||
|
||||
VariableType Scr_GetType(scriptInstance_t inst, unsigned int index)
|
||||
{
|
||||
static const auto call_addr = SELECT(0x0, 0x69A4E0);
|
||||
VariableType answer;
|
||||
|
||||
__asm
|
||||
{
|
||||
mov eax, inst;
|
||||
mov ecx, index;
|
||||
call call_addr;
|
||||
mov answer, eax;
|
||||
}
|
||||
|
||||
return answer;
|
||||
}
|
||||
|
||||
void Scr_Error(const char* err, scriptInstance_t inst, bool is_terminal)
|
||||
{
|
||||
static const auto call_addr = SELECT(0x0, 0x69AB70);
|
||||
|
||||
__asm
|
||||
{
|
||||
push is_terminal;
|
||||
mov edi, inst;
|
||||
mov ecx, err;
|
||||
call call_addr;
|
||||
add esp, 4;
|
||||
}
|
||||
}
|
||||
|
||||
const char* SL_ConvertToString(scriptInstance_t inst, int id)
|
||||
{
|
||||
static const auto call_addr = SELECT(0x0, 0x68D950);
|
||||
|
@ -21,6 +21,8 @@ namespace game
|
||||
bool t4sp();
|
||||
}
|
||||
|
||||
extern std::map<std::string, team_t> team_map;
|
||||
|
||||
const char* Cmd_Argv(int index);
|
||||
unsigned int Cmd_Argc();
|
||||
void Cmd_AddCommand(const char* name, void(__cdecl* function)());
|
||||
@ -28,28 +30,31 @@ namespace game
|
||||
dvar_s* Dvar_RegisterInt(const char* name, int value, int min, int max, DvarFlags flags, const char* desc);
|
||||
dvar_s* Dvar_RegisterString(const char* name, const char* value, DvarFlags flags, const char* desc);
|
||||
|
||||
int Scr_GetInt(game::scriptInstance_t inst, unsigned int arg_index); //testing
|
||||
void Scr_AddInt(game::scriptInstance_t inst, int value); //testing
|
||||
float Scr_GetFloat(game::scriptInstance_t inst, unsigned int arg_index); //testing
|
||||
void Scr_AddFloat(game::scriptInstance_t inst, float value); //testing
|
||||
char* Scr_GetString(game::scriptInstance_t inst, unsigned int arg_index); //testing
|
||||
void Scr_AddString(game::scriptInstance_t inst, const char* string); //testing
|
||||
const char* Scr_GetIString(game::scriptInstance_t inst, unsigned int arg_index); //testing
|
||||
void Scr_AddIString(game::scriptInstance_t inst, const char* string); //testing
|
||||
unsigned short Scr_GetConstString(game::scriptInstance_t inst, unsigned int arg_index); //testing
|
||||
void Scr_AddConstString(game::scriptInstance_t inst, unsigned short id); //testing
|
||||
void Scr_GetVector(game::scriptInstance_t inst, unsigned int arg_index, float* value); //testing
|
||||
void Scr_AddVector(game::scriptInstance_t inst, float* value); //testing
|
||||
void Scr_AddUndefined(game::scriptInstance_t inst); //testing
|
||||
gentity_s* Scr_GetEntity(unsigned int arg_index); //testing
|
||||
void Scr_AddEntity(game::scriptInstance_t inst, gentity_s* ent); //testing
|
||||
unsigned int Scr_GetEntityId(scriptInstance_t inst, int entNum, classNum_e classnum, unsigned int clientnum); //testing
|
||||
void Scr_AddEntityNum(scriptInstance_t inst, unsigned short entid); //testing
|
||||
pathnode_t* Scr_GetPathnode(scriptInstance_t inst); //testing
|
||||
void Scr_AddPathnode(scriptInstance_t inst, pathnode_t* node); //testing
|
||||
void Scr_MakeArray(scriptInstance_t inst); //testing
|
||||
void Scr_AddArrayStringIndexed(scriptInstance_t inst, unsigned short id); //testing
|
||||
const char* SL_ConvertToString(scriptInstance_t inst, int id); //testing
|
||||
int Scr_GetInt(game::scriptInstance_t inst, unsigned int arg_index);
|
||||
void Scr_AddInt(game::scriptInstance_t inst, int value);
|
||||
float Scr_GetFloat(game::scriptInstance_t inst, unsigned int arg_index);
|
||||
void Scr_AddFloat(game::scriptInstance_t inst, float value);
|
||||
char* Scr_GetString(game::scriptInstance_t inst, unsigned int arg_index);
|
||||
void Scr_AddString(game::scriptInstance_t inst, const char* string);
|
||||
const char* Scr_GetIString(game::scriptInstance_t inst, unsigned int arg_index);
|
||||
void Scr_AddIString(game::scriptInstance_t inst, const char* string);
|
||||
unsigned short Scr_GetConstString(game::scriptInstance_t inst, unsigned int arg_index);
|
||||
void Scr_AddConstString(game::scriptInstance_t inst, unsigned short id);
|
||||
void Scr_GetVector(game::scriptInstance_t inst, unsigned int arg_index, float* value);
|
||||
void Scr_AddVector(game::scriptInstance_t inst, float* value);
|
||||
void Scr_AddUndefined(game::scriptInstance_t inst);
|
||||
gentity_s* Scr_GetEntity(unsigned int arg_index);
|
||||
void Scr_AddEntity(game::scriptInstance_t inst, gentity_s* ent);
|
||||
unsigned int Scr_GetEntityId(scriptInstance_t inst, int entNum, classNum_e classnum, unsigned int clientnum);
|
||||
void Scr_AddEntityNum(scriptInstance_t inst, unsigned int entid);
|
||||
pathnode_t* Scr_GetPathnode(scriptInstance_t inst);
|
||||
void Scr_AddPathnode(scriptInstance_t inst, pathnode_t* node);
|
||||
void Scr_MakeArray(scriptInstance_t inst);
|
||||
void Scr_AddArrayStringIndexed(scriptInstance_t inst, unsigned short id);
|
||||
unsigned int Scr_GetNumParam(scriptInstance_t inst);
|
||||
VariableType Scr_GetType(scriptInstance_t inst, unsigned int index);
|
||||
void Scr_Error(const char* err, scriptInstance_t inst, bool is_terminal);
|
||||
const char* SL_ConvertToString(scriptInstance_t inst, int id);
|
||||
|
||||
int Path_FindPath(path_t* pPath, team_t eTeam, float* vStartPos, float* vGoalPos, int bAllowNegotiationLinks);
|
||||
|
||||
|
@ -15,6 +15,8 @@ namespace game
|
||||
struct animscripted_s;
|
||||
union pathnode_tree_info_t;
|
||||
struct pathnode_tree_t;
|
||||
struct VariableValue;
|
||||
struct function_frame_t;
|
||||
|
||||
typedef float vec_t;
|
||||
typedef vec_t vec2_t[2];
|
||||
@ -396,7 +398,7 @@ namespace game
|
||||
int duration;
|
||||
};
|
||||
|
||||
enum team_t : __int32
|
||||
enum team_t
|
||||
{
|
||||
TEAM_FREE = 0x0,
|
||||
TEAM_BAD = 0x0,
|
||||
@ -407,14 +409,14 @@ namespace game
|
||||
TEAM_NUM_TEAMS = 0x5,
|
||||
};
|
||||
|
||||
enum MissileStage : __int32
|
||||
enum MissileStage
|
||||
{
|
||||
MISSILESTAGE_SOFTLAUNCH = 0x0,
|
||||
MISSILESTAGE_ASCENT = 0x1,
|
||||
MISSILESTAGE_DESCENT = 0x2,
|
||||
};
|
||||
|
||||
enum MissileFlightMode : __int32
|
||||
enum MissileFlightMode
|
||||
{
|
||||
MISSILEFLIGHTMODE_TOP = 0x0,
|
||||
MISSILEFLIGHTMODE_DIRECT = 0x1,
|
||||
@ -1587,4 +1589,89 @@ namespace game
|
||||
unsigned int originErrors;
|
||||
pathlocal_t_circle circle;
|
||||
};
|
||||
|
||||
enum VariableType
|
||||
{
|
||||
VAR_UNDEFINED = 0x0,
|
||||
VAR_BEGIN_REF = 0x1,
|
||||
VAR_POINTER = 0x1,
|
||||
VAR_STRING = 0x2,
|
||||
VAR_ISTRING = 0x3,
|
||||
VAR_VECTOR = 0x4,
|
||||
VAR_END_REF = 0x5,
|
||||
VAR_FLOAT = 0x5,
|
||||
VAR_INTEGER = 0x6,
|
||||
VAR_CODEPOS = 0x7,
|
||||
VAR_PRECODEPOS = 0x8,
|
||||
VAR_FUNCTION = 0x9,
|
||||
VAR_BUILTIN_FUNCTION = 0xA,
|
||||
VAR_BUILTIN_METHOD = 0xB,
|
||||
VAR_STACK = 0xC,
|
||||
VAR_ANIMATION = 0xD,
|
||||
VAR_PRE_ANIMATION = 0xE,
|
||||
VAR_THREAD = 0xF,
|
||||
VAR_NOTIFY_THREAD = 0x10,
|
||||
VAR_TIME_THREAD = 0x11,
|
||||
VAR_CHILD_THREAD = 0x12,
|
||||
VAR_OBJECT = 0x13,
|
||||
VAR_DEAD_ENTITY = 0x14,
|
||||
VAR_ENTITY = 0x15,
|
||||
VAR_ARRAY = 0x16,
|
||||
VAR_DEAD_THREAD = 0x17,
|
||||
VAR_COUNT = 0x18,
|
||||
VAR_FREE = 0x18,
|
||||
VAR_THREAD_LIST = 0x19,
|
||||
VAR_ENDON_LIST = 0x1A,
|
||||
VAR_TOTAL_COUNT = 0x1B,
|
||||
};
|
||||
|
||||
union VariableUnion
|
||||
{
|
||||
int intValue;
|
||||
float floatValue;
|
||||
unsigned int stringValue;
|
||||
const float* vectorValue;
|
||||
const char* codePosValue;
|
||||
unsigned int pointerValue;
|
||||
char* stackValue;
|
||||
unsigned int entityOffset;
|
||||
};
|
||||
|
||||
struct VariableValue
|
||||
{
|
||||
VariableUnion u;
|
||||
VariableType type;
|
||||
};
|
||||
|
||||
struct function_stack_t
|
||||
{
|
||||
const char* pos;
|
||||
unsigned int localId;
|
||||
unsigned int localVarCount;
|
||||
VariableValue* top;
|
||||
VariableValue* startTop;
|
||||
};
|
||||
|
||||
struct function_frame_t
|
||||
{
|
||||
function_stack_t fs;
|
||||
int topType;
|
||||
};
|
||||
|
||||
struct __declspec(align(4)) scrVmPub_t
|
||||
{
|
||||
int* localVars;
|
||||
VariableValue* maxstack;
|
||||
int function_count;
|
||||
function_frame_t* function_frame;
|
||||
VariableValue* top;
|
||||
bool debugCode;
|
||||
bool abort_on_error;
|
||||
char terminal_error;
|
||||
char field_17;
|
||||
unsigned int inparamcount;
|
||||
unsigned int outparamcount;
|
||||
function_frame_t function_frame_start[32];
|
||||
VariableValue stack[2048];
|
||||
};
|
||||
}
|
@ -23,6 +23,8 @@ namespace game
|
||||
|
||||
WEAK symbol<gentity_s> g_entities{ 0x0, 0x176C6F0 };
|
||||
|
||||
WEAK symbol<scrVmPub_t> scrVmPub{ 0x0, 0x3BD4700 };
|
||||
|
||||
namespace plutonium
|
||||
{
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user