/** ** 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); } } }
/** ** 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); } } }
/** ** Parse the condition Panel. ** ** @param l Lua State. */ static ConditionPanel *ParseConditionPanel(lua_State *l) { Assert(lua_istable(l, -1)); ConditionPanel *condition = new ConditionPanel; for (lua_pushnil(l); lua_next(l, -2); lua_pop(l, 1)) { const char *key = LuaToString(l, -2); if (!strcmp(key, "ShowOnlySelected")) { condition->ShowOnlySelected = LuaToBoolean(l, -1); } else if (!strcmp(key, "HideNeutral")) { condition->HideNeutral = LuaToBoolean(l, -1); } else if (!strcmp(key, "HideAllied")) { condition->HideAllied = LuaToBoolean(l, -1); } else if (!strcmp(key, "ShowOpponent")) { condition->ShowOpponent = LuaToBoolean(l, -1); } else { int index = UnitTypeVar.BoolFlagNameLookup[key]; if (index != -1) { if (!condition->BoolFlags) { size_t new_bool_size = UnitTypeVar.GetNumberBoolFlag(); condition->BoolFlags = new char[new_bool_size]; memset(condition->BoolFlags, 0, new_bool_size * sizeof(char)); } condition->BoolFlags[index] = Ccl2Condition(l, LuaToString(l, -1)); continue; } index = UnitTypeVar.VariableNameLookup[key]; if (index != -1) { if (!condition->Variables) { size_t new_variables_size = UnitTypeVar.GetNumberVariable(); condition->Variables = new char[new_variables_size]; memset(condition->Variables, 0, new_variables_size * sizeof(char)); } condition->Variables[index] = Ccl2Condition(l, LuaToString(l, -1)); continue; } LuaError(l, "'%s' invalid for Condition in DefinePanelContents" _C_ key); } } return condition; }
/** ** Parse the Condition for spell. ** ** @param l Lua state. ** @param condition pointer to condition to fill with data. ** ** @note Conditions must be allocated. All data already in is LOST. */ static void CclSpellCondition(lua_State *l, ConditionInfo *condition) { // Flags are defaulted to 0(CONDITION_TRUE) size_t new_bool_size = UnitTypeVar.GetNumberBoolFlag(); condition->BoolFlag = new char[new_bool_size]; memset(condition->BoolFlag, 0, new_bool_size * sizeof(char)); condition->Variable = new ConditionInfoVariable[UnitTypeVar.GetNumberVariable()]; // Initialize min/max stuff to values with no effect. for (unsigned int i = 0; i < UnitTypeVar.GetNumberVariable(); i++) { condition->Variable[i].Check = false; condition->Variable[i].MinValue = -1; condition->Variable[i].MaxValue = -1; condition->Variable[i].MinMax = -1; condition->Variable[i].MinValuePercent = -8; condition->Variable[i].MaxValuePercent = 1024; } // Now parse the list and set values. 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, "alliance")) { lua_rawgeti(l, -1, j + 1); condition->Alliance = Ccl2Condition(l, LuaToString(l, -1)); lua_pop(l, 1); } else if (!strcmp(value, "opponent")) { lua_rawgeti(l, -1, j + 1); condition->Opponent = Ccl2Condition(l, LuaToString(l, -1)); lua_pop(l, 1); } else if (!strcmp(value, "self")) { lua_rawgeti(l, -1, j + 1); condition->TargetSelf = Ccl2Condition(l, LuaToString(l, -1)); lua_pop(l, 1); } else { int index = UnitTypeVar.BoolFlagNameLookup[value]; if (index != -1) { lua_rawgeti(l, -1, j + 1); condition->BoolFlag[index] = Ccl2Condition(l, LuaToString(l, -1)); lua_pop(l, 1); continue; } index = UnitTypeVar.VariableNameLookup[value]; if (index != -1) { // Valid index. lua_rawgeti(l, -1, j + 1); if (!lua_istable(l, -1)) { LuaError(l, "Table expected in variable in condition"); } for (lua_pushnil(l); lua_next(l, -2); lua_pop(l, 1)) { const char *const key = LuaToString(l, -2); condition->Variable[index].Check = true; if (!strcmp(key, "Enable")) { condition->Variable[index].Enable = Ccl2Condition(l, LuaToString(l, -1)); } else if (!strcmp(key, "MinValue")) { condition->Variable[index].MinValue = LuaToNumber(l, -1); } else if (!strcmp(key, "MaxValue")) { condition->Variable[index].MaxValue = LuaToNumber(l, -1); } else if (!strcmp(key, "MinMax")) { condition->Variable[index].MinMax = LuaToNumber(l, -1); } else if (!strcmp(key, "MinValuePercent")) { condition->Variable[index].MinValuePercent = LuaToNumber(l, -1); } else if (!strcmp(key, "MaxValuePercent")) { condition->Variable[index].MaxValuePercent = LuaToNumber(l, -1); } else if (!strcmp(key, "ConditionApplyOnCaster")) { condition->Variable[index].ConditionApplyOnCaster = LuaToBoolean(l, -1); } else { // Error LuaError(l, "%s invalid for Variable in condition" _C_ key); } } lua_pop(l, 1); // lua_rawgeti() continue; } LuaError(l, "Unsuported condition tag: %s" _C_ value); } } }
/** ** Parse the Condition for spell. ** ** @param l Lua state. ** @param condition pointer to condition to fill with data. ** ** @note Conditions must be allocated. All data already in is LOST. */ static void CclSpellCondition(lua_State *l, ConditionInfo *condition) { // Flags are defaulted to 0(CONDITION_TRUE) size_t new_bool_size = UnitTypeVar.GetNumberBoolFlag(); condition->BoolFlag = new char[new_bool_size]; memset(condition->BoolFlag, 0, new_bool_size * sizeof(char)); condition->Variable = new ConditionInfoVariable[UnitTypeVar.GetNumberVariable()]; // Initialize min/max stuff to values with no effect. for (unsigned int i = 0; i < UnitTypeVar.GetNumberVariable(); i++) { condition->Variable[i].Check = false; condition->Variable[i].ExactValue = -1; condition->Variable[i].ExceptValue = -1; condition->Variable[i].MinValue = -1; condition->Variable[i].MaxValue = -1; condition->Variable[i].MinMax = -1; condition->Variable[i].MinValuePercent = -8; condition->Variable[i].MaxValuePercent = 1024; } // Now parse the list and set values. 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, "alliance")) { condition->Alliance = Ccl2Condition(l, LuaToString(l, -1, j + 1)); } else if (!strcmp(value, "opponent")) { condition->Opponent = Ccl2Condition(l, LuaToString(l, -1, j + 1)); } else if (!strcmp(value, "self")) { condition->TargetSelf = Ccl2Condition(l, LuaToString(l, -1, j + 1)); } else if (!strcmp(value, "callback")) { lua_rawgeti(l, -1, j + 1); condition->CheckFunc = new LuaCallback(l, -1); lua_pop(l, 1); //Wyrmgus start } else if (!strcmp(value, "thrusting-weapon")) { condition->ThrustingWeapon = Ccl2Condition(l, LuaToString(l, -1, j + 1)); } else if (!strcmp(value, "faction-unit")) { condition->FactionUnit = Ccl2Condition(l, LuaToString(l, -1, j + 1)); } else if (!strcmp(value, "faction-equivalent")) { value = LuaToString(l, -1, j + 1); int civilization = PlayerRaces.GetRaceIndexByName(value); if (civilization != -1) { ++j; value = LuaToString(l, -1, j + 1); int faction = PlayerRaces.GetFactionIndexByName(civilization, value); if (faction != -1) { condition->FactionEquivalent = const_cast<CFaction *>(&(*PlayerRaces.Factions[civilization][faction]));; } else { fprintf(stderr, "Faction %s doesn't exist.\n", value); } } else { fprintf(stderr, "Civilization %s doesn't exist.\n", value); } //Wyrmgus end } else { int index = UnitTypeVar.BoolFlagNameLookup[value]; if (index != -1) { condition->BoolFlag[index] = Ccl2Condition(l, LuaToString(l, -1, j + 1)); continue; } index = UnitTypeVar.VariableNameLookup[value]; if (index != -1) { // Valid index. lua_rawgeti(l, -1, j + 1); if (!lua_istable(l, -1)) { LuaError(l, "Table expected in variable in condition"); } for (lua_pushnil(l); lua_next(l, -2); lua_pop(l, 1)) { const char *const key = LuaToString(l, -2); condition->Variable[index].Check = true; if (!strcmp(key, "Enable")) { condition->Variable[index].Enable = Ccl2Condition(l, LuaToString(l, -1)); } else if (!strcmp(key, "ExactValue")) { condition->Variable[index].ExactValue = LuaToNumber(l, -1); } else if (!strcmp(key, "ExceptValue")) { condition->Variable[index].ExceptValue = LuaToNumber(l, -1); } else if (!strcmp(key, "MinValue")) { condition->Variable[index].MinValue = LuaToNumber(l, -1); } else if (!strcmp(key, "MaxValue")) { condition->Variable[index].MaxValue = LuaToNumber(l, -1); } else if (!strcmp(key, "MinMax")) { condition->Variable[index].MinMax = LuaToNumber(l, -1); } else if (!strcmp(key, "MinValuePercent")) { condition->Variable[index].MinValuePercent = LuaToNumber(l, -1); } else if (!strcmp(key, "MaxValuePercent")) { condition->Variable[index].MaxValuePercent = LuaToNumber(l, -1); } else if (!strcmp(key, "ConditionApplyOnCaster")) { condition->Variable[index].ConditionApplyOnCaster = LuaToBoolean(l, -1); } else { // Error LuaError(l, "%s invalid for Variable in condition" _C_ key); } } lua_pop(l, 1); // lua_rawgeti() continue; } LuaError(l, "Unsuported condition tag: %s" _C_ value); } } }