void PathFinderOutput::Load(lua_State *l) { if (!lua_istable(l, -1)) { LuaError(l, "incorrect argument in PathFinderOutput::Load"); } const int args = 1 + lua_rawlen(l, -1); for (int i = 1; i < args; ++i) { const char *tag = LuaToString(l, -1, i); ++i; if (!strcmp(tag, "cycles")) { this->Cycles = LuaToNumber(l, -1, i); } else if (!strcmp(tag, "fast")) { this->Fast = 1; --i; } else if (!strcmp(tag, "path")) { lua_rawgeti(l, -1, i); if (!lua_istable(l, -1)) { LuaError(l, "incorrect argument _"); } const int subargs = lua_rawlen(l, -1); for (int k = 0; k < subargs; ++k) { this->Path[k] = LuaToNumber(l, -1, k + 1); } this->Length = subargs; lua_pop(l, 1); } else { LuaError(l, "PathFinderOutput::Load: Unsupported tag: %s" _C_ tag); } } }
void PathFinderInput::Load(lua_State *l) { if (!lua_istable(l, -1)) { LuaError(l, "incorrect argument in PathFinderInput::Load"); } const int args = 1 + lua_rawlen(l, -1); for (int i = 1; i < args; ++i) { const char *tag = LuaToString(l, -1, i); ++i; if (!strcmp(tag, "unit-size")) { lua_rawgeti(l, -1, i); CclGetPos(l, &this->unitSize.x, &this->unitSize.y); lua_pop(l, 1); } else if (!strcmp(tag, "goalpos")) { lua_rawgeti(l, -1, i); CclGetPos(l, &this->goalPos.x, &this->goalPos.y); lua_pop(l, 1); } else if (!strcmp(tag, "goal-size")) { lua_rawgeti(l, -1, i); CclGetPos(l, &this->goalSize.x, &this->goalSize.y); lua_pop(l, 1); } else if (!strcmp(tag, "minrange")) { this->minRange = LuaToNumber(l, -1, i); } else if (!strcmp(tag, "maxrange")) { this->maxRange = LuaToNumber(l, -1, i); } else if (!strcmp(tag, "invalid")) { this->isRecalculatePathNeeded = true; --i; } else { LuaError(l, "PathFinderInput::Load: Unsupported tag: %s" _C_ tag); } } }
/* 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"); } }
/* 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)"); } }
/** ** Get a player's units in rectangle box specified with 2 coordinates ** ** @param l Lua state. ** ** @return Array of units. */ static int CclGetUnitsAroundUnit(lua_State *l) { const int nargs = lua_gettop(l); if (nargs != 2 && nargs != 3) { LuaError(l, "incorrect argument\n"); } const int slot = LuaToNumber(l, 1); const CUnit &unit = UnitManager.GetSlotUnit(slot); const int range = LuaToNumber(l, 2); bool allUnits = false; if (nargs == 3) { allUnits = LuaToBoolean(l, 3); } lua_newtable(l); std::vector<CUnit *> table; if (allUnits) { SelectAroundUnit(unit, range, table, HasNotSamePlayerAs(Players[PlayerNumNeutral])); } else { SelectAroundUnit(unit, range, table, HasSamePlayerAs(*unit.Player)); } size_t n = 0; for (size_t i = 0; i < table.size(); ++i) { if (table[i]->IsAliveOnMap()) { lua_pushnumber(l, UnitNumber(*table[i])); lua_rawseti(l, -2, ++n); } } return 1; }
/** ** Define the group. ** ** @param l Lua state. */ static int CclGroup(lua_State *l) { int i; CUnitGroup *grp; int args; int j; LuaCheckArgs(l, 3); InitGroups(); grp = &Groups[(int)LuaToNumber(l, 1)]; grp->NumUnits = LuaToNumber(l, 2); i = 0; args = lua_objlen(l, 3); for (j = 0; j < args; ++j) { const char *str; lua_rawgeti(l, 3, j + 1); str = LuaToString(l, -1); lua_pop(l, 1); grp->Units[i++] = UnitSlots[strtol(str + 1, NULL, 16)]; } return 0; }
/* virtual */ bool COrder_Built::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit) { if (!strcmp(value, "worker")) { ++j; lua_rawgeti(l, -1, j + 1); this->Worker = CclGetUnitFromRef(l); lua_pop(l, 1); } else if (!strcmp(value, "progress")) { ++j; this->ProgressCounter = LuaToNumber(l, -1, j + 1); } else if (!strcmp(value, "cancel")) { this->IsCancelled = true; } else if (!strcmp(value, "frame")) { ++j; int frame = LuaToNumber(l, -1, j + 1); CConstructionFrame *cframe = unit.Type->Construction->Frames; while (frame-- && cframe->Next != NULL) { cframe = cframe->Next; } this->Frame = cframe; } else { return false; } return true; }
/** ** 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; }
/** ** 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; }
/* virtual */ bool COrder_SpellCast::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit) { if (!strcmp(value, "spell")) { ++j; lua_rawgeti(l, -1, j + 1); this->Spell = SpellTypeByIdent(LuaToString(l, -1)); lua_pop(l, 1); } else if (!strcmp(value, "range")) { ++j; lua_rawgeti(l, -1, j + 1); this->Range = LuaToNumber(l, -1); lua_pop(l, 1); } else if (!strcmp(value, "state")) { ++j; lua_rawgeti(l, -1, j + 1); this->State = LuaToNumber(l, -1); lua_pop(l, 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 { return false; } return true; }
/* static */ void CAnimations::LoadWaitUnitAnim(lua_State *l, CUnit &unit, int luaIndex) { if (!lua_istable(l, luaIndex)) { LuaError(l, "incorrect argument"); } const int nargs = lua_rawlen(l, luaIndex); for (int j = 0; j != nargs; ++j) { const char *value = LuaToString(l, luaIndex, j + 1); ++j; if (!strcmp(value, "anim-wait")) { unit.WaitBackup.Wait = LuaToNumber(l, luaIndex, j + 1); } else if (!strcmp(value, "curr-anim")) { const int animIndex = LuaToNumber(l, luaIndex, j + 1); unit.WaitBackup.CurrAnim = AnimationsArray[animIndex]; } else if (!strcmp(value, "anim")) { const int animIndex = LuaToNumber(l, luaIndex, j + 1); unit.WaitBackup.Anim = Advance(unit.WaitBackup.CurrAnim, animIndex); } else if (!strcmp(value, "unbreakable")) { unit.WaitBackup.Unbreakable = 1; --j; } else { LuaError(l, "Unit anim-data: Unsupported tag: %s" _C_ value); } } }
/* virtual */ bool COrder_Attack::ParseSpecificData(lua_State *l, int &j, const char *value, const CUnit &unit) { if (!strcmp(value, "state")) { ++j; lua_rawgeti(l, -1, j + 1); this->State = LuaToNumber(l, -1); lua_pop(l, 1); } else if (!strcmp(value, "min-range")) { ++j; lua_rawgeti(l, -1, j + 1); this->MinRange = LuaToNumber(l, -1); lua_pop(l, 1); } else if (!strcmp(value, "range")) { ++j; lua_rawgeti(l, -1, j + 1); this->Range = LuaToNumber(l, -1); lua_pop(l, 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 { return false; } return true; }
/** ** 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; }
/** ** 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; }
/* 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; }
/** ** Center the map. ** ** @param l Lua state. */ static int CclCenterMap(lua_State *l) { LuaCheckArgs(l, 2); const Vec2i pos(LuaToNumber(l, 1), LuaToNumber(l, 2)); UI.SelectedViewport->Center(Map.TilePosToMapPixelPos_Center(pos)); return 0; }
/** ** Center the map. ** ** @param l Lua state. */ static int CclCenterMap(lua_State *l) { LuaCheckArgs(l, 2); UI.SelectedViewport->Center( LuaToNumber(l, 1), LuaToNumber(l, 2), TileSizeX / 2, TileSizeY / 2); 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); } } }
/** ** Define the starting viewpoint for a given player. ** ** @param l Lua state. */ static int CclSetStartView(lua_State *l) { LuaCheckArgs(l, 3); const int p = LuaToNumber(l, 1); Players[p].StartPos.x = LuaToNumber(l, 2); Players[p].StartPos.y = LuaToNumber(l, 3); return 0; }
/** ** Define the starting viewpoint for a given player. ** ** @param l Lua state. */ static int CclSetStartView(lua_State *l) { int p; LuaCheckArgs(l, 3); p = LuaToNumber(l, 1); Players[p].StartX = LuaToNumber(l, 2); Players[p].StartY = LuaToNumber(l, 3); return 0; }
/** ** Define a force, a groups of units. ** ** @param l Lua state. */ static int CclAiForce(lua_State *l) { LuaCheckArgs(l, 2); if (!lua_istable(l, 2)) { LuaError(l, "incorrect argument"); } int force = LuaToNumber(l, 1); if (force < 0 || force >= AI_MAX_FORCES) { LuaError(l, "Force out of range: %d" _C_ force); } AiForce &aiforce = AiPlayer->Force[AiPlayer->Force.getScriptForce(force)]; int args = lua_rawlen(l, 2); for (int j = 0; j < args; ++j) { lua_rawgeti(l, 2, j + 1); CUnitType *type = CclGetUnitType(l); lua_pop(l, 1); ++j; lua_rawgeti(l, 2, j + 1); int count = LuaToNumber(l, -1); lua_pop(l, 1); if (!type) { // bulletproof continue; } // Use the equivalent unittype. type = UnitTypes[UnitTypeEquivs[type->Slot]]; // Look if already in force. size_t i; for (i = 0; i < aiforce.UnitTypes.size(); ++i) { AiUnitType *aiut = &aiforce.UnitTypes[i]; if (aiut->Type->Slot == type->Slot) { // found if (count) { aiut->Want = count; } else { aiforce.UnitTypes.erase(aiforce.UnitTypes.begin() + i); } break; } } // New type append it. if (i == aiforce.UnitTypes.size()) { AiUnitType newaiut; newaiut.Want = count; newaiut.Type = type; aiforce.UnitTypes.push_back(newaiut); } } AiAssignFreeUnitsToForce(); lua_pushboolean(l, 0); return 1; }
/** ** Change the shared vision from player to another player. ** ** @param l Lua state. ** ** @return FIXME: should return old state. */ static int CclSetSharedVision(lua_State *l) { LuaCheckArgs(l, 3); const int base = LuaToNumber(l, 1); const bool shared = LuaToBoolean(l, 2); const int plynr = LuaToNumber(l, 3); SendCommandSharedVision(base, shared, plynr); return 0; }
/** ** Set basic map caracteristics. ** ** @param l Lua state. */ static int CclPresentMap(lua_State *l) { LuaCheckArgs(l, 5); Map.Info.Description = LuaToString(l, 1); // Number of players in LuaToNumber(l, 3); // Not used yet. Map.Info.MapWidth = LuaToNumber(l, 3); Map.Info.MapHeight = LuaToNumber(l, 4); Map.Info.MapUID = LuaToNumber(l, 5); return 0; }
/** ** Set the video resolution. ** ** @param l Lua state. */ static int CclSetVideoResolution(lua_State *l) { LuaCheckArgs(l, 2); if (CclInConfigFile) { // May have been set from the command line if (!Video.Width || !Video.Height) { Video.Width = LuaToNumber(l, 1); Video.Height = LuaToNumber(l, 2); } } return 0; }
void CMapField::parse(lua_State *l) { if (!lua_istable(l, -1)) { LuaError(l, "incorrect argument"); } const int len = lua_rawlen(l, -1); if (len < 4) { LuaError(l, "incorrect argument"); } this->tile = LuaToNumber(l, -1, 1); this->playerInfo.SeenTile = LuaToNumber(l, -1, 2); this->Value = LuaToNumber(l, -1, 3); this->cost = LuaToNumber(l, -1, 4); for (int j = 4; j < len; ++j) { const char *value = LuaToString(l, -1, j + 1); if (!strcmp(value, "explored")) { ++j; this->playerInfo.Visible[LuaToNumber(l, -1, j + 1)] = 1; } else if (!strcmp(value, "human")) { this->Flags |= MapFieldHuman; } else if (!strcmp(value, "land")) { this->Flags |= MapFieldLandAllowed; } else if (!strcmp(value, "coast")) { this->Flags |= MapFieldCoastAllowed; } else if (!strcmp(value, "water")) { this->Flags |= MapFieldWaterAllowed; } else if (!strcmp(value, "mud")) { this->Flags |= MapFieldNoBuilding; } else if (!strcmp(value, "block")) { this->Flags |= MapFieldUnpassable; } else if (!strcmp(value, "wall")) { this->Flags |= MapFieldWall; } else if (!strcmp(value, "rock")) { this->Flags |= MapFieldRocks; } else if (!strcmp(value, "wood")) { this->Flags |= MapFieldForest; } else if (!strcmp(value, "ground")) { this->Flags |= MapFieldLandUnit; } else if (!strcmp(value, "air")) { this->Flags |= MapFieldAirUnit; } else if (!strcmp(value, "sea")) { this->Flags |= MapFieldSeaUnit; } else if (!strcmp(value, "building")) { this->Flags |= MapFieldBuilding; } else { LuaError(l, "Unsupported tag: %s" _C_ value); } } }
/** ** 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 player color indexes ** ** @param l Lua state. */ static int CclDefinePlayerColorIndex(lua_State *l) { LuaCheckArgs(l, 2); PlayerColorIndexStart = LuaToNumber(l, 1); PlayerColorIndexCount = LuaToNumber(l, 2); for (int i = 0; i < PlayerMax; ++i) { PlayerColorsRGB[i].clear(); PlayerColorsRGB[i].resize(PlayerColorIndexCount); PlayerColors[i].clear(); PlayerColors[i].resize(PlayerColorIndexCount, 0); } return 0; }
/** ** Parse AiBuildQueue builing list ** ** @param l Lua state. ** @param ai PlayerAi pointer which should be filled with the data. */ static void CclParseBuildQueue(lua_State *l, PlayerAi *ai, int offset) { if (!lua_istable(l, offset)) { LuaError(l, "incorrect argument"); } Vec2i pos(-1, -1); const int args = lua_rawlen(l, offset); for (int k = 0; k < args; ++k) { lua_rawgeti(l, offset, k + 1); const char *value = LuaToString(l, -1); lua_pop(l, 1); ++k; if (!strcmp(value, "onpos")) { lua_rawgeti(l, offset, k + 1); pos.x = LuaToNumber(l, -1); lua_pop(l, 1); ++k; lua_rawgeti(l, offset, k + 1); pos.y = LuaToNumber(l, -1); lua_pop(l, 1); } else { //lua_rawgeti(l, j + 1, k + 1); //ident = LuaToString(l, -1); //lua_pop(l, 1); //++k; lua_rawgeti(l, offset, k + 1); const int made = LuaToNumber(l, -1); lua_pop(l, 1); ++k; lua_rawgeti(l, offset, k + 1); const int want = LuaToNumber(l, -1); lua_pop(l, 1); AiBuildQueue queue; queue.Type = UnitTypeByIdent(value); queue.Want = want; queue.Made = made; queue.Pos = pos; ai->UnitTypeBuilt.push_back(queue); pos.x = -1; pos.y = -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)"); } }
/** ** 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); } } }