/** ** Get world data. ** ** @param l Lua state. */ static int CclGetWorldData(lua_State *l) { if (lua_gettop(l) < 2) { LuaError(l, "incorrect argument"); } std::string world_name = LuaToString(l, 1); CWorld *world = GetWorld(world_name); if (!world) { LuaError(l, "World \"%s\" doesn't exist." _C_ world_name.c_str()); } const char *data = LuaToString(l, 2); if (!strcmp(data, "Name")) { lua_pushstring(l, world->Name.c_str()); return 1; } else if (!strcmp(data, "Description")) { lua_pushstring(l, world->Description.c_str()); return 1; } else if (!strcmp(data, "Background")) { lua_pushstring(l, world->Background.c_str()); return 1; } else if (!strcmp(data, "Quote")) { lua_pushstring(l, world->Quote.c_str()); return 1; } else if (!strcmp(data, "BaseTerrain")) { if (world->BaseTerrain) { lua_pushstring(l, world->BaseTerrain->Name.c_str()); } else { lua_pushstring(l, ""); } return 1; } else if (!strcmp(data, "Plane")) { if (world->Plane) { lua_pushstring(l, world->Plane->Name.c_str()); } else { lua_pushstring(l, ""); } return 1; } else if (!strcmp(data, "Provinces")) { lua_createtable(l, world->Provinces.size(), 0); for (size_t i = 1; i <= world->Provinces.size(); ++i) { lua_pushstring(l, world->Provinces[i-1]->Name.c_str()); lua_rawseti(l, -2, i); } return 1; } else if (!strcmp(data, "Species")) { lua_createtable(l, world->Species.size(), 0); for (size_t i = 1; i <= world->Species.size(); ++i) { lua_pushstring(l, world->Species[i-1]->Ident.c_str()); lua_rawseti(l, -2, i); } return 1; } else { LuaError(l, "Invalid field: %s" _C_ data); } return 0; }
/** ** Define a plane. ** ** @param l Lua state. */ static int CclDefinePlane(lua_State *l) { LuaCheckArgs(l, 2); if (!lua_istable(l, 2)) { LuaError(l, "incorrect argument (expected table)"); } std::string plane_name = LuaToString(l, 1); CPlane *plane = GetPlane(plane_name); if (!plane) { plane = new CPlane; plane->Name = plane_name; plane->ID = Planes.size(); Planes.push_back(plane); } // Parse the list: for (lua_pushnil(l); lua_next(l, 2); lua_pop(l, 1)) { const char *value = LuaToString(l, -2); if (!strcmp(value, "Description")) { plane->Description = LuaToString(l, -1); } else if (!strcmp(value, "Background")) { plane->Background = LuaToString(l, -1); } else if (!strcmp(value, "Quote")) { plane->Quote = LuaToString(l, -1); } else { LuaError(l, "Unsupported tag: %s" _C_ value); } } return 0; }
/* virtual */ void CContentTypeFormattedText::Parse(lua_State *l) { Assert(lua_istable(l, -1)); for (lua_pushnil(l); lua_next(l, -2); lua_pop(l, 1)) { const char *key = LuaToString(l, -2); if (!strcmp(key, "Format")) { this->Format = LuaToString(l, -1); } else if (!strcmp(key, "Font")) { this->Font = CFont::Get(LuaToString(l, -1)); } else if (!strcmp(key, "Variable")) { const char *const name = LuaToString(l, -1); this->Index = UnitTypeVar.VariableNameLookup[name]; if (this->Index == -1) { LuaError(l, "unknown variable '%s'" _C_ name); } } else if (!strcmp(key, "Component")) { this->Component = Str2EnumVariable(l, LuaToString(l, -1)); } else if (!strcmp(key, "Centered")) { this->Centered = LuaToBoolean(l, -1); } else { LuaError(l, "'%s' invalid for method 'FormattedText' in DefinePanelContents" _C_ key); } } }
/** ** Parse the Condition for spell. ** ** @param l Lua state. ** @param autocast pointer to autocast to fill with data. ** ** @note: autocast must be allocated. All data already in is LOST. */ static void CclSpellAutocast(lua_State *l, AutoCastInfo *autocast) { if (!lua_istable(l, -1)) { LuaError(l, "incorrect argument"); } const int args = lua_rawlen(l, -1); for (int j = 0; j < args; ++j) { lua_rawgeti(l, -1, j + 1); const char *value = LuaToString(l, -1); lua_pop(l, 1); ++j; if (!strcmp(value, "range")) { lua_rawgeti(l, -1, j + 1); autocast->Range = LuaToNumber(l, -1); lua_pop(l, 1); } else if (!strcmp(value, "combat")) { lua_rawgeti(l, -1, j + 1); autocast->Combat = Ccl2Condition(l, LuaToString(l, -1)); lua_pop(l, 1); } else if (!strcmp(value, "condition")) { if (!autocast->Condition) { autocast->Condition = new ConditionInfo; } lua_rawgeti(l, -1, j + 1); CclSpellCondition(l, autocast->Condition); lua_pop(l, 1); } else { LuaError(l, "Unsupported autocast tag: %s" _C_ value); } } }
/** ** Create a sound. ** ** Glue between c and scheme. This function asks the sound system to ** register a sound under a given name, wiht an associated list of files ** (the list can be replaced by only one file). ** ** @param l Lua state. ** ** @return the sound id of the created sound */ static int CclMakeSound(lua_State *l) { LuaCheckArgs(l, 2); std::string c_name = LuaToString(l, 1); std::vector<std::string> files; CSound *id; if (lua_isstring(l, 2)) { // only one file files.push_back(LuaToString(l, 2)); id = MakeSound(c_name, files); } else if (lua_istable(l, 2)) { // several files const int args = lua_rawlen(l, 2); files.reserve(args); for (int j = 0; j < args; ++j) { lua_rawgeti(l, 2, j + 1); files.push_back(LuaToString(l, -1)); lua_pop(l, 1); } id = MakeSound(c_name, files); } else { LuaError(l, "string or table expected"); return 0; } LuaUserData *data = (LuaUserData *)lua_newuserdata(l, sizeof(LuaUserData)); data->Type = LuaSoundType; data->Data = id; return 1; }
/* virtual */ void Spell_Summon::Parse(lua_State *l, int startIndex, int endIndex) { for (int j = startIndex; j < endIndex; ++j) { const char *value = LuaToString(l, -1, j + 1); ++j; if (!strcmp(value, "unit-type")) { value = LuaToString(l, -1, j + 1); this->UnitType = UnitTypeByIdent(value); if (!this->UnitType) { this->UnitType = 0; DebugPrint("unit type \"%s\" not found for summon spell.\n" _C_ value); } } else if (!strcmp(value, "time-to-live")) { this->TTL = LuaToNumber(l, -1, j + 1); } else if (!strcmp(value, "require-corpse")) { this->RequireCorpse = true; --j; } else if (!strcmp(value, "join-to-ai-force")) { this->JoinToAiForce = true; --j; } else { LuaError(l, "Unsupported summon tag: %s" _C_ value); } } // Now, checking value. if (this->UnitType == NULL) { LuaError(l, "Use a unittype for summon (with unit-type)"); } }
void CTileset::parse(lua_State *l) { clear(); this->pixelTileSize.x = 32; this->pixelTileSize.y = 32; const int args = lua_gettop(l); for (int j = 1; j < args; ++j) { const char *value = LuaToString(l, j); ++j; if (!strcmp(value, "name")) { this->Name = LuaToString(l, j); } else if (!strcmp(value, "image")) { this->ImageFile = LuaToString(l, j); } else if (!strcmp(value, "size")) { CclGetPos(l, &this->pixelTileSize.x, &this->pixelTileSize.y, j); } else if (!strcmp(value, "slots")) { if (!lua_istable(l, j)) { LuaError(l, "incorrect argument"); } parseSlots(l, j); } else { LuaError(l, "Unsupported tag: %s" _C_ value); } } }
/** ** Define race names ** ** @param l Lua state. */ static int CclDefineRaceNames(lua_State *l) { PlayerRaces.Clean(); int args = lua_gettop(l); for (int j = 0; j < args; ++j) { const char *value = LuaToString(l, j + 1); if (!strcmp(value, "race")) { ++j; if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } int subargs = lua_rawlen(l, j + 1); int i = PlayerRaces.Count++; for (int k = 0; k < subargs; ++k) { value = LuaToString(l, j + 1, k + 1); if (!strcmp(value, "name")) { ++k; PlayerRaces.Name[i] = LuaToString(l, j + 1, k + 1); } else if (!strcmp(value, "display")) { ++k; PlayerRaces.Display[i] = LuaToString(l, j + 1, k + 1); } else if (!strcmp(value, "visible")) { PlayerRaces.Visible[i] = 1; } else { LuaError(l, "Unsupported tag: %s" _C_ value); } } } else { LuaError(l, "Unsupported tag: %s" _C_ value); } } return 0; }
/* virtual */ void Spell_Polymorph::Parse(lua_State *l, int startIndex, int endIndex) { for (int j = startIndex; j < endIndex; ++j) { lua_rawgeti(l, -1, j + 1); const char *value = LuaToString(l, -1); lua_pop(l, 1); ++j; if (!strcmp(value, "new-form")) { lua_rawgeti(l, -1, j + 1); value = LuaToString(l, -1); lua_pop(l, 1); this->NewForm = UnitTypeByIdent(value); if (!this->NewForm) { this->NewForm = 0; DebugPrint("unit type \"%s\" not found for polymorph spell.\n" _C_ value); } // FIXME: temp polymorphs? hard to do. } else if (!strcmp(value, "player-neutral")) { this->PlayerNeutral = 1; --j; } else if (!strcmp(value, "player-caster")) { this->PlayerNeutral = 2; --j; } else { LuaError(l, "Unsupported polymorph tag: %s" _C_ value); } } // Now, checking value. if (this->NewForm == NULL) { LuaError(l, "Use a unittype for polymorph (with new-form)"); } }
/* virtual */ void Spell_SpawnPortal::Parse(lua_State *l, int startIndex, int endIndex) { for (int j = startIndex; j < endIndex; ++j) { lua_rawgeti(l, -1, j + 1); const char *value = LuaToString(l, -1); lua_pop(l, 1); ++j; if (!strcmp(value, "portal-type")) { lua_rawgeti(l, -1, j + 1); value = LuaToString(l, -1); lua_pop(l, 1); this->PortalType = UnitTypeByIdent(value); if (!this->PortalType) { this->PortalType = 0; DebugPrint("unit type \"%s\" not found for spawn-portal.\n" _C_ value); } } else { LuaError(l, "Unsupported spawn-portal tag: %s" _C_ value); } } // Now, checking value. if (this->PortalType == NULL) { LuaError(l, "Use a unittype for spawn-portal (with portal-type)"); } }
/* virtual */ void Spell_AreaBombardment::Parse(lua_State *l, int startIndex, int endIndex) { for (int j = startIndex; j < endIndex; ++j) { const char *value = LuaToString(l, -1, j + 1); ++j; if (!strcmp(value, "fields")) { this->Fields = LuaToNumber(l, -1, j + 1); } else if (!strcmp(value, "shards")) { this->Shards = LuaToNumber(l, -1, j + 1); } else if (!strcmp(value, "damage")) { this->Damage = LuaToNumber(l, -1, j + 1); } else if (!strcmp(value, "start-offset-x")) { this->StartOffsetX = LuaToNumber(l, -1, j + 1); } else if (!strcmp(value, "start-offset-y")) { this->StartOffsetY = LuaToNumber(l, -1, j + 1); } else if (!strcmp(value, "missile")) { value = LuaToString(l, -1, j + 1); this->Missile = MissileTypeByIdent(value); if (this->Missile == NULL) { DebugPrint("in area-bombardement : missile %s does not exist\n" _C_ value); } } else { LuaError(l, "Unsupported area-bombardment tag: %s" _C_ value); } } // Now, checking value. if (this->Missile == NULL) { LuaError(l, "Use a missile for area-bombardment (with missile)"); } }
/** ** Define burning building missiles. ** ** @param l Lua state. */ static int CclDefineBurningBuilding(lua_State *l) { for (std::vector<BurningBuildingFrame *>::iterator i = BurningBuildingFrames.begin(); i != BurningBuildingFrames.end(); ++i) { delete *i; } BurningBuildingFrames.clear(); const int args = lua_gettop(l); for (int j = 0; j < args; ++j) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } BurningBuildingFrame *ptr = new BurningBuildingFrame; const int subargs = lua_rawlen(l, j + 1); for (int k = 0; k < subargs; ++k) { const char *value = LuaToString(l, j + 1, k + 1); ++k; if (!strcmp(value, "percent")) { ptr->Percent = LuaToNumber(l, j + 1, k + 1); } else if (!strcmp(value, "missile")) { ptr->Missile = MissileTypeByIdent(LuaToString(l, j + 1, k + 1)); } } BurningBuildingFrames.insert(BurningBuildingFrames.begin(), ptr); } return 0; }
/** ** Load the SavedGameInfo Header ** ** @param l Lua state. */ static int CclSavedGameInfo(lua_State *l) { const char *value; LuaCheckArgs(l, 1); LuaCheckTable(l, 1); lua_pushnil(l); while (lua_next(l, 1)) { value = LuaToString(l, -2); if (!strcmp(value, "SaveFile")) { if (strcpy_s(CurrentMapPath, sizeof(CurrentMapPath), LuaToString(l, -1)) != 0) { LuaError(l, "SaveFile too long"); } std::string buf = StratagusLibPath; buf += "/"; buf += LuaToString(l, -1); if (LuaLoadFile(buf) == -1) { DebugPrint("Load failed: %s\n" _C_ value); } } else if (!strcmp(value, "SyncHash")) { SyncHash = LuaToNumber(l, -1); } else if (!strcmp(value, "SyncRandSeed")) { SyncRandSeed = LuaToNumber(l, -1); } else { LuaError(l, "Unsupported tag: %s" _C_ value); } lua_pop(l, 1); } return 0; }
/* virtual */ void CContentTypeLifeBar::Parse(lua_State *l) { for (lua_pushnil(l); lua_next(l, -2); lua_pop(l, 1)) { const char *key = LuaToString(l, -2); if (!strcmp(key, "Variable")) { const char *const name = LuaToString(l, -1); this->Index = UnitTypeVar.VariableNameLookup[name]; if (this->Index == -1) { LuaError(l, "unknown variable '%s'" _C_ name); } } else if (!strcmp(key, "Height")) { this->Height = LuaToNumber(l, -1); } else if (!strcmp(key, "Width")) { this->Width = LuaToNumber(l, -1); } else { LuaError(l, "'%s' invalid for method 'LifeBar' in DefinePanelContents" _C_ key); } } // Default value and checking errors. if (this->Height <= 0) { this->Height = 5; // Default value. } if (this->Width <= 0) { this->Width = 50; // Default value. } if (this->Index == -1) { LuaError(l, "variable undefined for LifeBar"); } }
/** ** Get province data. ** ** @param l Lua state. */ static int CclGetProvinceData(lua_State *l) { if (lua_gettop(l) < 2) { LuaError(l, "incorrect argument"); } std::string province_name = LuaToString(l, 1); CProvince *province = GetProvince(province_name); if (!province) { LuaError(l, "Province \"%s\" doesn't exist." _C_ province_name.c_str()); } const char *data = LuaToString(l, 2); if (!strcmp(data, "Name")) { lua_pushstring(l, province->Name.c_str()); return 1; } else if (!strcmp(data, "World")) { if (province->World != nullptr) { lua_pushstring(l, province->World->Ident.c_str()); } else { lua_pushstring(l, ""); } return 1; } else if (!strcmp(data, "Water")) { lua_pushboolean(l, province->Water); return 1; } else if (!strcmp(data, "Coastal")) { lua_pushboolean(l, province->Coastal); return 1; } else { LuaError(l, "Invalid field: %s" _C_ data); } return 0; }
/** ** Parse an animation */ static CAnimation *ParseAnimation(lua_State *l, int idx) { if (!lua_istable(l, idx)) { LuaError(l, "incorrect argument"); } const int args = lua_rawlen(l, idx); if (args == 0) { return NULL; } Labels.clear(); LabelsLater.clear(); const char *str = LuaToString(l, idx, 1); CAnimation *firstAnim = ParseAnimationFrame(l, str); CAnimation *prev = firstAnim; for (int j = 1; j < args; ++j) { const char *str = LuaToString(l, idx, j + 1); CAnimation *anim = ParseAnimationFrame(l, str); prev->Next = anim; prev = anim; } prev->Next = firstAnim; FixLabels(l); return firstAnim; }
/** ** Define a new dependency. ** ** @param l Lua state. */ static int CclDefineDependency(lua_State *l) { const char *target; const char *required; int count; const char *value; int or_flag; int args; int j; int subargs; int k; args = lua_gettop(l); j = 0; target = LuaToString(l, j + 1); ++j; // // All or rules. // or_flag = 0; for (; j < args; ++j) { if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } subargs = lua_objlen(l, j + 1); for (k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); required = LuaToString(l, -1); lua_pop(l, 1); count = 1; if (k + 1 < subargs) { lua_rawgeti(l, j + 1, k + 2); if (lua_isnumber(l, -1)) { count = LuaToNumber(l, -1); ++k; } lua_pop(l, 1); } AddDependency(target, required, count, or_flag); or_flag = 0; } if (j + 1 < args) { ++j; value = LuaToString(l, j + 1); if (strcmp(value, "or")) { LuaError(l, "not or symbol: %s" _C_ value); return 0; } or_flag = 1; } } return 0; }
/** ** Get province data. ** ** @param l Lua state. */ static int CclGetProvinceData(lua_State *l) { if (lua_gettop(l) < 2) { LuaError(l, "incorrect argument"); } std::string province_name = LuaToString(l, 1); CProvince *province = GetProvince(province_name); if (!province) { LuaError(l, "Province \"%s\" doesn't exist." _C_ province_name.c_str()); } const char *data = LuaToString(l, 2); if (!strcmp(data, "Name")) { lua_pushstring(l, province->Name.c_str()); return 1; } else if (!strcmp(data, "World")) { if (province->World != NULL) { lua_pushstring(l, province->World->Name.c_str()); } else { lua_pushstring(l, ""); } return 1; } else if (!strcmp(data, "Water")) { lua_pushboolean(l, province->Water); return 1; } else if (!strcmp(data, "Coastal")) { lua_pushboolean(l, province->Coastal); return 1; } else if (!strcmp(data, "Map")) { lua_pushstring(l, province->Map.c_str()); return 1; } else if (!strcmp(data, "SettlementTerrain")) { lua_pushstring(l, province->SettlementTerrain.c_str()); return 1; } else if (!strcmp(data, "SettlementLocationX")) { lua_pushnumber(l, province->SettlementLocation.x); return 1; } else if (!strcmp(data, "SettlementLocationY")) { lua_pushnumber(l, province->SettlementLocation.y); return 1; } else if (!strcmp(data, "Tiles")) { lua_createtable(l, province->Tiles.size() * 2, 0); for (size_t i = 1; i <= province->Tiles.size() * 2; ++i) { lua_pushnumber(l, province->Tiles[(i-1) / 2].x); lua_rawseti(l, -2, i); ++i; lua_pushnumber(l, province->Tiles[(i-1) / 2].y); lua_rawseti(l, -2, i); } return 1; } else { LuaError(l, "Invalid field: %s" _C_ data); } return 0; }
/** ** Parse the Condition for spell. ** ** @param l Lua state. ** @param autocast pointer to autocast to fill with data. ** ** @note: autocast must be allocated. All data already in is LOST. */ static void CclSpellAutocast(lua_State *l, AutoCastInfo *autocast) { if (!lua_istable(l, -1)) { LuaError(l, "incorrect argument"); } const int args = lua_rawlen(l, -1); for (int j = 0; j < args; ++j) { const char *value = LuaToString(l, -1, j + 1); ++j; if (!strcmp(value, "range")) { autocast->Range = LuaToNumber(l, -1, j + 1); } else if (!strcmp(value, "min-range")) { autocast->MinRange = LuaToNumber(l, -1, j + 1); } else if (!strcmp(value, "position-autocast")) { lua_rawgeti(l, -1, j + 1); autocast->PositionAutoCast = new LuaCallback(l, -1); lua_pop(l, 1); } else if (!strcmp(value, "combat")) { autocast->Combat = Ccl2Condition(l, LuaToString(l, -1, j + 1)); } else if (!strcmp(value, "attacker")) { autocast->Attacker = Ccl2Condition(l, LuaToString(l, -1, j + 1)); } else if (!strcmp(value, "corpse")) { autocast->Corpse = Ccl2Condition(l, LuaToString(l, -1, j + 1)); } else if (!strcmp(value, "priority")) { lua_rawgeti(l, -1, j + 1); if (!lua_istable(l, -1) || lua_rawlen(l, -1) != 2) { LuaError(l, "incorrect argument"); } lua_rawgeti(l, -1, 1); std::string var = LuaToString(l, -1); int index = UnitTypeVar.VariableNameLookup[var.c_str()];// User variables if (index == -1) { if (!strcmp(var.c_str(), "Distance")) { index = ACP_DISTANCE; } else { fprintf(stderr, "Bad variable name '%s'\n", var.c_str()); Exit(1); } } autocast->PriorytyVar = index; lua_pop(l, 1); autocast->ReverseSort = LuaToBoolean(l, -1, 2); lua_pop(l, 1); } else if (!strcmp(value, "condition")) { if (!autocast->Condition) { autocast->Condition = new ConditionInfo; } lua_rawgeti(l, -1, j + 1); CclSpellCondition(l, autocast->Condition); lua_pop(l, 1); } else { LuaError(l, "Unsupported autocast tag: %s" _C_ value); } } }
/* virtual */ void CContentTypeIcon::Parse(lua_State *l) { for (lua_pushnil(l); lua_next(l, -2); lua_pop(l, 1)) { const char *key = LuaToString(l, -2); if (!strcmp(key, "Unit")) { this->UnitRef = Str2EnumUnit(l, LuaToString(l, -1)); } else { LuaError(l, "'%s' invalid for method 'Icon' in DefinePanelContents" _C_ key); } } }
/** ** Load a file and execute it. ** ** @param l Lua state. ** ** @return 0 in success, else exit. */ static int CclLoad(lua_State *l) { char buf[1024]; LuaCheckArgs(l, 1); LibraryFileName(LuaToString(l, 1), buf, sizeof(buf)); if (LuaLoadFile(buf) == -1) { DebugPrint("Load failed: %s\n" _C_ LuaToString(l, 1)); } return 0; }
/** ** Parse the missile location description for a spell action. ** ** @param l Lua state. ** @param location Pointer to missile location description. ** ** @note This is only here to avoid code duplication. You don't have ** any reason to USE this:) */ static void CclSpellMissileLocation(lua_State *l, SpellActionMissileLocation *location) { const char *value; int args; int j; Assert(location != NULL); if (!lua_istable(l, -1)) { LuaError(l, "incorrect argument"); } args = lua_objlen(l, -1); j = 0; for (j = 0; j < args; ++j) { lua_rawgeti(l, -1, j + 1); value = LuaToString(l, -1); lua_pop(l, 1); ++j; if (!strcmp(value, "base")) { lua_rawgeti(l, -1, j + 1); value = LuaToString(l, -1); lua_pop(l, 1); if (!strcmp(value, "caster")) { location->Base = LocBaseCaster; } else if (!strcmp(value, "target")) { location->Base = LocBaseTarget; } else { LuaError(l, "Unsupported missile location base flag: %s" _C_ value); } } else if (!strcmp(value, "add-x")) { lua_rawgeti(l, -1, j + 1); location->AddX = LuaToNumber(l, -1); lua_pop(l, 1); } else if (!strcmp(value, "add-y")) { lua_rawgeti(l, -1, j + 1); location->AddY = LuaToNumber(l, -1); lua_pop(l, 1); } else if (!strcmp(value, "add-rand-x")) { lua_rawgeti(l, -1, j + 1); location->AddRandX = LuaToNumber(l, -1); lua_pop(l, 1); } else if (!strcmp(value, "add-rand-y")) { lua_rawgeti(l, -1, j + 1); location->AddRandY = LuaToNumber(l, -1); lua_pop(l, 1); } else { LuaError(l, "Unsupported missile location description flag: %s" _C_ value); } } }
/** ** Define race names ** ** @param l Lua state. */ static int CclDefineRaceNames(lua_State *l) { int i; int j; int k; int args; int subargs; const char *value; PlayerRaces.Count = 0; args = lua_gettop(l); for (j = 0; j < args; ++j) { value = LuaToString(l, j + 1); if (!strcmp(value, "race")) { ++j; if (!lua_istable(l, j + 1)) { LuaError(l, "incorrect argument"); } subargs = luaL_getn(l, j + 1); i = PlayerRaces.Count++; PlayerRaces.Name[i] = NULL; PlayerRaces.Display[i] = NULL; PlayerRaces.Visible[i] = 0; for (k = 0; k < subargs; ++k) { lua_rawgeti(l, j + 1, k + 1); value = LuaToString(l, -1); lua_pop(l, 1); if (!strcmp(value, "name")) { ++k; lua_rawgeti(l, j + 1, k + 1); PlayerRaces.Name[i] = new_strdup(LuaToString(l, -1)); lua_pop(l, 1); } else if (!strcmp(value, "display")) { ++k; lua_rawgeti(l, j + 1, k + 1); PlayerRaces.Display[i] = new_strdup(LuaToString(l, -1)); lua_pop(l, 1); } else if (!strcmp(value, "visible")) { PlayerRaces.Visible[i] = 1; } else { LuaError(l, "Unsupported tag: %s" _C_ value); } } } else { LuaError(l, "Unsupported tag: %s" _C_ value); } } return 0; }
/** ** Load the lua file which will define the tile models ** ** @param l Lua state. */ static int CclLoadTileModels(lua_State *l) { char buf[1024]; if (lua_gettop(l) != 1) { LuaError(l, "incorrect argument"); } strcpy_s(Map.TileModelsFileName, sizeof(Map.TileModelsFileName), LuaToString(l, 1)); LibraryFileName(Map.TileModelsFileName, buf, sizeof(buf)); if (LuaLoadFile(buf) == -1) { DebugPrint("Load failed: %s\n" _C_ LuaToString(l, 1)); } return 0; }
/** ** Define the Panels. ** Define what is shown in the panel(text, icon, variables) ** ** @param l Lua state. ** @return 0. */ static int CclDefinePanelContents(lua_State *l) { const int nargs = lua_gettop(l); for (int i = 0; i < nargs; i++) { Assert(lua_istable(l, i + 1)); CUnitInfoPanel *infopanel = new CUnitInfoPanel; for (lua_pushnil(l); lua_next(l, i + 1); lua_pop(l, 1)) { const char *key = LuaToString(l, -2); if (!strcmp(key, "Ident")) { infopanel->Name = LuaToString(l, -1); } else if (!strcmp(key, "Pos")) { CclGetPos(l, &infopanel->PosX, &infopanel->PosY); } else if (!strcmp(key, "DefaultFont")) { infopanel->DefaultFont = CFont::Get(LuaToString(l, -1)); } else if (!strcmp(key, "Condition")) { infopanel->Condition = ParseConditionPanel(l); } else if (!strcmp(key, "Contents")) { Assert(lua_istable(l, -1)); for (size_t j = 0; j < lua_rawlen(l, -1); j++, lua_pop(l, 1)) { lua_rawgeti(l, -1, j + 1); infopanel->Contents.push_back(CclParseContent(l)); } } else { LuaError(l, "'%s' invalid for DefinePanelContents" _C_ key); } } for (std::vector<CContentType *>::iterator content = infopanel->Contents.begin(); content != infopanel->Contents.end(); ++content) { // Default value for invalid value. (*content)->Pos.x += infopanel->PosX; (*content)->Pos.y += infopanel->PosY; } size_t j; for (j = 0; j < UI.InfoPanelContents.size(); ++j) { if (infopanel->Name == UI.InfoPanelContents[j]->Name) { DebugPrint("Redefinition of Panel '%s'\n" _C_ infopanel->Name.c_str()); delete UI.InfoPanelContents[j]; UI.InfoPanelContents[j] = infopanel; break; } } if (j == UI.InfoPanelContents.size()) { UI.InfoPanelContents.push_back(infopanel); } } return 0; }
/* virtual */ bool COrder_Build::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit) { if (!strcmp(value, "building")) { ++j; lua_rawgeti(l, -1, j + 1); this->BuildingUnit = CclGetUnitFromRef(l); lua_pop(l, 1); } else if (!strcmp(value, "range")) { ++j; this->Range = LuaToNumber(l, -1, j + 1); } else if (!strcmp(value, "state")) { ++j; this->State = LuaToNumber(l, -1, j + 1); } else if (!strcmp(value, "tile")) { ++j; lua_rawgeti(l, -1, j + 1); CclGetPos(l, &this->goalPos.x , &this->goalPos.y); lua_pop(l, 1); } else if (!strcmp(value, "type")) { ++j; this->Type = UnitTypeByIdent(LuaToString(l, -1, j + 1)); } else { return false; } return true; }
/** ** Define the lua file that will build the map ** ** @param l Lua state. */ static int CclDefineMapSetup(lua_State *l) { LuaCheckArgs(l, 1); Map.Info.Filename = LuaToString(l, 1); return 0; }
/** ** Define the viewports. ** ** @param l Lua state. */ static int CclDefineViewports(lua_State *l) { int i = 0; const int args = lua_gettop(l); for (int j = 0; j < args; ++j) { const char *value = LuaToString(l, j + 1); ++j; if (!strcmp(value, "mode")) { UI.ViewportMode = (ViewportModeType)LuaToNumber(l, j + 1); } else if (!strcmp(value, "viewport")) { if (!lua_istable(l, j + 1) && lua_rawlen(l, j + 1) != 3) { LuaError(l, "incorrect argument"); } UI.Viewports[i].MapPos.x = LuaToNumber(l, j + 1, 1); UI.Viewports[i].MapPos.y = LuaToNumber(l, j + 1, 2); const int slot = LuaToNumber(l, j + 1, 3); if (slot != -1) { UI.Viewports[i].Unit = &UnitManager.GetSlotUnit(slot); } ++i; } else { LuaError(l, "Unsupported tag: %s" _C_ value); } } UI.NumViewports = i; return 0; }
/** ** Show Map Location ** ** @param l Lua state. */ static int CclShowMapLocation(lua_State *l) { // Put a unit on map, use its properties, except for // what is listed below LuaCheckArgs(l, 4); const char *unitname = LuaToString(l, 5); CUnitType *unitType = UnitTypeByIdent(unitname); if (!unitType) { DebugPrint("Unable to find UnitType '%s'" _C_ unitname); return 0; } CUnit *target = MakeUnit(*unitType, ThisPlayer); if (target != NULL) { target->Variable[HP_INDEX].Value = 0; target->tilePos.x = LuaToNumber(l, 1); target->tilePos.y = LuaToNumber(l, 2); target->TTL = GameCycle + LuaToNumber(l, 4); target->CurrentSightRange = LuaToNumber(l, 3); //Wyrmgus start UpdateUnitSightRange(*target); //Wyrmgus end MapMarkUnitSight(*target); } else { DebugPrint("Unable to allocate Unit"); } return 0; }
/** ** Check if the tile's terrain has a particular flag. ** ** @param l Lua state. ** ** @return True if has the flag, false if not. */ static int CclGetTileTerrainHasFlag(lua_State *l) { LuaCheckArgs(l, 3); const Vec2i pos(LuaToNumber(l, 1), LuaToNumber(l, 2)); //Wyrmgus start if (pos.x < 0 || pos.x >= Map.Info.MapWidth || pos.y < 0 || pos.y >= Map.Info.MapHeight) { lua_pushboolean(l, 0); return 1; } // unsigned short flag = 0; unsigned long flag = 0; //Wyrmgus end const char *flag_name = LuaToString(l, 3); if (!strcmp(flag_name, "water")) { flag = MapFieldWaterAllowed; } else if (!strcmp(flag_name, "land")) { flag = MapFieldLandAllowed; } else if (!strcmp(flag_name, "coast")) { flag = MapFieldCoastAllowed; } else if (!strcmp(flag_name, "no-building")) { flag = MapFieldNoBuilding; } else if (!strcmp(flag_name, "unpassable")) { flag = MapFieldUnpassable; //Wyrmgus start } else if (!strcmp(flag_name, "air-unpassable")) { flag = MapFieldAirUnpassable; } else if (!strcmp(flag_name, "dirt")) { flag = MapFieldDirt; } else if (!strcmp(flag_name, "grass")) { flag = MapFieldGrass; } else if (!strcmp(flag_name, "gravel")) { flag = MapFieldGravel; } else if (!strcmp(flag_name, "mud")) { flag = MapFieldMud; } else if (!strcmp(flag_name, "stone-floor")) { flag = MapFieldStoneFloor; } else if (!strcmp(flag_name, "stumps")) { flag = MapFieldStumps; //Wyrmgus end } else if (!strcmp(flag_name, "wall")) { flag = MapFieldWall; } else if (!strcmp(flag_name, "rock")) { flag = MapFieldRocks; } else if (!strcmp(flag_name, "forest")) { flag = MapFieldForest; } const CMapField &mf = *Map.Field(pos); if (mf.getFlag() & flag) { lua_pushboolean(l, 1); } else { lua_pushboolean(l, 0); } return 1; }