So here's the rub. I'm working on a json/angelscript combo system as part of weapon design. The JSON defining the script block and function to call, which uses the signature "void call(gentity_t@)". The problem is, I'm not sure if I'm handling the object correctly. gentity_t is just a simple struct (but it isn't asOBJ_POD as it contains pointers to some other things within). The script will modify certain aspects of the gentity_t, which is meant to be passed in as a pointer, as well as execute several global functions which take the gentity_t as an argument.
Right, so here's how I'm registering my object:
scrpEngine->RegisterObjectType("gentity_t", sizeof(gentity_t), asOBJ_REF | asOBJ_NOCOUNT);
and here's how I'm calling the script:
bool TryNewDempRoutine(gentity_t *ent) {
if(ent->s.weapon != WP_DEMP2) {
return false;
}
G_ExecuteASVoid("void DEMP2Test(gentity_t@ ent)", 1, ent);
return true;
}
(here's G_ExecuteASVoid: )
void G_ExecuteASVoid(const char* funcDeclaration, int numArgs, ...) {
string s = funcDeclaration;
auto paramStart = s.find_first_of('(')+1;
auto paramEnd = s.find_last_of(')')-paramStart;
string params = s.substr(paramStart, paramEnd);
vector<string> arguments;
asIScriptFunction *func = scrpEngine->GetModule(0)->GetFunctionByDecl(funcDeclaration);
scrpContext->Prepare(func);
auto argSplitter = params.find_first_of(',');
while(argSplitter != params.npos) {
string thisArgument = params.substr(0, argSplitter-1);
arguments.push_back(thisArgument);
params+=argSplitter;
argSplitter = params.find_first_of(',')+1;
}
arguments.push_back(params);
va_list argptr;
va_start(argptr, numArgs);
void* arg;
for(int i = 2; i < numArgs+2; i++) {
arg = va_arg(argptr, void*);
AS_SetArgBasedOnType(&arg, arguments.at(i-2), i-2);
}
scrpContext->Execute();
}
Here's my angelscript file:
void FireDemp2(gentity_t@ ent) {
vec3_t start;
int damage = GetWeaponDamage(WP_DEMP2);
Com_Print("test4\n");
VectorCopy(wpMuzzle, start); // Copy value of wpMuzzle to start
Com_Print("test5\n");
WP_TraceSetStart(ent, start, vec3_origin, vec3_origin);
Com_Print("test6\n");
gentity_t@ missile = CreateMissile(start, wpFwd, 1800, 10000, ent);
Com_Print("test7\n");
missile.s.weapon = WP_DEMP2;
Com_Print("test8\n");
VectorSet( missile.maxs, 2.0, 2.0, 2.0 );
Com_Print("test9\n");
VectorScale( missile.maxs, -1, missile.mins );
Com_Print("test10\n");
missile.damage = damage;
Com_Print("test11\n");
missile.dflags = 128; // Lazy, don't feel like creating an enum for this right now
Com_Print("test12\n");
missile.methodOfDeath = 12; // Also lazy and don't feel like creating an enum for this right now either
Com_Print("test13\n");
missile.clipmask = 263041; // BLARGH SO MUCH TO DO OMG
Com_Print("test14\n");
}
void DEMP2Test(gentity_t@ ent) {
// Increase number of shots fired (for loading screen statistics
ent.client.ps.accuracy_shots++;
// From our viewangles, generate three vectors -> wpFwd, wpVright, wpUp (all are global)
Com_Print("test\n");
AngleVectors(ent.client.ps.viewangles, wpFwd, wpVright, wpUp);
Com_Print("test2\n");
// Given the three vectors, calculate our muzzle point and stuff it into wpMuzzle (also global)
CalcMuzzlePoint(ent, wpFwd, wpVright, wpUp, wpMuzzle, 0);
Com_Print("test3\n");
// Call our funtion which fires the DEMP2
FireDemp2(ent);
}
The script only gets as far as "test2" before it fails on CalcMuzzlePoint, that function being a global function:
void CalcMuzzlePoint( gentity_t *const ent, vec3_t wpFwd, vec3_t right, vec3_t wpUp, vec3_t muzzlePoint, float lead_in )
....
scrpEngine->RegisterGlobalFunction("void CalcMuzzlePoint(gentity_t@ ent, vec3_t fwd, vec3_t right, vec3_t up, vec3_t muzzle, float lead_in)", asFUNCTION(CalculateMuzzlePoint_AS), asCALL_CDECL);
I suspect that I'm doing this completely wrong and that maybe I should be using something like CScriptHandle, but I'm not too sure where to go with this.