예제 #1
0
static bool WrapTable(lua_State* L)
{
	const int realTable = lua_gettop(L);

	lua_newtable(L); { // the proxy table

		lua_newtable(L); { // the metatable

			HSTR_PUSH(L, "__index");
			lua_pushvalue(L, realTable);
			lua_pushcclosure(L, SyncTableIndex, 1);
			lua_rawset(L, -3); // closure 

			HSTR_PUSH(L, "__newindex");
			lua_pushcfunction(L, SyncTableNewIndex);
			lua_rawset(L, -3);

			HSTR_PUSH(L, "__metatable");
			lua_pushcfunction(L, SyncTableMetatable);
			lua_rawset(L, -3);

			HSTR_PUSH(L, "realTable");
			lua_pushvalue(L, realTable);
			lua_rawset(L, -3);
		}

		lua_setmetatable(L, -2);
	}

	lua_remove(L, realTable);

	return true;
}
예제 #2
0
static int WeaponsTable(lua_State* L, const void* data)
{
	const vector<UnitDefWeapon>& weapons =
		*((const vector<UnitDefWeapon>*)data);

	lua_newtable(L);

	for (size_t i = 0; i < weapons.size(); i++) {
		const UnitDefWeapon& udw = weapons[i];
		const WeaponDef* weapon = udw.def;
		lua_pushnumber(L, i + LUA_WEAPON_BASE_INDEX);
		lua_newtable(L); {
			HSTR_PUSH_NUMBER(L, "weaponDef",   weapon->id);
			HSTR_PUSH_NUMBER(L, "slavedTo",    udw.slavedTo-1+LUA_WEAPON_BASE_INDEX);
			HSTR_PUSH_NUMBER(L, "fuelUsage",   udw.fuelUsage);
			HSTR_PUSH_NUMBER(L, "maxAngleDif", udw.maxMainDirAngleDif);
			HSTR_PUSH_NUMBER(L, "mainDirX",    udw.mainDir.x);
			HSTR_PUSH_NUMBER(L, "mainDirY",    udw.mainDir.y);
			HSTR_PUSH_NUMBER(L, "mainDirZ",    udw.mainDir.z);

			HSTR_PUSH(L, "badTargets");
			CategorySetFromBits(L, &udw.badTargetCat);
			lua_rawset(L, -3);

			HSTR_PUSH(L, "onlyTargets");
			CategorySetFromBits(L, &udw.onlyTargetCat);
			lua_rawset(L, -3);
		}
		lua_rawset(L, -3);
	}

	return 1;
}
예제 #3
0
string CLuaHandle::WorldTooltip(const CUnit* unit,
                                const CFeature* feature,
                                const float3* groundPos)
{
	if (!CheckModUICtrl()) {
		return "";
	}
	LUA_CALL_IN_CHECK(L);
	lua_checkstack(L, 6);
	static const LuaHashString cmdStr("WorldTooltip");
	if (!PushUnsyncedCallIn(cmdStr)) {
		return ""; // the call is not defined
	}

	int args;
	if (unit) {
		HSTR_PUSH(L, "unit");
		lua_pushnumber(L, unit->id);
		args = 2;
	}
	else if (feature) {
		HSTR_PUSH(L, "feature");
		lua_pushnumber(L, feature->id);
		args = 2;
	}
	else if (groundPos) {
		HSTR_PUSH(L, "ground");
		lua_pushnumber(L, groundPos->x);
		lua_pushnumber(L, groundPos->y);
		lua_pushnumber(L, groundPos->z);
		args = 4;
	}
	else {
		HSTR_PUSH(L, "selection");
		args = 1;
	}

	// call the routine
	if (!RunCallInUnsynced(cmdStr, args, 1)) {
		return "";
	}

	if (!lua_isstring(L, -1)) {
		lua_pop(L, 1);
		return "";
	}
	const string retval = lua_tostring(L, -1);
	lua_pop(L, 1);
	return retval;
}
예제 #4
0
bool LuaUnitDefs::PushEntries(lua_State* L)
{
	if (paramMap.empty()) {
	  InitParamMap();
	}

	const map<string, int>& udMap = unitDefHandler->unitDefIDsByName;
	map<string, int>::const_iterator udIt;
	for (udIt = udMap.begin(); udIt != udMap.end(); ++udIt) {
	  const UnitDef* ud = unitDefHandler->GetUnitDefByID(udIt->second);
		if (ud == NULL) {
	  	continue;
		}
		lua_pushnumber(L, ud->id);
		lua_newtable(L); { // the proxy table

			lua_newtable(L); { // the metatable

				HSTR_PUSH(L, "__index");
				lua_pushlightuserdata(L, (void*)ud);
				lua_pushcclosure(L, UnitDefIndex, 1);
				lua_rawset(L, -3); // closure

				HSTR_PUSH(L, "__newindex");
				lua_pushlightuserdata(L, (void*)ud);
				lua_pushcclosure(L, UnitDefNewIndex, 1);
				lua_rawset(L, -3);

				HSTR_PUSH(L, "__metatable");
				lua_pushlightuserdata(L, (void*)ud);
				lua_pushcclosure(L, UnitDefMetatable, 1);
				lua_rawset(L, -3);
			}

			lua_setmetatable(L, -2);
		}

		HSTR_PUSH(L, "pairs");
		lua_pushcfunction(L, Pairs);
		lua_rawset(L, -3);

		HSTR_PUSH(L, "next");
		lua_pushcfunction(L, Next);
		lua_rawset(L, -3);

		lua_rawset(L, -3); // proxy table into UnitDefs
	}

	return true;
}
bool LuaWeaponDefs::PushEntries(lua_State* L)
{
	if (paramMap.empty()) {
	  InitParamMap();
	}

	const map<string, int>& weaponMap = weaponDefHandler->weaponID;
	map<string, int>::const_iterator wit;
	for (wit = weaponMap.begin(); wit != weaponMap.end(); ++wit) {
		const WeaponDef* wd = &weaponDefHandler->weaponDefs[wit->second];
		if (wd == NULL) {
	  	continue;
		}
		lua_pushnumber(L, wd->id);
		lua_newtable(L); { // the proxy table

			lua_newtable(L); { // the metatable

				HSTR_PUSH(L, "__index");
				lua_pushlightuserdata(L, (void*)wd);
				lua_pushcclosure(L, WeaponDefIndex, 1);
				lua_rawset(L, -3); // closure

				HSTR_PUSH(L, "__newindex");
				lua_pushlightuserdata(L, (void*)wd);
				lua_pushcclosure(L, WeaponDefNewIndex, 1);
				lua_rawset(L, -3);

				HSTR_PUSH(L, "__metatable");
				lua_pushlightuserdata(L, (void*)wd);
				lua_pushcclosure(L, WeaponDefMetatable, 1);
				lua_rawset(L, -3);
			}

			lua_setmetatable(L, -2);
		}

		HSTR_PUSH(L, "pairs");
		lua_pushcfunction(L, Pairs);
		lua_rawset(L, -3);

		HSTR_PUSH(L, "next");
		lua_pushcfunction(L, Next);
		lua_rawset(L, -3);

		lua_rawset(L, -3); // proxy table into WeaponDefs
	}

	return true;
}
예제 #6
0
bool LuaFeatureDefs::PushEntries(lua_State* L)
{
	if (paramMap.empty()) {
		InitParamMap();
	}

	const map<string, const FeatureDef*>& featureDefs = featureHandler->GetFeatureDefs();
	map<string, const FeatureDef*>::const_iterator fdIt;
	for (fdIt = featureDefs.begin(); fdIt != featureDefs.end(); ++fdIt) {
		const FeatureDef* fd = fdIt->second;
		if (fd == NULL) {
			continue;
		}
		lua_pushnumber(L, fd->id);
		lua_newtable(L); { // the proxy table

			lua_newtable(L); { // the metatable

				HSTR_PUSH(L, "__index");
				lua_pushlightuserdata(L, (void*)fd);
				lua_pushcclosure(L, FeatureDefIndex, 1);
				lua_rawset(L, -3); // closure

				HSTR_PUSH(L, "__newindex");
				lua_pushlightuserdata(L, (void*)fd);
				lua_pushcclosure(L, FeatureDefNewIndex, 1);
				lua_rawset(L, -3);

				HSTR_PUSH(L, "__metatable");
				lua_pushlightuserdata(L, (void*)fd);
				lua_pushcclosure(L, FeatureDefMetatable, 1);
				lua_rawset(L, -3);
			}

			lua_setmetatable(L, -2);
		}

		HSTR_PUSH(L, "pairs");
		lua_pushcfunction(L, Pairs);
		lua_rawset(L, -3);

		HSTR_PUSH(L, "next");
		lua_pushcfunction(L, Next);
		lua_rawset(L, -3);

		lua_rawset(L, -3); // proxy table into FeatureDefs
	}

	return true;
}
예제 #7
0
파일: LuaUtils.cpp 프로젝트: Arkazon/spring
void LuaUtils::PushCommandDesc(lua_State* L, const CommandDescription& cd)
{
	const int numParams = cd.params.size();
	const int numTblKeys = 12;

	lua_checkstack(L, 1 + 1 + 1 + 1);
	lua_createtable(L, 0, numTblKeys);

	HSTR_PUSH_NUMBER(L, "id",          cd.id);
	HSTR_PUSH_NUMBER(L, "type",        cd.type);
	HSTR_PUSH_STRING(L, "name",        cd.name);
	HSTR_PUSH_STRING(L, "action",      cd.action);
	HSTR_PUSH_STRING(L, "tooltip",     cd.tooltip);
	HSTR_PUSH_STRING(L, "texture",     cd.iconname);
	HSTR_PUSH_STRING(L, "cursor",      cd.mouseicon);
	HSTR_PUSH_BOOL(L,   "hidden",      cd.hidden);
	HSTR_PUSH_BOOL(L,   "disabled",    cd.disabled);
	HSTR_PUSH_BOOL(L,   "showUnique",  cd.showUnique);
	HSTR_PUSH_BOOL(L,   "onlyTexture", cd.onlyTexture);

	HSTR_PUSH(L, "params");

	lua_createtable(L, 0, numParams);

	for (int p = 0; p < numParams; p++) {
		lua_pushsstring(L, cd.params[p]);
		lua_rawseti(L, -2, p + 1);
	}

	// CmdDesc["params"] = {[1] = "string1", [2] = "string2", ...}
	lua_settable(L, -3);
}
예제 #8
0
bool CLuaHandle::AddBasicCalls()
{
	HSTR_PUSH(L, "Script");
	lua_newtable(L); {
		HSTR_PUSH_CFUNC(L, "Kill",            KillActiveHandle);
		HSTR_PUSH_CFUNC(L, "GetName",         CallOutGetName);
		HSTR_PUSH_CFUNC(L, "GetSynced",       CallOutGetSynced);
		HSTR_PUSH_CFUNC(L, "GetFullCtrl",     CallOutGetFullCtrl);
		HSTR_PUSH_CFUNC(L, "GetFullRead",     CallOutGetFullRead);
		HSTR_PUSH_CFUNC(L, "GetCtrlTeam",     CallOutGetCtrlTeam);
		HSTR_PUSH_CFUNC(L, "GetReadTeam",     CallOutGetReadTeam);
		HSTR_PUSH_CFUNC(L, "GetReadAllyTeam", CallOutGetReadAllyTeam);
		HSTR_PUSH_CFUNC(L, "GetSelectTeam",   CallOutGetSelectTeam);
		HSTR_PUSH_CFUNC(L, "GetGlobal",       CallOutGetGlobal);
		HSTR_PUSH_CFUNC(L, "GetRegistry",     CallOutGetRegistry);
		HSTR_PUSH_CFUNC(L, "GetCallInList",   CallOutGetCallInList);
		// special team constants
		HSTR_PUSH_NUMBER(L, "NO_ACCESS_TEAM",  CEventClient::NoAccessTeam);
		HSTR_PUSH_NUMBER(L, "ALL_ACCESS_TEAM", CEventClient::AllAccessTeam);
//FIXME		LuaArrays::PushEntries(L);
	}
	lua_rawset(L, -3);

	// extra math utilities
	lua_getglobal(L, "math");
	LuaBitOps::PushEntries(L);
	lua_pop(L, 1);
	return true;
}
예제 #9
0
bool CLuaHandle::DefaultCommand(const CUnit* unit,
                                const CFeature* feature, int& cmd)
{
	LUA_CALL_IN_CHECK(L);	
	lua_checkstack(L, 4);
	static const LuaHashString cmdStr("DefaultCommand");
	if (!PushUnsyncedCallIn(cmdStr)) {
		return false;
	}

	int args = 0;
	if (unit) {
		HSTR_PUSH(L, "unit");
		lua_pushnumber(L, unit->id);
		args = 2;
	}
	else if (feature) {
		HSTR_PUSH(L, "feature");
		lua_pushnumber(L, feature->id);
		args = 2;
	}
/* FIXME
	else if (groundPos) {
		HSTR_PUSH(L, "ground");
		lua_pushnumber(L, groundPos->x);
		lua_pushnumber(L, groundPos->y);
		lua_pushnumber(L, groundPos->z);
		args = 4;
	}
	else {
		HSTR_PUSH(L, "selection");
		args = 1;
	}
*/

	// call the routine
	RunCallInUnsynced(cmdStr, args, 1);

	if (!lua_isnumber(L, 1)) {
		lua_pop(L, 1);
		return false;
	}

	cmd = lua_toint(L, -1);
	lua_pop(L, 1);
	return true;
}
예제 #10
0
static int DrawTypeString(lua_State* L, const void* data)
{
	const int drawType = *((const int*)data);
	switch (drawType) {
		case DRAWTYPE_MODEL: { HSTR_PUSH(L,   "model"); break; }
		case DRAWTYPE_NONE:  { HSTR_PUSH(L,    "none"); break; }

		default: {
			if (drawType >= DRAWTYPE_TREE) {
				HSTR_PUSH(L,    "tree");
			} else {
				HSTR_PUSH(L, "unknown");
			}
			break;
		}
	}
	return 1;
}
예제 #11
0
static inline void PushRealTable(lua_State* L, int index, const char* name)
{
	if (lua_getmetatable(L, 1) == 0) {
		luaL_error(L, "Error: using %s() with an invalid table", name);
	}
	HSTR_PUSH(L, "realTable");
	lua_rawget(L, -2);
	if (!lua_istable(L, -1)) {
		luaL_error(L, "Error: using %s() with an invalid table", name);
	}
	return;
}
예제 #12
0
bool LuaSyncedTable::PushEntries(lua_State* L)
{
	HSTR_PUSH(L, "SYNCED");
	lua_pushvalue(L, LUA_GLOBALSINDEX);

	WrapTable(L); // replace the GLOBAL table with a proxy
	lua_rawset(L, -3);

	LuaPushNamedCFunc(L, "snext", Next);
	LuaPushNamedCFunc(L, "spairs", Pairs);
	LuaPushNamedCFunc(L, "sipairs", IPairs);
	
	return true;
}
예제 #13
0
static bool PushSyncedTable(lua_State* L)
{
	HSTR_PUSH(L, "SYNCED");
	lua_newtable(L); { // the proxy table

		lua_newtable(L); { // the metatable
			LuaPushNamedCFunc(L, "__index",     SyncTableIndex);
			LuaPushNamedCFunc(L, "__newindex",  SyncTableNewIndex);
			LuaPushNamedCFunc(L, "__metatable", SyncTableMetatable);
		}

		lua_setmetatable(L, -2);
	}
	lua_rawset(L, -3);

	return true;
}
예제 #14
0
static int ModelTable(lua_State* L, const void* data) {
	const UnitDef* ud = static_cast<const UnitDef*>(data);
	const std::string modelFile = modelParser->FindModelPath(ud->modelName);

	lua_newtable(L);
	HSTR_PUSH_STRING(L, "type", StringToLower(FileSystem::GetExtension(modelFile)));
	HSTR_PUSH_STRING(L, "path", modelFile);
	HSTR_PUSH_STRING(L, "name", ud->modelName);
	HSTR_PUSH(L, "textures");

	lua_newtable(L);
	if (ud->model != NULL) {
		LuaPushNamedString(L, "tex1", ud->model->tex1);
		LuaPushNamedString(L, "tex2", ud->model->tex2);
	}
	lua_rawset(L, -3);
	return 1;
}
예제 #15
0
bool CLuaHandle::MapDrawCmd(int playerID, int type,
                            const float3* pos0,
                            const float3* pos1,
                            const string* label)
{
	if (!CheckModUICtrl()) {
		return false;
	}
	LUA_CALL_IN_CHECK(L);
	lua_checkstack(L, 9);
	static const LuaHashString cmdStr("MapDrawCmd");
	if (!PushUnsyncedCallIn(cmdStr)) {
		return false; // the call is not defined
	}

	int args;

	lua_pushnumber(L, playerID);

	if (type == CInMapDraw::NET_POINT) {
		HSTR_PUSH(L, "point");
		lua_pushnumber(L, pos0->x);
		lua_pushnumber(L, pos0->y);
		lua_pushnumber(L, pos0->z);
		lua_pushstring(L, label->c_str());
		args = 6;
	}
	else if (type == CInMapDraw::NET_LINE) {
		HSTR_PUSH(L, "line");
		lua_pushnumber(L, pos0->x);
		lua_pushnumber(L, pos0->y);
		lua_pushnumber(L, pos0->z);
		lua_pushnumber(L, pos1->x);
		lua_pushnumber(L, pos1->y);
		lua_pushnumber(L, pos1->z);
		args = 8;
	}
	else if (type == CInMapDraw::NET_ERASE) {
		HSTR_PUSH(L, "erase");
		lua_pushnumber(L, pos0->x);
		lua_pushnumber(L, pos0->y);
		lua_pushnumber(L, pos0->z);
		lua_pushnumber(L, 100.0f);  // radius
		args = 6;
	}
	else {
		logOutput.Print("Unknown MapDrawCmd() type");
		lua_pop(L, 2); // pop the function and playerID
		return false;
	}

	// call the routine
	if (!RunCallInUnsynced(cmdStr, args, 1)) {
		return false;
	}

	// take the event?
	if (!lua_isboolean(L, -1)) {
		lua_pop(L, 1);
		return false;
	}
	const bool retval = lua_toboolean(L, -1);
	lua_pop(L, 1);
	return retval;
}
예제 #16
0
bool CLuaHandleSynced::SetupSynced(lua_State *L, const string& code, const string& filename)
{
	if (!IsValid() || code.empty()) {
		return false;
	}

	lua_pushvalue(L, LUA_GLOBALSINDEX);

	HSTR_PUSH(L, "EXPORT");
	lua_newtable(L);
	lua_rawset(L, -3);

	AddBasicCalls(L); // into Global

	lua_pushliteral(L, "Script");
	lua_rawget(L, -2);
	LuaPushNamedCFunc(L, "AddActionFallback",    AddSyncedActionFallback);
	LuaPushNamedCFunc(L, "RemoveActionFallback", RemoveSyncedActionFallback);
	LuaPushNamedCFunc(L, "UpdateCallIn",         CallOutSyncedUpdateCallIn);
	LuaPushNamedCFunc(L, "GetWatchUnit",         GetWatchUnitDef);
	LuaPushNamedCFunc(L, "SetWatchUnit",         SetWatchUnitDef);
	LuaPushNamedCFunc(L, "GetWatchFeature",      GetWatchFeatureDef);
	LuaPushNamedCFunc(L, "SetWatchFeature",      SetWatchFeatureDef);
	LuaPushNamedCFunc(L, "GetWatchWeapon",       GetWatchWeaponDef);
	LuaPushNamedCFunc(L, "SetWatchWeapon",       SetWatchWeaponDef);
	lua_pop(L, 1);

	// add the custom file loader
	LuaPushNamedCFunc(L, "SendToUnsynced", SendToUnsynced);

	LuaPushNamedCFunc(L, "loadstring", LoadStringData);
	LuaPushNamedCFunc(L, "CallAsTeam", CallAsTeam);

	LuaPushNamedNumber(L, "COBSCALE", COBSCALE);

	// load our libraries  (LuaSyncedCtrl overrides some LuaUnsyncedCtrl entries)
	if (!AddEntriesToTable(L, "VFS",         LuaVFS::PushSynced)           ||
		!AddEntriesToTable(L, "VFS",         LuaZipFileReader::PushSynced) ||
		!AddEntriesToTable(L, "VFS",         LuaZipFileWriter::PushSynced) ||
	    !AddEntriesToTable(L, "UnitDefs",    LuaUnitDefs::PushEntries)     ||
	    !AddEntriesToTable(L, "WeaponDefs",  LuaWeaponDefs::PushEntries)   ||
	    !AddEntriesToTable(L, "FeatureDefs", LuaFeatureDefs::PushEntries)  ||
	    !AddEntriesToTable(L, "Script",      LuaSyncedCall::PushEntries)   ||
	    !AddEntriesToTable(L, "Spring",      LuaUnsyncedCtrl::PushEntries) ||
	    !AddEntriesToTable(L, "Spring",      LuaSyncedCtrl::PushEntries)   ||
	    !AddEntriesToTable(L, "Spring",      LuaSyncedRead::PushEntries)   ||
	    !AddEntriesToTable(L, "Game",        LuaConstGame::PushEntries)    ||
	    !AddEntriesToTable(L, "CMD",         LuaConstCMD::PushEntries)     ||
	    !AddEntriesToTable(L, "CMDTYPE",     LuaConstCMDTYPE::PushEntries) ||
	    !AddEntriesToTable(L, "COB",         LuaConstCOB::PushEntries)     ||
	    !AddEntriesToTable(L, "SFX",         LuaConstSFX::PushEntries)     ||
	    !AddEntriesToTable(L, "LOG",         LuaUtils::PushLogEntries)
	) {
		KillLua();
		return false;
	}

	// add code from the sub-class
	if (!AddSyncedCode(L)) {
		KillLua();
		return false;
	}

	lua_settop(L, 0);

	if (!LoadCode(L, code, filename)) {
		KillLua();
		return false;
	}

	return true;
}