void CLuaHandle::UnitFromFactory(const CUnit* unit, const CUnit* factory, bool userOrders) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 9); int errfunc = SetupTraceback(); static const LuaHashString cmdStr("UnitFromFactory"); if (!cmdStr.GetGlobalFunc(L)) { // remove error handler if (errfunc) lua_pop(L, 1); return; // the call is not defined } lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); lua_pushnumber(L, factory->id); lua_pushnumber(L, factory->unitDef->id); lua_pushboolean(L, userOrders); // call the routine RunCallInTraceback(cmdStr, 6, 0, errfunc); return; }
void CLuaHandle::UnitDestroyed(const CUnit* unit, const CUnit* attacker) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 9); int errfunc = SetupTraceback(); static const LuaHashString cmdStr("UnitDestroyed"); if (!cmdStr.GetGlobalFunc(L)) { // remove error handler if (errfunc) lua_pop(L, 1); return; // the call is not defined } int argCount = 3; lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); if (fullRead && (attacker != NULL)) { lua_pushnumber(L, attacker->id); lua_pushnumber(L, attacker->unitDef->id); lua_pushnumber(L, attacker->team); argCount += 3; } // call the routine RunCallInTraceback(cmdStr, argCount, 0, errfunc); return; }
int CLuaRules::AllowWeaponTargetCheck(unsigned int attackerID, unsigned int attackerWeaponNum, unsigned int attackerWeaponDefID) { if (!haveAllowWeaponTargetCheck) return -1; if (!watchWeaponDefs[attackerWeaponDefID]) return -1; LUA_CALL_IN_CHECK(L, -1); lua_checkstack(L, 3 + 1); const int errfunc(SetupTraceback(L)); static const LuaHashString cmdStr("AllowWeaponTargetCheck"); int ret = -1; if (!cmdStr.GetGlobalFunc(L)) { if (errfunc) lua_pop(L, 1); return ret; } lua_pushnumber(L, attackerID); lua_pushnumber(L, attackerWeaponNum); lua_pushnumber(L, attackerWeaponDefID); if (!RunCallInTraceback(cmdStr, 3, 1, errfunc)) return ret; ret = (lua_isboolean(L, -1) && lua_toboolean(L, -1))? 1: 0; lua_pop(L, -1); return ret; }
void CLuaHandle::UnitCommand(const CUnit* unit, const Command& command) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 11); int errfunc = SetupTraceback(); static const LuaHashString cmdStr("UnitCommand"); if (!cmdStr.GetGlobalFunc(L)) { // remove error handler if (errfunc) lua_pop(L, 1); return; // the call is not defined } lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); lua_pushnumber(L, command.id); lua_pushnumber(L, command.options); const vector<float> params = command.params; lua_createtable(L, params.size(), 0); for (unsigned int i = 0; i < params.size(); i++) { lua_pushnumber(L, i + 1); lua_pushnumber(L, params[i]); lua_rawset(L, -3); } // call the routine RunCallInTraceback(cmdStr, 6, 0, errfunc); return; }
bool CLuaRules::AllowWeaponInterceptTarget( const CUnit* interceptorUnit, const CWeapon* interceptorWeapon, const CProjectile* interceptorTarget ) { bool ret = true; if (!haveAllowWeaponInterceptTarget) return ret; if (!watchWeaponDefs[interceptorWeapon->weaponDef->id]) return ret; LUA_CALL_IN_CHECK(L, true); luaL_checkstack(L, 2 + 3 + 1, __FUNCTION__); static const LuaHashString cmdStr(__FUNCTION__); const LuaUtils::ScopedDebugTraceBack traceBack(L); if (cmdStr.GetGlobalFunc(L)) { lua_pushnumber(L, interceptorUnit->id); lua_pushnumber(L, interceptorWeapon->weaponNum); lua_pushnumber(L, interceptorTarget->id); if (!RunCallInTraceback(cmdStr, 3, 1, traceBack.GetErrFuncIdx(), false)) return ret; ret = (lua_isboolean(L, -1) && lua_toboolean(L, -1)); lua_pop(L, 1); } return ret; }
bool CLuaRules::ShieldPreDamaged( const CProjectile* projectile, const CWeapon* shieldEmitter, const CUnit* shieldCarrier, bool bounceProjectile ) { if (!haveShieldPreDamaged) return false; LUA_CALL_IN_CHECK(L, false); luaL_checkstack(L, 2 + 5 + 1, __FUNCTION__); static const LuaHashString cmdStr(__FUNCTION__); const LuaUtils::ScopedDebugTraceBack traceBack(L); if (!cmdStr.GetGlobalFunc(L)) return false; // push the call-in arguments lua_pushnumber(L, projectile->id); lua_pushnumber(L, projectile->GetOwnerID()); lua_pushnumber(L, shieldEmitter->weaponNum); lua_pushnumber(L, shieldCarrier->id); lua_pushboolean(L, bounceProjectile); // call the routine if (!RunCallInTraceback(cmdStr, 5, 1, traceBack.GetErrFuncIdx(), false)) return false; // pop the return-value; must be true or false const bool ret = (lua_isboolean(L, -1) && lua_toboolean(L, -1)); lua_pop(L, 1); return ret; }
int CLuaRules::AllowWeaponTargetCheck(unsigned int attackerID, unsigned int attackerWeaponNum, unsigned int attackerWeaponDefID) { if (!haveAllowWeaponTargetCheck) return -1; if (!watchWeaponDefs[attackerWeaponDefID]) return -1; LUA_CALL_IN_CHECK(L, -1); luaL_checkstack(L, 2 + 3 + 1, __FUNCTION__); static const LuaHashString cmdStr(__FUNCTION__); const LuaUtils::ScopedDebugTraceBack traceBack(L); int ret = -1; if (cmdStr.GetGlobalFunc(L)) { lua_pushnumber(L, attackerID); lua_pushnumber(L, attackerWeaponNum); lua_pushnumber(L, attackerWeaponDefID); if (!RunCallInTraceback(cmdStr, 3, 1, traceBack.GetErrFuncIdx(), false)) return ret; ret = int(lua_isboolean(L, -1) && lua_toboolean(L, -1)); lua_pop(L, 1); } return ret; }
int CSyncedLuaHandle::AllowWeaponTargetCheck(unsigned int attackerID, unsigned int attackerWeaponNum, unsigned int attackerWeaponDefID) { int ret = -1; if (!watchWeaponDefs[attackerWeaponDefID]) return ret; LUA_CALL_IN_CHECK(L, -1); luaL_checkstack(L, 2 + 3 + 1, __FUNCTION__); const LuaUtils::ScopedDebugTraceBack traceBack(L); static const LuaHashString cmdStr(__FUNCTION__); if (!cmdStr.GetGlobalFunc(L)) return ret; lua_pushnumber(L, attackerID); lua_pushnumber(L, attackerWeaponNum); lua_pushnumber(L, attackerWeaponDefID); if (!RunCallInTraceback(L, cmdStr, 3, 1, traceBack.GetErrFuncIdx(), false)) return ret; ret = int(luaL_optboolean(L, -1, false)); //FIXME int???? lua_pop(L, 1); return ret; }
bool CLuaHandleSynced::Initialize(const string& syncData) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3); static const LuaHashString cmdStr("Initialize"); if (!cmdStr.GetGlobalFunc(L)) { return true; } int errfunc = SetupTraceback() ? -2 : 0; logOutput.Print("Initialize errfunc=%d\n", errfunc); lua_pushlstring(L, syncData.c_str(), syncData.size()); // call the routine if (!RunCallInTraceback(cmdStr, 1, 1, errfunc)) { return false; } // get the results if (!lua_isboolean(L, -1)) { lua_pop(L, 1); return true; } const bool retval = !!lua_toboolean(L, -1); lua_pop(L, 1); return retval; }
bool CSyncedLuaHandle::TerraformComplete(const CUnit* unit, const CUnit* build) { LUA_CALL_IN_CHECK(L, false); luaL_checkstack(L, 8, __FUNCTION__); const LuaUtils::ScopedDebugTraceBack traceBack(L); static const LuaHashString cmdStr(__FUNCTION__); if (!cmdStr.GetGlobalFunc(L)) return false; // the call is not defined // push the unit info lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); // push the construction info lua_pushnumber(L, build->id); lua_pushnumber(L, build->unitDef->id); lua_pushnumber(L, build->team); // call the function if (!RunCallInTraceback(L, cmdStr, 6, 1, traceBack.GetErrFuncIdx(), false)) return false; // get the results const bool retval = luaL_optboolean(L, -1, false); lua_pop(L, 1); return retval; }
bool CLuaRules::AllowWeaponTargetCheck(unsigned int attackerID, unsigned int attackerWeaponNum, unsigned int attackerWeaponDefID) { if (!haveAllowWeaponTargetCheck) { return false; } LUA_CALL_IN_CHECK(L); lua_checkstack(L, 3 + 1); const int errfunc(SetupTraceback()); static const LuaHashString cmdStr("AllowWeaponTargetCheck"); bool ret = false; if (!cmdStr.GetGlobalFunc(L)) { if (errfunc) { lua_pop(L, 1); } return ret; } lua_pushnumber(L, attackerID); lua_pushnumber(L, attackerWeaponNum); lua_pushnumber(L, attackerWeaponDefID); RunCallInTraceback(cmdStr, 3, 1, errfunc); ret = (lua_isboolean(L, -1) && lua_toboolean(L, -1)); lua_pop(L, -1); return ret; }
void CLuaHandle::UnitCreated(const CUnit* unit, const CUnit* builder) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 7); int errfunc = SetupTraceback(); static const LuaHashString cmdStr("UnitCreated"); if (!cmdStr.GetGlobalFunc(L)) { // remove error handler if (errfunc) lua_pop(L, 1); return; // the call is not defined } lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); if (builder != NULL) { lua_pushnumber(L, builder->id); } int args = (builder != NULL) ? 4 : 3; // call the routine RunCallInTraceback(cmdStr, args, 0, errfunc); return; }
void CLuaHandleSynced::GameFrame(int frameNumber) { if (killMe) { string msg = GetName(); if (!killMsg.empty()) { msg += ": " + killMsg; } logOutput.Print("Disabled %s\n", msg.c_str()); delete this; return; } LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); int errfunc = SetupTraceback(); static const LuaHashString cmdStr("GameFrame"); if (!cmdStr.GetGlobalFunc(L)) { if (errfunc) lua_pop(L, 1); return; } lua_pushnumber(L, frameNumber); // 6 day roll-over // call the routine allowChanges = true; RunCallInTraceback(cmdStr, 1, 0, errfunc); allowChanges = allowUnsafeChanges; return; }
bool CSyncedLuaHandle::FeaturePreDamaged( const CFeature* feature, const CUnit* attacker, float damage, int weaponDefID, int projectileID, float* newDamage, float* impulseMult) { LUA_CALL_IN_CHECK(L, false); luaL_checkstack(L, 2 + 9 + 2, __FUNCTION__); static const LuaHashString cmdStr(__FUNCTION__); const LuaUtils::ScopedDebugTraceBack traceBack(L); if (!cmdStr.GetGlobalFunc(L)) return false; int inArgCount = 4; int outArgCount = 2; lua_pushnumber(L, feature->id); lua_pushnumber(L, feature->def->id); lua_pushnumber(L, feature->team); lua_pushnumber(L, damage); if (GetHandleFullRead(L)) { lua_pushnumber(L, weaponDefID); inArgCount += 1; lua_pushnumber(L, projectileID); inArgCount += 1; if (attacker != NULL) { lua_pushnumber(L, attacker->id); lua_pushnumber(L, attacker->unitDef->id); lua_pushnumber(L, attacker->team); inArgCount += 3; } } // call the routine if (!RunCallInTraceback(L, cmdStr, inArgCount, outArgCount, traceBack.GetErrFuncIdx(), false)) return false; if (newDamage && lua_isnumber(L, -2)) { *newDamage = lua_tonumber(L, -2); } else if (!lua_isnumber(L, -2) || lua_isnil(L, -2)) { // first value is obligatory, so may not be nil LOG_L(L_WARNING, "%s(): 1st value returned should be a number (newDamage)", (cmdStr.GetString()).c_str()); } if (impulseMult && lua_isnumber(L, -1)) { *impulseMult = lua_tonumber(L, -1); } else if (!lua_isnumber(L, -1) && !lua_isnil(L, -1)) { // second value is optional, so nils are OK LOG_L(L_WARNING, "%s(): 2nd value returned should be a number (impulseMult)", (cmdStr.GetString()).c_str()); } lua_pop(L, outArgCount); return (*newDamage == 0.f && *impulseMult == 0.f); // returns true to disable engine dmg handling }
/** * called after every damage modification (even HitByWeaponId) * but before the damage is applied * * expects two numbers returned by lua code: * 1st is stored under *newDamage if newDamage != NULL * 2nd is stored under *impulseMult if impulseMult != NULL */ bool CLuaRules::UnitPreDamaged(const CUnit* unit, const CUnit* attacker, float damage, int weaponID, bool paralyzer, float* newDamage, float* impulseMult) { if (!haveUnitPreDamaged) { return false; } LUA_CALL_IN_CHECK(L); lua_checkstack(L, 11); const int errfunc = SetupTraceback(); static const LuaHashString cmdStr("UnitPreDamaged"); if (!cmdStr.GetGlobalFunc(L)) { // remove error handler if (errfunc) { lua_pop(L, 1); } return false; // the call is not defined } int argCount = 5; lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); lua_pushnumber(L, damage); lua_pushboolean(L, paralyzer); if (fullRead) { lua_pushnumber(L, weaponID); argCount += 1; if (attacker != NULL) { lua_pushnumber(L, attacker->id); lua_pushnumber(L, attacker->unitDef->id); lua_pushnumber(L, attacker->team); argCount += 3; } } // call the routine RunCallInTraceback(cmdStr, argCount, 2, errfunc); if (newDamage && lua_isnumber(L, -2)) { *newDamage = lua_tonumber(L, -2); } else if (!lua_isnumber(L, -2) || lua_isnil(L, -2)) { // first value is obligatory, so may not be nil logOutput.Print("%s(): 1st value returned should be a number (newDamage)\n", cmdStr.GetString().c_str()); } if (impulseMult && lua_isnumber(L, -1)) { *impulseMult = lua_tonumber(L, -1); } else if (!lua_isnumber(L, -1) && !lua_isnil(L, -1)) { // second value is optional, so nils are OK logOutput.Print("%s(): 2nd value returned should be a number (impulseMult)\n", cmdStr.GetString().c_str()); } lua_pop(L, 2); return true; }
bool CLuaHandle::RunCallInTraceback(const LuaHashString& hs, int inArgs, int outArgs, int errfuncIndex) { std::string traceback; const int error = RunCallInTraceback(inArgs, outArgs, errfuncIndex, traceback); if (error != 0) { logOutput.Print("%s::RunCallIn: error = %i, %s, %s\n", GetName().c_str(), error, hs.GetString().c_str(), traceback.c_str()); return false; } return true; }
bool CLuaRules::AllowWeaponTarget( unsigned int attackerID, unsigned int targetID, unsigned int attackerWeaponNum, unsigned int attackerWeaponDefID, float* targetPriority) { assert(targetPriority != NULL); bool ret = true; if (!haveAllowWeaponTarget) return ret; if (!watchWeaponDefs[attackerWeaponDefID]) return ret; LUA_CALL_IN_CHECK(L, true); lua_checkstack(L, 5 + 2); const int errfunc(SetupTraceback(L)); static const LuaHashString cmdStr("AllowWeaponTarget"); if (!cmdStr.GetGlobalFunc(L)) { if (errfunc) lua_pop(L, 1); return ret; } lua_pushnumber(L, attackerID); lua_pushnumber(L, targetID); lua_pushnumber(L, attackerWeaponNum); lua_pushnumber(L, attackerWeaponDefID); lua_pushnumber(L, *targetPriority); if (!RunCallInTraceback(cmdStr, 5, 2, errfunc)) return ret; ret = lua_toboolean(L, -2); if (lua_isnumber(L, -1)) { *targetPriority = lua_tonumber(L, -1); } lua_pop(L, 2); return ret; }
void CLuaHandle::GameOver() { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 2); int errfunc = SetupTraceback(); static const LuaHashString cmdStr("GameOver"); if (!cmdStr.GetGlobalFunc(L)) { // remove error handler if (errfunc) lua_pop(L, 1); return; // the call is not defined } // call the routine RunCallInTraceback(cmdStr, 0, 0, errfunc); return; }
bool CLuaRules::AllowWeaponTarget( unsigned int attackerID, unsigned int targetID, unsigned int attackerWeaponNum, unsigned int attackerWeaponDefID, float* targetPriority) { assert(targetPriority != NULL); bool ret = true; if (!haveAllowWeaponTarget) return ret; if (!watchWeaponDefs[attackerWeaponDefID]) return ret; LUA_CALL_IN_CHECK(L, true); luaL_checkstack(L, 2 + 5 + 2, __FUNCTION__); static const LuaHashString cmdStr(__FUNCTION__); const LuaUtils::ScopedDebugTraceBack traceBack(L); if (cmdStr.GetGlobalFunc(L)) { lua_pushnumber(L, attackerID); lua_pushnumber(L, targetID); lua_pushnumber(L, attackerWeaponNum); lua_pushnumber(L, attackerWeaponDefID); lua_pushnumber(L, *targetPriority); if (!RunCallInTraceback(cmdStr, 5, 2, traceBack.GetErrFuncIdx(), false)) return ret; ret = (lua_isboolean(L, -2) && lua_toboolean(L, -2)); if (lua_isnumber(L, -1)) { *targetPriority = lua_tonumber(L, -1); } lua_pop(L, 2); } return ret; }
int CLuaRules::AllowWeaponTarget( unsigned int attackerID, unsigned int targetID, unsigned int attackerWeaponNum, unsigned int attackerWeaponDefID, float* targetPriority) { if (!haveAllowWeaponTarget) return -1; LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4 + 2); const int errfunc(SetupTraceback(L)); static const LuaHashString cmdStr("AllowWeaponTarget"); int ret = -1; if (!cmdStr.GetGlobalFunc(L)) { if (errfunc) lua_pop(L, 1); return ret; } lua_pushnumber(L, attackerID); lua_pushnumber(L, targetID); lua_pushnumber(L, attackerWeaponNum); lua_pushnumber(L, attackerWeaponDefID); const bool success = RunCallInTraceback(cmdStr, 4, 2, errfunc); if (!success) return ret; ret = (lua_isboolean(L, -2) && lua_toboolean(L, -2))? 1: 0; if (targetPriority && lua_isnumber(L, -1)) { *targetPriority = lua_tonumber(L, -1); } lua_pop(L, 2); return ret; }
bool CLuaRules::ShieldPreDamaged( const CProjectile* projectile, const CWeapon* shieldEmitter, const CUnit* shieldCarrier, bool bounceProjectile ) { if (!haveShieldPreDamaged) { return false; } LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5 + 1); const int errfunc(SetupTraceback()); static const LuaHashString cmdStr("ShieldPreDamaged"); bool ret = false; if (!cmdStr.GetGlobalFunc(L)) { if (errfunc) { lua_pop(L, 1); } // undefined call-in return ret; } const CUnit* projectileOwner = projectile->owner(); // push the call-in arguments lua_pushnumber(L, projectile->id); lua_pushnumber(L, ((projectileOwner != NULL)? projectileOwner->id: -1)); lua_pushnumber(L, shieldEmitter->weaponNum); lua_pushnumber(L, shieldCarrier->id); lua_pushboolean(L, bounceProjectile); // call the routine RunCallInTraceback(cmdStr, 5, 1, errfunc); // pop the return-value; must be true or false ret = (lua_isboolean(L, -1) && lua_toboolean(L, -1)); lua_pop(L, -1); return ret; }
void CLuaHandle::PlayerChanged(int playerID) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 4); int errfunc = SetupTraceback(); static const LuaHashString cmdStr("PlayerChanged"); if (!cmdStr.GetGlobalFunc(L)) { // remove error handler if (errfunc) lua_pop(L, 1); return; // the call is not defined } lua_pushnumber(L, playerID); // call the routine RunCallInTraceback(cmdStr, 1, 0, errfunc); return; }
void CLuaHandle::FeatureDestroyed(const CFeature* feature) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 5); int errfunc = SetupTraceback(); static const LuaHashString cmdStr("FeatureDestroyed"); if (!cmdStr.GetGlobalFunc(L)) { // remove error handler if (errfunc) lua_pop(L, 1); return; // the call is not defined } lua_pushnumber(L, feature->id); lua_pushnumber(L, feature->allyteam); // call the routine RunCallInTraceback(cmdStr, 2, 0, errfunc); return; }
inline void CLuaHandle::UnitCallIn(const LuaHashString& hs, const CUnit* unit) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 6); int errfunc = SetupTraceback(); if (!hs.GetGlobalFunc(L)) { // remove error handler if (errfunc) lua_pop(L, 1); return; // the call is not defined } lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); // call the routine RunCallInTraceback(hs, 3, 0, errfunc); return; }
void CLuaHandle::UnitGiven(const CUnit* unit, int oldTeam) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 7); int errfunc = SetupTraceback(); static const LuaHashString cmdStr("UnitGiven"); if (!cmdStr.GetGlobalFunc(L)) { // remove error handler if (errfunc) lua_pop(L, 1); return; // the call is not defined } lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); lua_pushnumber(L, oldTeam); // call the routine RunCallInTraceback(cmdStr, 4, 0, errfunc); return; }
void CLuaHandle::UnitDamaged(const CUnit* unit, const CUnit* attacker, float damage, int weaponID, bool paralyzer) { LUA_CALL_IN_CHECK(L); lua_checkstack(L, 11); int errfunc = SetupTraceback(); static const LuaHashString cmdStr("UnitDamaged"); if (!cmdStr.GetGlobalFunc(L)) { // remove error handler if (errfunc) lua_pop(L, 1); return; // the call is not defined } int argCount = 5; lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); lua_pushnumber(L, damage); lua_pushboolean(L, paralyzer); if (fullRead) { lua_pushnumber(L, weaponID); argCount += 1; if (attacker != NULL) { lua_pushnumber(L, attacker->id); lua_pushnumber(L, attacker->unitDef->id); lua_pushnumber(L, attacker->team); argCount += 3; } } // call the routine RunCallInTraceback(cmdStr, argCount, 0, errfunc); return; }
/** * called after every damage modification (even HitByWeaponId) * but before the damage is applied * * expects two numbers returned by lua code: * 1st is stored under *newDamage if newDamage != NULL * 2nd is stored under *impulseMult if impulseMult != NULL */ bool CLuaRules::UnitPreDamaged( const CUnit* unit, const CUnit* attacker, float damage, int weaponDefID, int projectileID, bool paralyzer, float* newDamage, float* impulseMult) { if (!haveUnitPreDamaged) return false; LUA_CALL_IN_CHECK(L, false); luaL_checkstack(L, 2 + 2 + 10, __FUNCTION__); static const LuaHashString cmdStr(__FUNCTION__); const LuaUtils::ScopedDebugTraceBack traceBack(L); if (!cmdStr.GetGlobalFunc(L)) return false; int inArgCount = 5; int outArgCount = 2; lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); lua_pushnumber(L, damage); lua_pushboolean(L, paralyzer); //FIXME pass impulse too? if (GetHandleFullRead(L)) { lua_pushnumber(L, weaponDefID); inArgCount += 1; lua_pushnumber(L, projectileID); inArgCount += 1; if (attacker != NULL) { lua_pushnumber(L, attacker->id); lua_pushnumber(L, attacker->unitDef->id); lua_pushnumber(L, attacker->team); inArgCount += 3; } } // call the routine // NOTE: // RunCallInTraceback removes the error-handler by default // this has to be disabled when using ScopedDebugTraceBack // or it would mess up the stack if (!RunCallInTraceback(cmdStr, inArgCount, outArgCount, traceBack.GetErrFuncIdx(), false)) return false; if (newDamage && lua_isnumber(L, -2)) { *newDamage = lua_tonumber(L, -2); } else if (!lua_isnumber(L, -2) || lua_isnil(L, -2)) { // first value is obligatory, so may not be nil LOG_L(L_WARNING, "%s(): 1st return-value should be a number (newDamage)", (cmdStr.GetString()).c_str()); } if (impulseMult && lua_isnumber(L, -1)) { *impulseMult = lua_tonumber(L, -1); } else if (!lua_isnumber(L, -1) && !lua_isnil(L, -1)) { // second value is optional, so nils are OK LOG_L(L_WARNING, "%s(): 2nd return-value should be a number (impulseMult)", (cmdStr.GetString()).c_str()); } lua_pop(L, outArgCount); return true; }
bool CLuaHandle::RunCallIn(const LuaHashString& hs, int inArgs, int outArgs) { return RunCallInTraceback(hs, inArgs, outArgs, 0); }
int CLuaHandle::RunCallIn(int inArgs, int outArgs, std::string& errormessage) { return RunCallInTraceback(inArgs, outArgs, 0, errormessage); }