From 81a302755725fef3eb226a61340911d3e5db085f Mon Sep 17 00:00:00 2001 From: Andrettin Date: Thu, 10 Jan 2019 18:55:20 +0100 Subject: [PATCH] Unit type variations are now stored in a vector instead of an array --- src/include/stratagus.h | 1 - src/include/unit/unit.h | 10 +- src/include/unit/unittype.h | 57 +++--- src/map/map_layer.cpp | 4 +- src/map/mapfield.cpp | 4 +- src/sound/unitsound.cpp | 33 ++-- src/ui/botpanel.cpp | 4 +- src/ui/mainscr.cpp | 8 +- src/unit/script_unit.cpp | 13 +- src/unit/script_unittype.cpp | 127 ++++++------- src/unit/unit.cpp | 293 +++++++++++++++++------------ src/unit/unit_draw.cpp | 110 ++++------- src/unit/unittype.cpp | 351 +++++++++++++++++------------------ src/upgrade/upgrade.cpp | 113 +++++------ 14 files changed, 564 insertions(+), 564 deletions(-) diff --git a/src/include/stratagus.h b/src/include/stratagus.h index 12876f033..c366e6ac6 100644 --- a/src/include/stratagus.h +++ b/src/include/stratagus.h @@ -164,7 +164,6 @@ extern const char NameLine[]; #define MAX_RACES 128 #define FactionMax 128 /// Maximum number of factions a civilization can have #define PlayerColorMax 32 /// How many player colors are supported -#define VariationMax 32 /// Maximum number of variations a unit can have #define AuraRange 6 /// Range of auras #define PlayerHeroMax 4 /// Maximum heroes per player diff --git a/src/include/unit/unit.h b/src/include/unit/unit.h index 500fe2a70..c0a709a73 100644 --- a/src/include/unit/unit.h +++ b/src/include/unit/unit.h @@ -202,10 +202,12 @@ class CUnit void Retrain(); void HealingItemAutoUse(); void SetCharacter(const std::string &character_full_name, bool custom_hero = false); - bool CheckTerrainForVariation(const VariationInfo *varinfo) const; - bool CheckSeasonForVariation(const VariationInfo *varinfo) const; + bool CheckTerrainForVariation(const CUnitTypeVariation *variation) const; + bool CheckSeasonForVariation(const CUnitTypeVariation *variation) const; void ChooseVariation(const CUnitType *new_type = nullptr, bool ignore_old_variation = false, int image_layer = -1); - void SetVariation(int new_variation, const CUnitType *new_type = nullptr, int image_layer = -1); + void SetVariation(CUnitTypeVariation *new_variation, const CUnitType *new_type = nullptr, int image_layer = -1); + const CUnitTypeVariation *GetVariation() const; + const CUnitTypeVariation *GetLayerVariation(const unsigned int image_layer) const; void UpdateButtonIcons(); void ChooseButtonIcon(int button_action); void EquipItem(CUnit &item, bool affect_character = true); @@ -403,7 +405,7 @@ class CUnit bool CanAutoCastSpell(const CSpell *spell) const; bool IsItemEquipped(const CUnit *item) const; bool IsItemClassEquipped(int item_class) const; - bool IsItemTypeEquipped(CUnitType *item_type) const; + bool IsItemTypeEquipped(const CUnitType *item_type) const; bool IsUniqueItemEquipped(const CUniqueItem *unique) const; bool CanEquipItem(CUnit *item) const; bool CanEquipItemClass(int item_class) const; diff --git a/src/include/unit/unittype.h b/src/include/unit/unittype.h index a46b66353..03e95532e 100644 --- a/src/include/unit/unittype.h +++ b/src/include/unit/unittype.h @@ -134,47 +134,46 @@ class ResourceInfo //Wyrmgus start //unit variations -class VariationInfo +class CUnitTypeVariation { public: - VariationInfo() : - FrameWidth(0), FrameHeight(0), ResourceMin(0), ResourceMax(0), Weight(1), - Animations(nullptr), Construction(nullptr), Sprite(nullptr), ShadowSprite(nullptr), LightSprite(nullptr) + CUnitTypeVariation() { memset(LayerSprites, 0, sizeof(LayerSprites)); memset(SpriteWhenLoaded, 0, sizeof(SpriteWhenLoaded)); memset(SpriteWhenEmpty, 0, sizeof(SpriteWhenEmpty)); } - ~VariationInfo(); + ~CUnitTypeVariation(); + int ID = -1; /// The variation's index within the appropriate variation vector of its unit type std::string VariationId; /// Variation's name. std::string TypeName; /// Type name. std::string File; /// Variation's graphics. std::string ShadowFile; /// Variation's shadow graphics. std::string LightFile; /// Variation's light graphics. - int FrameWidth; - int FrameHeight; - int ResourceMin; - int ResourceMax; - int Weight; /// The weight for when randomly choosing a variation - IconConfig Icon; /// Icon to display for this unit - CPlayerColorGraphic *Sprite; /// The graphic corresponding to File. - CGraphic *ShadowSprite; /// The graphic corresponding to ShadowFile. - CGraphic *LightSprite; /// The graphic corresponding to LightFile. - CAnimations *Animations; /// Animation scripts - CConstruction *Construction; /// What is shown in construction phase - - std::string UpgradesRequired[VariationMax]; /// Upgrades required by variation - std::string UpgradesForbidden[VariationMax]; /// If player has one of these upgrades, unit can't have this variation + int FrameWidth = 0; + int FrameHeight = 0; + int ResourceMin = 0; + int ResourceMax = 0; + int Weight = 1; /// The weight for when randomly choosing a variation + IconConfig Icon; /// Icon to display for this unit + CPlayerColorGraphic *Sprite = nullptr; /// The graphic corresponding to File. + CGraphic *ShadowSprite = nullptr; /// The graphic corresponding to ShadowFile. + CGraphic *LightSprite = nullptr; /// The graphic corresponding to LightFile. + CAnimations *Animations = nullptr; /// Animation scripts + CConstruction *Construction = nullptr; /// What is shown in construction phase + + std::vector UpgradesRequired; /// Upgrades required by variation + std::vector UpgradesForbidden; /// If the player has one of these upgrades, the unit can't have this variation std::vector ItemClassesEquipped; std::vector ItemClassesNotEquipped; - std::vector ItemsEquipped; - std::vector ItemsNotEquipped; - std::vector Terrains; - std::vector TerrainsForbidden; - std::vector Seasons; - std::vector ForbiddenSeasons; + std::vector ItemsEquipped; + std::vector ItemsNotEquipped; + std::vector Terrains; + std::vector TerrainsForbidden; + std::vector Seasons; + std::vector ForbiddenSeasons; std::string LayerFiles[MaxImageLayers]; /// Variation's layer graphics. std::string FileWhenLoaded[MaxCosts]; /// Change the graphic when the unit is loaded. @@ -907,8 +906,8 @@ class CUnitType void UpdateDefaultBoolFlags(); int GetAvailableLevelUpUpgrades() const; int GetResourceStep(const int resource, const int player) const; - VariationInfo *GetDefaultVariation(CPlayer &player, int image_layer = -1) const; - VariationInfo *GetVariation(const std::string &variation_name, int image_layer = -1) const; + CUnitTypeVariation *GetDefaultVariation(CPlayer &player, int image_layer = -1) const; + CUnitTypeVariation *GetVariation(const std::string &variation_name, int image_layer = -1) const; std::string GetRandomVariationIdent(int image_layer = -1) const; std::string GetDefaultName(CPlayer &player) const; CPlayerColorGraphic *GetDefaultLayerSprite(CPlayer &player, int image_layer) const; @@ -1103,9 +1102,9 @@ class CUnitType int GrandStrategyProductionEfficiencyModifier[MaxCosts]; /// production modifier for a particular resource for grand strategy mode (used for buildings) //Wyrmgus end ResourceInfo *ResInfo[MaxCosts]; /// Resource information. + std::vector Variations; /// Variation information //Wyrmgus start - VariationInfo *VarInfo[VariationMax]; /// Variation information. - std::vector LayerVarInfo[MaxImageLayers]; /// Layer variation information. + std::vector LayerVariations[MaxImageLayers]; /// Layer variation information //Wyrmgus end std::vector BuildingRules; /// Rules list for building a building. std::vector AiBuildingRules; /// Rules list for for AI to build a building. diff --git a/src/map/map_layer.cpp b/src/map/map_layer.cpp index 8f37bb1ae..815065403 100644 --- a/src/map/map_layer.cpp +++ b/src/map/map_layer.cpp @@ -446,8 +446,8 @@ void CMapLayer::SetSeason(CScheduledSeason *season) if ( unit && unit->IsAlive() && unit->MapLayer == this ) { - VariationInfo *varinfo = unit->Type->VarInfo[unit->Variation]; - if (varinfo && !unit->CheckSeasonForVariation(varinfo)) { + const CUnitTypeVariation *variation = unit->GetVariation(); + if (variation && !unit->CheckSeasonForVariation(variation)) { unit->ChooseVariation(); //choose a new variation, as the old one has become invalid due to the season change } } diff --git a/src/map/mapfield.cpp b/src/map/mapfield.cpp index d695dbbf1..24c1b79c3 100644 --- a/src/map/mapfield.cpp +++ b/src/map/mapfield.cpp @@ -233,8 +233,8 @@ void CMapField::SetTerrain(CTerrainType *terrain_type) this->Flags |= MapFieldUnpassable; this->Flags |= MapFieldAirUnpassable; } - VariationInfo *varinfo = unit.Type->VarInfo[unit.Variation]; - if (varinfo && !unit.CheckTerrainForVariation(varinfo)) { // if a unit that is on the tile has a terrain-dependent variation that is not compatible with the current variation, repick the unit's variation + const CUnitTypeVariation *variation = unit.GetVariation(); + if (variation && !unit.CheckTerrainForVariation(variation)) { // if a unit that is on the tile has a terrain-dependent variation that is not compatible with the current variation, repick the unit's variation unit.ChooseVariation(); } } diff --git a/src/sound/unitsound.cpp b/src/sound/unitsound.cpp index 3c2f1b8e2..148962614 100644 --- a/src/sound/unitsound.cpp +++ b/src/sound/unitsound.cpp @@ -135,30 +135,29 @@ static void MapAnimSounds(CUnitType &type) MapAnimSounds2(type.Animations->Harvest[i]); } //Wyrmgus start - for (int var_i = 0; var_i < VariationMax; ++var_i) { - VariationInfo *varinfo = type.VarInfo[var_i]; - if (!varinfo) { + for (CUnitTypeVariation *variation : type.Variations) { + if (!variation) { continue; } - if (!varinfo->Animations) { + if (!variation->Animations) { continue; } - MapAnimSounds2(varinfo->Animations->Start); - MapAnimSounds2(varinfo->Animations->Still); - MapAnimSounds2(varinfo->Animations->Move); - MapAnimSounds2(varinfo->Animations->Attack); - MapAnimSounds2(varinfo->Animations->RangedAttack); - MapAnimSounds2(varinfo->Animations->SpellCast); + MapAnimSounds2(variation->Animations->Start); + MapAnimSounds2(variation->Animations->Still); + MapAnimSounds2(variation->Animations->Move); + MapAnimSounds2(variation->Animations->Attack); + MapAnimSounds2(variation->Animations->RangedAttack); + MapAnimSounds2(variation->Animations->SpellCast); for (int i = 0; i <= ANIMATIONS_DEATHTYPES; ++i) { - MapAnimSounds2(varinfo->Animations->Death[i]); + MapAnimSounds2(variation->Animations->Death[i]); } - MapAnimSounds2(varinfo->Animations->Repair); - MapAnimSounds2(varinfo->Animations->Train); - MapAnimSounds2(varinfo->Animations->Research); - MapAnimSounds2(varinfo->Animations->Upgrade); - MapAnimSounds2(varinfo->Animations->Build); + MapAnimSounds2(variation->Animations->Repair); + MapAnimSounds2(variation->Animations->Train); + MapAnimSounds2(variation->Animations->Research); + MapAnimSounds2(variation->Animations->Upgrade); + MapAnimSounds2(variation->Animations->Build); for (int i = 0; i < MaxCosts; ++i) { - MapAnimSounds2(varinfo->Animations->Harvest[i]); + MapAnimSounds2(variation->Animations->Harvest[i]); } } //Wyrmgus end diff --git a/src/ui/botpanel.cpp b/src/ui/botpanel.cpp index d0969b5ac..d2e046aa2 100644 --- a/src/ui/botpanel.cpp +++ b/src/ui/botpanel.cpp @@ -1178,8 +1178,8 @@ void CButtonPanel::Draw() button_icon = Selected[0]->UnitInside->GetButtonIcon(buttons[i].Action); } else if (buttons[i].Icon.Name.empty() && Selected[0]->GetButtonIcon(buttons[i].Action) != nullptr) { button_icon = Selected[0]->GetButtonIcon(buttons[i].Action); - } else if (buttons[i].Action == ButtonExperienceUpgradeTo && Selected[0]->Type->VarInfo[Selected[0]->Variation] && UnitTypes[buttons[i].Value]->GetVariation(Selected[0]->Type->VarInfo[Selected[0]->Variation]->VariationId) != nullptr && !UnitTypes[buttons[i].Value]->GetVariation(Selected[0]->Type->VarInfo[Selected[0]->Variation]->VariationId)->Icon.Name.empty()) { - button_icon = UnitTypes[buttons[i].Value]->GetVariation(Selected[0]->Type->VarInfo[Selected[0]->Variation]->VariationId)->Icon.Icon; + } else if (buttons[i].Action == ButtonExperienceUpgradeTo && Selected[0]->GetVariation() && UnitTypes[buttons[i].Value]->GetVariation(Selected[0]->GetVariation()->VariationId) != nullptr && !UnitTypes[buttons[i].Value]->GetVariation(Selected[0]->GetVariation()->VariationId)->Icon.Name.empty()) { + button_icon = UnitTypes[buttons[i].Value]->GetVariation(Selected[0]->GetVariation()->VariationId)->Icon.Icon; } else if ((buttons[i].Action == ButtonTrain || buttons[i].Action == ButtonBuild || buttons[i].Action == ButtonUpgradeTo || buttons[i].Action == ButtonExperienceUpgradeTo) && buttons[i].Icon.Name.empty() && UnitTypes[buttons[i].Value]->GetDefaultVariation(*ThisPlayer) != nullptr && !UnitTypes[buttons[i].Value]->GetDefaultVariation(*ThisPlayer)->Icon.Name.empty()) { button_icon = UnitTypes[buttons[i].Value]->GetDefaultVariation(*ThisPlayer)->Icon.Icon; } else if ((buttons[i].Action == ButtonTrain || buttons[i].Action == ButtonBuild || buttons[i].Action == ButtonUpgradeTo || buttons[i].Action == ButtonExperienceUpgradeTo) && buttons[i].Icon.Name.empty() && !UnitTypes[buttons[i].Value]->Icon.Name.empty()) { diff --git a/src/ui/mainscr.cpp b/src/ui/mainscr.cpp index 1a5ec55a6..f8439560b 100644 --- a/src/ui/mainscr.cpp +++ b/src/ui/mainscr.cpp @@ -517,9 +517,9 @@ static void DrawUnitInfo_Training(const CUnit &unit) if (UI.SingleTrainingButton) { const COrder_Train &order = *static_cast(unit.CurrentOrder()); //Wyrmgus sta - VariationInfo *varinfo = order.GetUnitType().GetDefaultVariation(*ThisPlayer); + CUnitTypeVariation *variation = order.GetUnitType().GetDefaultVariation(*ThisPlayer); // CIcon &icon = *order.GetUnitType().Icon.Icon; - CIcon &icon = (varinfo && varinfo->Icon.Icon) ? *varinfo->Icon.Icon : *order.GetUnitType().Icon.Icon; + CIcon &icon = (variation && variation->Icon.Icon) ? *variation->Icon.Icon : *order.GetUnitType().Icon.Icon; //Wyrmgus end //Wyrmgus start // const unsigned int flags = (ButtonAreaUnderCursor == ButtonAreaTraining && ButtonUnderCursor == 0) ? @@ -556,8 +556,8 @@ static void DrawUnitInfo_Training(const CUnit &unit) if (j >= UI.TrainingButtons.size()) { break; } - VariationInfo *varinfo = order.GetUnitType().GetDefaultVariation(*ThisPlayer); - CIcon &icon = (varinfo && varinfo->Icon.Icon) ? *varinfo->Icon.Icon : *order.GetUnitType().Icon.Icon; + CUnitTypeVariation *variation = order.GetUnitType().GetDefaultVariation(*ThisPlayer); + CIcon &icon = (variation && variation->Icon.Icon) ? *variation->Icon.Icon : *order.GetUnitType().Icon.Icon; //Wyrmgus start // const int flag = (ButtonAreaUnderCursor == ButtonAreaTraining int flag = (ButtonAreaUnderCursor == ButtonAreaTraining diff --git a/src/unit/script_unit.cpp b/src/unit/script_unit.cpp index 637d55a4f..9a9c599f6 100644 --- a/src/unit/script_unit.cpp +++ b/src/unit/script_unit.cpp @@ -1965,15 +1965,20 @@ static int CclSetUnitVariable(lua_State *l) } else if (!strcmp(name, "CustomHero")) { unit->SetCharacter(LuaToString(l, 3), true); } else if (!strcmp(name, "Variation")) { - value = LuaToNumber(l, 3); - unit->SetVariation(value); - unit->Variable[VARIATION_INDEX].Value = unit->Variation; + size_t variation_index = LuaToNumber(l, 3); + if (variation_index >= 0 && variation_index < unit->Type->Variations.size()) { + unit->SetVariation(unit->Type->Variations[variation_index]); + unit->Variable[VARIATION_INDEX].Value = unit->Variation; + } } else if (!strcmp(name, "LayerVariation")) { LuaCheckArgs(l, 4); std::string image_layer_name = LuaToString(l, 3); int image_layer = GetImageLayerIdByName(image_layer_name); if (image_layer != -1) { - unit->SetVariation(LuaToNumber(l, 4), nullptr, image_layer); + size_t variation_index = LuaToNumber(l, 4); + if (variation_index >= 0 && variation_index < unit->Type->LayerVariations[image_layer].size()) { + unit->SetVariation(unit->Type->LayerVariations[image_layer][variation_index], nullptr, image_layer); + } } else { LuaError(l, "Image layer \"%s\" doesn't exist." _C_ image_layer_name.c_str()); } diff --git a/src/unit/script_unittype.cpp b/src/unit/script_unittype.cpp index 59aed7149..d93d4589c 100644 --- a/src/unit/script_unittype.cpp +++ b/src/unit/script_unittype.cpp @@ -727,26 +727,22 @@ static int CclDefineUnitType(lua_State *l) } else if (!strcmp(value, "Variations")) { type->DefaultStat.Variables[VARIATION_INDEX].Enable = 1; type->DefaultStat.Variables[VARIATION_INDEX].Value = 0; - type->DefaultStat.Variables[VARIATION_INDEX].Max = VariationMax; //remove previously defined variations, if any - for (int var_n = 0; var_n < VariationMax; ++var_n) { - if (type->VarInfo[var_n]) { - delete type->VarInfo[var_n]; - type->VarInfo[var_n] = nullptr; - } + for (CUnitTypeVariation *variation : type->Variations) { + delete variation; } + type->Variations.clear(); //remove previously defined layer variations, if any for (int i = 0; i < MaxImageLayers; ++i) { - for (size_t j = 0; j < type->LayerVarInfo[i].size(); ++j) { - delete type->LayerVarInfo[i][j]; + for (CUnitTypeVariation *variation : type->LayerVariations[i]) { + delete variation; } - type->LayerVarInfo[i].clear(); + type->LayerVariations[i].clear(); } - int variation_count = 0; const int args = lua_rawlen(l, -1); for (int j = 0; j < args; ++j) { lua_rawgeti(l, -1, j + 1); - VariationInfo *var = new VariationInfo; + CUnitTypeVariation *variation = new CUnitTypeVariation; if (!lua_istable(l, -1)) { LuaError(l, "incorrect argument (expected table for variations)"); } @@ -759,78 +755,81 @@ static int CclDefineUnitType(lua_State *l) std::string image_layer_name = LuaToString(l, -1, k + 1); image_layer = GetImageLayerIdByName(image_layer_name); if (image_layer != -1) { - type->LayerVarInfo[image_layer].push_back(var); + variation->ID = type->LayerVariations[image_layer].size(); + type->LayerVariations[image_layer].push_back(variation); } else { LuaError(l, "Image layer \"%s\" doesn't exist." _C_ image_layer_name.c_str()); } } else if (!strcmp(value, "variation-id")) { - var->VariationId = LuaToString(l, -1, k + 1); + variation->VariationId = LuaToString(l, -1, k + 1); if (image_layer == -1) { - type->VarInfo[variation_count] = var; - variation_count += 1; + variation->ID = type->Variations.size(); + type->Variations.push_back(variation); } } else if (!strcmp(value, "type-name")) { - var->TypeName = LuaToString(l, -1, k + 1); + variation->TypeName = LuaToString(l, -1, k + 1); } else if (!strcmp(value, "file")) { - var->File = LuaToString(l, -1, k + 1); + variation->File = LuaToString(l, -1, k + 1); } else if (!strcmp(value, "file-when-loaded")) { const int res = GetResourceIdByName(LuaToString(l, -1, k + 1)); ++k; - var->FileWhenLoaded[res] = LuaToString(l, -1, k + 1); + variation->FileWhenLoaded[res] = LuaToString(l, -1, k + 1); } else if (!strcmp(value, "file-when-empty")) { const int res = GetResourceIdByName(LuaToString(l, -1, k + 1)); ++k; - var->FileWhenEmpty[res] = LuaToString(l, -1, k + 1); + variation->FileWhenEmpty[res] = LuaToString(l, -1, k + 1); } else if (!strcmp(value, "shadow-file")) { - var->ShadowFile = LuaToString(l, -1, k + 1); + variation->ShadowFile = LuaToString(l, -1, k + 1); } else if (!strcmp(value, "light-file")) { - var->LightFile = LuaToString(l, -1, k + 1); + variation->LightFile = LuaToString(l, -1, k + 1); } else if (!strcmp(value, "layer-file")) { int image_layer = GetImageLayerIdByName(LuaToString(l, -1, k + 1)); ++k; - var->LayerFiles[image_layer] = LuaToString(l, -1, k + 1); + variation->LayerFiles[image_layer] = LuaToString(l, -1, k + 1); } else if (!strcmp(value, "frame-size")) { lua_rawgeti(l, -1, k + 1); - CclGetPos(l, &var->FrameWidth, &var->FrameHeight); + CclGetPos(l, &variation->FrameWidth, &variation->FrameHeight); lua_pop(l, 1); } else if (!strcmp(value, "icon")) { - var->Icon.Name = LuaToString(l, -1, k + 1); - var->Icon.Icon = nullptr; - var->Icon.Load(); - var->Icon.Icon->Load(); + variation->Icon.Name = LuaToString(l, -1, k + 1); + variation->Icon.Icon = nullptr; + variation->Icon.Load(); + variation->Icon.Icon->Load(); } else if (!strcmp(value, "button-icon")) { int button_action = GetButtonActionIdByName(LuaToString(l, -1, k + 1)); ++k; - var->ButtonIcons[button_action].Name = LuaToString(l, -1, k + 1); - var->ButtonIcons[button_action].Icon = nullptr; - var->ButtonIcons[button_action].Load(); - var->ButtonIcons[button_action].Icon->Load(); + variation->ButtonIcons[button_action].Name = LuaToString(l, -1, k + 1); + variation->ButtonIcons[button_action].Icon = nullptr; + variation->ButtonIcons[button_action].Load(); + variation->ButtonIcons[button_action].Icon->Load(); } else if (!strcmp(value, "animations")) { - var->Animations = AnimationsByIdent(LuaToString(l, -1, k + 1)); - if (!var->Animations) { + variation->Animations = AnimationsByIdent(LuaToString(l, -1, k + 1)); + if (!variation->Animations) { DebugPrint("Warning animation '%s' not found\n" _C_ LuaToString(l, -1, k + 1)); } } else if (!strcmp(value, "construction")) { - var->Construction = ConstructionByIdent(LuaToString(l, -1, k + 1)); + variation->Construction = ConstructionByIdent(LuaToString(l, -1, k + 1)); } else if (!strcmp(value, "upgrade-required")) { - for (int u = 0; u < VariationMax; ++u) { - if (var->UpgradesRequired[u].empty()) { - var->UpgradesRequired[u] = LuaToString(l, -1, k + 1); - break; - } + const std::string upgrade_ident = LuaToString(l, -1, k + 1); + const CUpgrade *upgrade = CUpgrade::Get(upgrade_ident); + if (upgrade != nullptr) { + variation->UpgradesRequired.push_back(upgrade); + } else { + variation->UpgradesRequired.push_back(CUpgrade::New(upgrade_ident)); //if this upgrade doesn't exist, define it now (this is useful if the unit type is defined before the upgrade) } } else if (!strcmp(value, "upgrade-forbidden")) { - for (int u = 0; u < VariationMax; ++u) { - if (var->UpgradesForbidden[u].empty()) { - var->UpgradesForbidden[u] = LuaToString(l, -1, k + 1); - break; - } + const std::string upgrade_ident = LuaToString(l, -1, k + 1); + const CUpgrade *upgrade = CUpgrade::Get(upgrade_ident); + if (upgrade != nullptr) { + variation->UpgradesForbidden.push_back(upgrade); + } else { + variation->UpgradesForbidden.push_back(CUpgrade::New(upgrade_ident)); //if this upgrade doesn't exist, define it now (this is useful if the unit type is defined before the upgrade) } } else if (!strcmp(value, "item-class-equipped")) { std::string item_class_ident = LuaToString(l, -1, k + 1); int item_class = GetItemClassIdByName(item_class_ident); if (item_class != -1) { - var->ItemClassesEquipped.push_back(item_class); + variation->ItemClassesEquipped.push_back(item_class); } else { LuaError(l, "Item class \"%s\" does not exist." _C_ item_class_ident.c_str()); } @@ -838,7 +837,7 @@ static int CclDefineUnitType(lua_State *l) std::string item_class_ident = LuaToString(l, -1, k + 1); int item_class = GetItemClassIdByName(item_class_ident); if (item_class != -1) { - var->ItemClassesNotEquipped.push_back(item_class); + variation->ItemClassesNotEquipped.push_back(item_class); } else { LuaError(l, "Item class \"%s\" does not exist." _C_ item_class_ident.c_str()); } @@ -846,7 +845,7 @@ static int CclDefineUnitType(lua_State *l) std::string type_ident = LuaToString(l, -1, k + 1); CUnitType *type = UnitTypeByIdent(type_ident); if (type) { - var->ItemsEquipped.push_back(type); + variation->ItemsEquipped.push_back(type); } else { LuaError(l, "Unit type %s not defined" _C_ type_ident.c_str()); } @@ -854,7 +853,7 @@ static int CclDefineUnitType(lua_State *l) std::string type_ident = LuaToString(l, -1, k + 1); CUnitType *type = UnitTypeByIdent(type_ident); if (type) { - var->ItemsNotEquipped.push_back(type); + variation->ItemsNotEquipped.push_back(type); } else { LuaError(l, "Unit type %s not defined" _C_ type_ident.c_str()); } @@ -862,7 +861,7 @@ static int CclDefineUnitType(lua_State *l) std::string terrain_ident = LuaToString(l, -1, k + 1); CTerrainType *terrain = CTerrainType::GetTerrainType(terrain_ident); if (terrain) { - var->Terrains.push_back(terrain); + variation->Terrains.push_back(terrain); } else { LuaError(l, "Terrain type \"%s\" doesn't exist." _C_ terrain_ident.c_str()); } @@ -870,7 +869,7 @@ static int CclDefineUnitType(lua_State *l) std::string terrain_ident = LuaToString(l, -1, k + 1); CTerrainType *terrain = CTerrainType::GetTerrainType(terrain_ident); if (terrain) { - var->TerrainsForbidden.push_back(terrain); + variation->TerrainsForbidden.push_back(terrain); } else { LuaError(l, "Terrain type \"%s\" doesn't exist." _C_ terrain_ident.c_str()); } @@ -878,28 +877,30 @@ static int CclDefineUnitType(lua_State *l) const std::string season_ident = LuaToString(l, -1, k + 1); CSeason *season = CSeason::GetSeason(season_ident); if (season) { - var->Seasons.push_back(season); + variation->Seasons.push_back(season); } } else if (!strcmp(value, "forbidden-season")) { const std::string season_ident = LuaToString(l, -1, k + 1); CSeason *season = CSeason::GetSeason(season_ident); if (season) { - var->ForbiddenSeasons.push_back(season); + variation->ForbiddenSeasons.push_back(season); } } else if (!strcmp(value, "resource-min")) { - var->ResourceMin = LuaToNumber(l, -1, k + 1); + variation->ResourceMin = LuaToNumber(l, -1, k + 1); } else if (!strcmp(value, "resource-max")) { - var->ResourceMax = LuaToNumber(l, -1, k + 1); + variation->ResourceMax = LuaToNumber(l, -1, k + 1); } else if (!strcmp(value, "weight")) { - var->Weight = LuaToNumber(l, -1, k + 1); + variation->Weight = LuaToNumber(l, -1, k + 1); } else { printf("\n%s\n", type->Name.c_str()); LuaError(l, "Unsupported tag: %s" _C_ value); } } - // Assert(var->VariationId); + // Assert(variation->VariationId); lua_pop(l, 1); } + + type->DefaultStat.Variables[VARIATION_INDEX].Max = type->Variations.size(); //Wyrmgus end } else if (!strcmp(value, "Image")) { if (!lua_istable(l, -1)) { @@ -2969,9 +2970,9 @@ static int CclGetUnitTypeData(lua_State *l) return 1; } else if (!strcmp(data, "Variations")) { std::vector variation_idents; - for (int var_n = 0; var_n < VariationMax; ++var_n) { - if (type->VarInfo[var_n] && std::find(variation_idents.begin(), variation_idents.end(), type->VarInfo[var_n]->VariationId) == variation_idents.end()) { - variation_idents.push_back(type->VarInfo[var_n]->VariationId); + for (CUnitTypeVariation *variation : type->Variations) { + if (std::find(variation_idents.begin(), variation_idents.end(), variation->VariationId) == variation_idents.end()) { + variation_idents.push_back(variation->VariationId); } } @@ -2988,9 +2989,9 @@ static int CclGetUnitTypeData(lua_State *l) const int image_layer = GetImageLayerIdByName(image_layer_name); std::vector variation_idents; - for (size_t var_n = 0; var_n < type->LayerVarInfo[image_layer].size(); ++var_n) { - if (type->LayerVarInfo[image_layer][var_n] && std::find(variation_idents.begin(), variation_idents.end(), type->LayerVarInfo[image_layer][var_n]->VariationId) == variation_idents.end()) { - variation_idents.push_back(type->LayerVarInfo[image_layer][var_n]->VariationId); + for (CUnitTypeVariation *layer_variation : type->LayerVariations[image_layer]) { + if (std::find(variation_idents.begin(), variation_idents.end(), layer_variation->VariationId) == variation_idents.end()) { + variation_idents.push_back(layer_variation->VariationId); } } @@ -3461,7 +3462,7 @@ void UpdateUnitVariables(CUnit &unit) } //Wyrmgus - unit.Variable[VARIATION_INDEX].Max = VariationMax; + unit.Variable[VARIATION_INDEX].Max = unit.Type->Variations.size(); unit.Variable[VARIATION_INDEX].Enable = 1; unit.Variable[VARIATION_INDEX].Value = unit.Variation; diff --git a/src/unit/unit.cpp b/src/unit/unit.cpp index 7a0906b73..027fdc667 100644 --- a/src/unit/unit.cpp +++ b/src/unit/unit.cpp @@ -635,8 +635,14 @@ void CUnit::SetResourcesHeld(int quantity) { this->ResourcesHeld = quantity; - VariationInfo *varinfo = this->Type->VarInfo[this->Variation]; - if (varinfo && ((varinfo->ResourceMin && this->ResourcesHeld < varinfo->ResourceMin) || (varinfo->ResourceMax && this->ResourcesHeld > varinfo->ResourceMax))) { + const CUnitTypeVariation *variation = this->GetVariation(); + if ( + variation + && ( + (variation->ResourceMin && this->ResourcesHeld < variation->ResourceMin) + || (variation->ResourceMax && this->ResourcesHeld > variation->ResourceMax) + ) + ) { this->ChooseVariation(); } } @@ -1065,10 +1071,10 @@ void CUnit::SetCharacter(const std::string &character_ident, bool custom_hero) this->UpdateXPRequired(); } -bool CUnit::CheckTerrainForVariation(const VariationInfo *varinfo) const +bool CUnit::CheckTerrainForVariation(const CUnitTypeVariation *variation) const { //if the variation has one or more terrain set as a precondition, then all tiles underneath the unit must match at least one of those terrains - if (varinfo->Terrains.size() > 0) { + if (variation->Terrains.size() > 0) { if (!Map.Info.IsPointOnMap(this->tilePos, this->MapLayer)) { return false; } @@ -1076,7 +1082,7 @@ bool CUnit::CheckTerrainForVariation(const VariationInfo *varinfo) const for (int x = 0; x < this->Type->TileSize.x; ++x) { for (int y = 0; y < this->Type->TileSize.y; ++y) { if (Map.Info.IsPointOnMap(this->tilePos + Vec2i(x, y), this->MapLayer)) { - if (std::find(varinfo->Terrains.begin(), varinfo->Terrains.end(), Map.GetTileTopTerrain(this->tilePos + Vec2i(x, y), false, this->MapLayer->ID, true)) == varinfo->Terrains.end()) { + if (std::find(variation->Terrains.begin(), variation->Terrains.end(), Map.GetTileTopTerrain(this->tilePos + Vec2i(x, y), false, this->MapLayer->ID, true)) == variation->Terrains.end()) { terrain_check = false; break; } @@ -1092,7 +1098,7 @@ bool CUnit::CheckTerrainForVariation(const VariationInfo *varinfo) const } //if the variation has one or more terrains set as a forbidden precondition, then no tiles underneath the unit may match one of those terrains - if (varinfo->TerrainsForbidden.size() > 0) { + if (variation->TerrainsForbidden.size() > 0) { if (!Map.Info.IsPointOnMap(this->tilePos, this->MapLayer)) { return false; } @@ -1100,7 +1106,7 @@ bool CUnit::CheckTerrainForVariation(const VariationInfo *varinfo) const for (int x = 0; x < this->Type->TileSize.x; ++x) { for (int y = 0; y < this->Type->TileSize.y; ++y) { if (Map.Info.IsPointOnMap(this->tilePos + Vec2i(x, y), this->MapLayer)) { - if (std::find(varinfo->TerrainsForbidden.begin(), varinfo->TerrainsForbidden.end(), Map.GetTileTopTerrain(this->tilePos + Vec2i(x, y), false, this->MapLayer->ID, true)) == varinfo->TerrainsForbidden.end()) { + if (std::find(variation->TerrainsForbidden.begin(), variation->TerrainsForbidden.end(), Map.GetTileTopTerrain(this->tilePos + Vec2i(x, y), false, this->MapLayer->ID, true)) == variation->TerrainsForbidden.end()) { terrain_check = false; break; } @@ -1118,19 +1124,19 @@ bool CUnit::CheckTerrainForVariation(const VariationInfo *varinfo) const return true; } -bool CUnit::CheckSeasonForVariation(const VariationInfo *varinfo) const +bool CUnit::CheckSeasonForVariation(const CUnitTypeVariation *variation) const { if ( - !varinfo->Seasons.empty() - && (!this->MapLayer || std::find(varinfo->Seasons.begin(), varinfo->Seasons.end(), this->MapLayer->GetSeason()) == varinfo->Seasons.end()) + !variation->Seasons.empty() + && (!this->MapLayer || std::find(variation->Seasons.begin(), variation->Seasons.end(), this->MapLayer->GetSeason()) == variation->Seasons.end()) ) { return false; } if ( - !varinfo->ForbiddenSeasons.empty() + !variation->ForbiddenSeasons.empty() && this->MapLayer - && std::find(varinfo->ForbiddenSeasons.begin(), varinfo->ForbiddenSeasons.end(), this->MapLayer->GetSeason()) != varinfo->ForbiddenSeasons.end() + && std::find(variation->ForbiddenSeasons.begin(), variation->ForbiddenSeasons.end(), this->MapLayer->GetSeason()) != variation->ForbiddenSeasons.end() ) { return false; } @@ -1144,37 +1150,34 @@ void CUnit::ChooseVariation(const CUnitType *new_type, bool ignore_old_variation if (image_layer == -1) { if (this->Character != nullptr && !this->Character->HairVariation.empty()) { priority_variation = this->Character->HairVariation; - } else if (this->Type->VarInfo[this->Variation]) { - priority_variation = this->Type->VarInfo[this->Variation]->VariationId; + } else if (this->GetVariation() != nullptr) { + priority_variation = this->GetVariation()->VariationId; } } else { if (image_layer == HairImageLayer && this->Character != nullptr && !this->Character->HairVariation.empty()) { priority_variation = this->Character->HairVariation; - } else if (this->LayerVariation[image_layer] != -1 && this->LayerVariation[image_layer] < ((int) this->Type->LayerVarInfo[image_layer].size())) { - priority_variation = this->Type->LayerVarInfo[image_layer][this->LayerVariation[image_layer]]->VariationId; + } else if (this->GetLayerVariation(image_layer)) { + priority_variation = this->GetLayerVariation(image_layer)->VariationId; } } - std::vector type_variations; - int variation_max = image_layer == -1 ? VariationMax : (new_type != nullptr ? new_type->LayerVarInfo[image_layer].size() : this->Type->LayerVarInfo[image_layer].size()); + std::vector type_variations; + const std::vector &variation_list = image_layer == -1 ? (new_type != nullptr ? new_type->Variations : this->Type->Variations) : (new_type != nullptr ? new_type->LayerVariations[image_layer] : this->Type->LayerVariations[image_layer]); + bool found_similar = false; - for (int i = 0; i < variation_max; ++i) { - VariationInfo *varinfo = image_layer == -1 ? new_type != nullptr ? new_type->VarInfo[i] : this->Type->VarInfo[i] : (new_type != nullptr ? new_type->LayerVarInfo[image_layer][i] : this->Type->LayerVarInfo[image_layer][i]); - if (!varinfo) { - continue; - } - if (varinfo->ResourceMin && this->ResourcesHeld < varinfo->ResourceMin) { + for (CUnitTypeVariation *variation : variation_list) { + if (variation->ResourceMin && this->ResourcesHeld < variation->ResourceMin) { continue; } - if (varinfo->ResourceMax && this->ResourcesHeld > varinfo->ResourceMax) { + if (variation->ResourceMax && this->ResourcesHeld > variation->ResourceMax) { continue; } - if (!this->CheckSeasonForVariation(varinfo)) { + if (!this->CheckSeasonForVariation(variation)) { continue; } - if (!this->CheckTerrainForVariation(varinfo)) { + if (!this->CheckTerrainForVariation(variation)) { continue; } @@ -1183,36 +1186,40 @@ void CUnit::ChooseVariation(const CUnitType *new_type, bool ignore_old_variation bool found_weapon = false; bool requires_shield = false; bool found_shield = false; - for (int u = 0; u < VariationMax; ++u) { - if (!varinfo->UpgradesRequired[u].empty()) { - if (CUpgrade::Get(varinfo->UpgradesRequired[u])->Weapon) { - requires_weapon = true; - if (UpgradeIdentAllowed(*this->Player, varinfo->UpgradesRequired[u].c_str()) == 'R' || this->GetIndividualUpgrade(CUpgrade::Get(varinfo->UpgradesRequired[u]))) { - found_weapon = true; - } - } else if (CUpgrade::Get(varinfo->UpgradesRequired[u])->Shield) { - requires_shield = true; - if (UpgradeIdentAllowed(*this->Player, varinfo->UpgradesRequired[u].c_str()) == 'R' || this->GetIndividualUpgrade(CUpgrade::Get(varinfo->UpgradesRequired[u]))) { - found_shield = true; - } - } else if (UpgradeIdentAllowed(*this->Player, varinfo->UpgradesRequired[u].c_str()) != 'R' && this->GetIndividualUpgrade(CUpgrade::Get(varinfo->UpgradesRequired[u])) == false) { - upgrades_check = false; - break; + for (const CUpgrade *required_upgrade : variation->UpgradesRequired) { + if (required_upgrade->Weapon) { + requires_weapon = true; + if (UpgradeIdentAllowed(*this->Player, required_upgrade->Ident.c_str()) == 'R' || this->GetIndividualUpgrade(required_upgrade)) { + found_weapon = true; } - } - if (!varinfo->UpgradesForbidden[u].empty() && (UpgradeIdentAllowed(*this->Player, varinfo->UpgradesForbidden[u].c_str()) == 'R' || this->GetIndividualUpgrade(CUpgrade::Get(varinfo->UpgradesForbidden[u])))) { + } else if (required_upgrade->Shield) { + requires_shield = true; + if (UpgradeIdentAllowed(*this->Player, required_upgrade->Ident.c_str()) == 'R' || this->GetIndividualUpgrade(required_upgrade)) { + found_shield = true; + } + } else if (UpgradeIdentAllowed(*this->Player, required_upgrade->Ident.c_str()) != 'R' && this->GetIndividualUpgrade(required_upgrade) == false) { upgrades_check = false; break; } } - for (size_t j = 0; j < varinfo->ItemClassesNotEquipped.size(); ++j) { - if (IsItemClassEquipped(varinfo->ItemClassesNotEquipped[j])) { + + if (upgrades_check) { + for (const CUpgrade *forbidden_upgrade : variation->UpgradesForbidden) { + if (UpgradeIdentAllowed(*this->Player, forbidden_upgrade->Ident.c_str()) == 'R' || this->GetIndividualUpgrade(forbidden_upgrade)) { + upgrades_check = false; + break; + } + } + } + + for (size_t j = 0; j < variation->ItemClassesNotEquipped.size(); ++j) { + if (this->IsItemClassEquipped(variation->ItemClassesNotEquipped[j])) { upgrades_check = false; break; } } - for (size_t j = 0; j < varinfo->ItemsNotEquipped.size(); ++j) { - if (IsItemTypeEquipped(varinfo->ItemsNotEquipped[j])) { + for (size_t j = 0; j < variation->ItemsNotEquipped.size(); ++j) { + if (this->IsItemTypeEquipped(variation->ItemsNotEquipped[j])) { upgrades_check = false; break; } @@ -1220,28 +1227,28 @@ void CUnit::ChooseVariation(const CUnitType *new_type, bool ignore_old_variation if (upgrades_check == false) { continue; } - for (size_t j = 0; j < varinfo->ItemClassesEquipped.size(); ++j) { - if (GetItemClassSlot(varinfo->ItemClassesEquipped[j]) == WeaponItemSlot) { + for (size_t j = 0; j < variation->ItemClassesEquipped.size(); ++j) { + if (GetItemClassSlot(variation->ItemClassesEquipped[j]) == WeaponItemSlot) { requires_weapon = true; - if (IsItemClassEquipped(varinfo->ItemClassesEquipped[j])) { + if (IsItemClassEquipped(variation->ItemClassesEquipped[j])) { found_weapon = true; } - } else if (GetItemClassSlot(varinfo->ItemClassesEquipped[j]) == ShieldItemSlot) { + } else if (GetItemClassSlot(variation->ItemClassesEquipped[j]) == ShieldItemSlot) { requires_shield = true; - if (IsItemClassEquipped(varinfo->ItemClassesEquipped[j])) { + if (IsItemClassEquipped(variation->ItemClassesEquipped[j])) { found_shield = true; } } } - for (size_t j = 0; j < varinfo->ItemsEquipped.size(); ++j) { - if (GetItemClassSlot(varinfo->ItemsEquipped[j]->ItemClass) == WeaponItemSlot) { + for (size_t j = 0; j < variation->ItemsEquipped.size(); ++j) { + if (GetItemClassSlot(variation->ItemsEquipped[j]->ItemClass) == WeaponItemSlot) { requires_weapon = true; - if (IsItemTypeEquipped(varinfo->ItemsEquipped[j])) { + if (this->IsItemTypeEquipped(variation->ItemsEquipped[j])) { found_weapon = true; } - } else if (GetItemClassSlot(varinfo->ItemsEquipped[j]->ItemClass) == ShieldItemSlot) { + } else if (GetItemClassSlot(variation->ItemsEquipped[j]->ItemClass) == ShieldItemSlot) { requires_shield = true; - if (IsItemTypeEquipped(varinfo->ItemsEquipped[j])) { + if (this->IsItemTypeEquipped(variation->ItemsEquipped[j])) { found_shield = true; } } @@ -1249,7 +1256,7 @@ void CUnit::ChooseVariation(const CUnitType *new_type, bool ignore_old_variation if ((requires_weapon && !found_weapon) || (requires_shield && !found_shield)) { continue; } - if (!ignore_old_variation && !priority_variation.empty() && (varinfo->VariationId.find(priority_variation) != std::string::npos || priority_variation.find(varinfo->VariationId) != std::string::npos)) { // if the priority variation's ident is included in that of a new viable variation (or vice-versa), give priority to the new variation over others + if (!ignore_old_variation && !priority_variation.empty() && (variation->VariationId.find(priority_variation) != std::string::npos || priority_variation.find(variation->VariationId) != std::string::npos)) { // if the priority variation's ident is included in that of a new viable variation (or vice-versa), give priority to the new variation over others if (!found_similar) { found_similar = true; type_variations.clear(); @@ -1259,8 +1266,8 @@ void CUnit::ChooseVariation(const CUnitType *new_type, bool ignore_old_variation continue; } } - for (int j = 0; j < varinfo->Weight; ++j) { - type_variations.push_back(i); + for (int j = 0; j < variation->Weight; ++j) { + type_variations.push_back(variation); } } if (type_variations.size() > 0) { @@ -1268,22 +1275,39 @@ void CUnit::ChooseVariation(const CUnitType *new_type, bool ignore_old_variation } } -void CUnit::SetVariation(int new_variation, const CUnitType *new_type, int image_layer) +void CUnit::SetVariation(CUnitTypeVariation *new_variation, const CUnitType *new_type, int image_layer) { if (image_layer == -1) { if ( - (this->Type->VarInfo[this->Variation] && this->Type->VarInfo[this->Variation]->Animations) - || (new_type == nullptr && this->Type->VarInfo[new_variation] && this->Type->VarInfo[new_variation]->Animations) - || (new_type != nullptr && new_type->VarInfo[new_variation]->Animations) + (this->GetVariation() && this->GetVariation()->Animations) + || (new_variation && new_variation->Animations) ) { //if the old (if any) or the new variation has specific animations, set the unit's frame to its type's still frame this->Frame = this->Type->StillFrame; } - this->Variation = new_variation; + this->Variation = new_variation ? new_variation->ID : 0; } else { - this->LayerVariation[image_layer] = new_variation; + this->LayerVariation[image_layer] = new_variation ? new_variation->ID : -1; } } +const CUnitTypeVariation *CUnit::GetVariation() const +{ + if (this->Variation < (int) this->Type->Variations.size()) { + return this->Type->Variations[this->Variation]; + } + + return nullptr; +} + +const CUnitTypeVariation *CUnit::GetLayerVariation(const unsigned int image_layer) const +{ + if (this->LayerVariation[image_layer] >= 0 && this->LayerVariation[image_layer] < (int) this->Type->LayerVariations[image_layer].size()) { + return this->Type->LayerVariations[image_layer][this->LayerVariation[image_layer]]; + } + + return nullptr; +} + void CUnit::UpdateButtonIcons() { this->ChooseButtonIcon(ButtonAttack); @@ -1330,17 +1354,15 @@ void CUnit::ChooseButtonIcon(int button_action) } } - if (this->Type->VarInfo[this->Variation] && this->Type->VarInfo[this->Variation]->ButtonIcons.find(button_action) != this->Type->VarInfo[this->Variation]->ButtonIcons.end()) { - this->ButtonIcons[button_action] = this->Type->VarInfo[this->Variation]->ButtonIcons[button_action].Icon; + const CUnitTypeVariation *variation = this->GetVariation(); + if (variation && variation->ButtonIcons.find(button_action) != variation->ButtonIcons.end()) { + this->ButtonIcons[button_action] = variation->ButtonIcons.find(button_action)->second.Icon; return; } for (int i = 0; i < MaxImageLayers; ++i) { - if (this->LayerVariation[i] == -1 || this->LayerVariation[i] >= ((int) this->Type->LayerVarInfo[i].size())) { - continue; - } - VariationInfo *varinfo = this->Type->LayerVarInfo[i][this->LayerVariation[i]]; - if (varinfo && varinfo->ButtonIcons.find(button_action) != varinfo->ButtonIcons.end()) { - this->ButtonIcons[button_action] = varinfo->ButtonIcons[button_action].Icon; + const CUnitTypeVariation *layer_variation = this->GetLayerVariation(i); + if (layer_variation && layer_variation->ButtonIcons.find(button_action) != layer_variation->ButtonIcons.end()) { + this->ButtonIcons[button_action] = layer_variation->ButtonIcons.find(button_action)->second.Icon; return; } } @@ -1515,16 +1537,25 @@ void CUnit::EquipItem(CUnit &item, bool affect_character) EquippedItems[item_slot].push_back(&item); //change variation, if the current one has become forbidden - VariationInfo *varinfo = Type->VarInfo[Variation]; - if (varinfo && (std::find(varinfo->ItemClassesNotEquipped.begin(), varinfo->ItemClassesNotEquipped.end(), item.Type->ItemClass) != varinfo->ItemClassesNotEquipped.end() || std::find(varinfo->ItemsNotEquipped.begin(), varinfo->ItemsNotEquipped.end(), item.Type) != varinfo->ItemsNotEquipped.end())) { + const CUnitTypeVariation *variation = this->GetVariation(); + if ( + variation + && ( + std::find(variation->ItemClassesNotEquipped.begin(), variation->ItemClassesNotEquipped.end(), item.Type->ItemClass) != variation->ItemClassesNotEquipped.end() + || std::find(variation->ItemsNotEquipped.begin(), variation->ItemsNotEquipped.end(), item.Type) != variation->ItemsNotEquipped.end() + ) + ) { ChooseVariation(); //choose a new variation now } for (int i = 0; i < MaxImageLayers; ++i) { - if (this->LayerVariation[i] == -1 || this->LayerVariation[i] >= ((int) this->Type->LayerVarInfo[i].size())) { - continue; - } - VariationInfo *varinfo = Type->LayerVarInfo[i][this->LayerVariation[i]]; - if (std::find(varinfo->ItemClassesNotEquipped.begin(), varinfo->ItemClassesNotEquipped.end(), item.Type->ItemClass) != varinfo->ItemClassesNotEquipped.end() || std::find(varinfo->ItemsNotEquipped.begin(), varinfo->ItemsNotEquipped.end(), item.Type) != varinfo->ItemsNotEquipped.end()) { + const CUnitTypeVariation *layer_variation = this->GetLayerVariation(i); + if ( + layer_variation + && ( + std::find(layer_variation->ItemClassesNotEquipped.begin(), layer_variation->ItemClassesNotEquipped.end(), item.Type->ItemClass) != layer_variation->ItemClassesNotEquipped.end() + || std::find(layer_variation->ItemsNotEquipped.begin(), layer_variation->ItemsNotEquipped.end(), item.Type) != layer_variation->ItemsNotEquipped.end() + ) + ) { ChooseVariation(nullptr, false, i); } } @@ -1688,16 +1719,26 @@ void CUnit::DeequipItem(CUnit &item, bool affect_character) } //change variation, if the current one has become forbidden - VariationInfo *varinfo = Type->VarInfo[Variation]; - if (varinfo && (std::find(varinfo->ItemClassesEquipped.begin(), varinfo->ItemClassesEquipped.end(), item.Type->ItemClass) != varinfo->ItemClassesEquipped.end() || std::find(varinfo->ItemsEquipped.begin(), varinfo->ItemsEquipped.end(), item.Type) != varinfo->ItemsEquipped.end())) { + const CUnitTypeVariation *variation = this->GetVariation(); + if ( + variation + && ( + std::find(variation->ItemClassesEquipped.begin(), variation->ItemClassesEquipped.end(), item.Type->ItemClass) != variation->ItemClassesEquipped.end() + || std::find(variation->ItemsEquipped.begin(), variation->ItemsEquipped.end(), item.Type) != variation->ItemsEquipped.end() + ) + ) { ChooseVariation(); //choose a new variation now } for (int i = 0; i < MaxImageLayers; ++i) { - if (this->LayerVariation[i] == -1 || this->LayerVariation[i] >= ((int) this->Type->LayerVarInfo[i].size())) { - continue; - } - VariationInfo *varinfo = Type->LayerVarInfo[i][this->LayerVariation[i]]; - if (std::find(varinfo->ItemClassesEquipped.begin(), varinfo->ItemClassesEquipped.end(), item.Type->ItemClass) != varinfo->ItemClassesEquipped.end() || std::find(varinfo->ItemsEquipped.begin(), varinfo->ItemsEquipped.end(), item.Type) != varinfo->ItemsEquipped.end()) { + const CUnitTypeVariation *layer_variation = this->GetLayerVariation(i); + + if ( + layer_variation + && ( + std::find(layer_variation->ItemClassesEquipped.begin(), layer_variation->ItemClassesEquipped.end(), item.Type->ItemClass) != layer_variation->ItemClassesEquipped.end() + || std::find(layer_variation->ItemsEquipped.begin(), layer_variation->ItemsEquipped.end(), item.Type) != layer_variation->ItemsEquipped.end() + ) + ) { ChooseVariation(nullptr, false, i); } } @@ -3571,10 +3612,10 @@ void CUnit::Place(const Vec2i &pos, int z) } } - VariationInfo *varinfo = this->Type->VarInfo[this->Variation]; - if (varinfo) { + const CUnitTypeVariation *variation = this->GetVariation(); + if (variation) { // if a unit that is on the tile has a terrain-dependent or season-dependent variation that is not compatible with the new tile, repick the unit's variation - if (!this->CheckTerrainForVariation(varinfo) || !this->CheckSeasonForVariation(varinfo)) { + if (!this->CheckTerrainForVariation(variation) || !this->CheckSeasonForVariation(variation)) { this->ChooseVariation(); } } @@ -4402,10 +4443,10 @@ bool CUnit::IsVisibleInViewport(const CViewport &vp) const int frame_width = Type->Width; int frame_height = Type->Height; - VariationInfo *varinfo = Type->VarInfo[Variation]; - if (varinfo && varinfo->FrameWidth && varinfo->FrameHeight) { - frame_width = varinfo->FrameWidth; - frame_height = varinfo->FrameHeight; + const CUnitTypeVariation *variation = this->GetVariation(); + if (variation && variation->FrameWidth && variation->FrameHeight) { + frame_width = variation->FrameWidth; + frame_height = variation->FrameHeight; } int x = tilePos.x * Map.GetMapLayerPixelTileSize(this->MapLayer->ID).x + IX - (frame_width - Type->TileSize.x * Map.GetMapLayerPixelTileSize(this->MapLayer->ID).x) / 2 + Type->OffsetX; @@ -5137,12 +5178,12 @@ CUnit *UnitOnScreen(int x, int y) // (type.Width - type.Sprite->Width) / 2 + type.BoxOffsetX; // unitSpritePos.y = unitSpritePos.y - type.BoxHeight / 2 - // (type.Height - type.Sprite->Height) / 2 + type.BoxOffsetY; - VariationInfo *varinfo = type.VarInfo[unit.Variation]; - if (varinfo && varinfo->FrameWidth && varinfo->FrameHeight && !varinfo->File.empty()) { + const CUnitTypeVariation *variation = unit.GetVariation(); + if (variation && variation->FrameWidth && variation->FrameHeight && !variation->File.empty()) { unitSpritePos.x = unitSpritePos.x - type.BoxWidth / 2 - - (varinfo->FrameWidth - varinfo->Sprite->Width) / 2 + type.BoxOffsetX; + (variation->FrameWidth - variation->Sprite->Width) / 2 + type.BoxOffsetX; unitSpritePos.y = unitSpritePos.y - type.BoxHeight / 2 - - (varinfo->FrameHeight - varinfo->Sprite->Height) / 2 + type.BoxOffsetY; + (variation->FrameHeight - variation->Sprite->Height) / 2 + type.BoxOffsetY; } else { unitSpritePos.x = unitSpritePos.x - type.BoxWidth / 2 - (type.Width - type.Sprite->Width) / 2 + type.BoxOffsetX; @@ -5851,7 +5892,7 @@ bool CUnit::IsItemClassEquipped(int item_class) const return false; } -bool CUnit::IsItemTypeEquipped(CUnitType *item_type) const +bool CUnit::IsItemTypeEquipped(const CUnitType *item_type) const { int item_slot = GetItemClassSlot(item_type->ItemClass); @@ -6253,21 +6294,21 @@ bool CUnit::HasAdjacentRailForUnitType(const CUnitType *type) const CAnimations *CUnit::GetAnimations() const { - VariationInfo *varinfo = Type->VarInfo[Variation]; - if (varinfo && varinfo->Animations) { - return varinfo->Animations; + const CUnitTypeVariation *variation = this->GetVariation(); + if (variation && variation->Animations) { + return variation->Animations; } else { - return Type->Animations; + return this->Type->Animations; } } CConstruction *CUnit::GetConstruction() const { - VariationInfo *varinfo = Type->VarInfo[Variation]; - if (varinfo && varinfo->Construction) { - return varinfo->Construction; + const CUnitTypeVariation *variation = this->GetVariation(); + if (variation && variation->Construction) { + return variation->Construction; } else { - return Type->Construction; + return this->Type->Construction; } } @@ -6279,10 +6320,13 @@ IconConfig CUnit::GetIcon() const return this->Character->Icon; } else if (this->Unique != nullptr && this->Unique->Icon.Icon) { return this->Unique->Icon; - } else if (Type->VarInfo[Variation] && Type->VarInfo[Variation]->Icon.Icon) { - return Type->VarInfo[Variation]->Icon; + } + + const CUnitTypeVariation *variation = this->GetVariation(); + if (variation && variation->Icon.Icon) { + return variation->Icon; } else { - return Type->Icon; + return this->Type->Icon; } } @@ -6310,13 +6354,16 @@ MissileConfig CUnit::GetMissile() const CPlayerColorGraphic *CUnit::GetLayerSprite(int image_layer) const { - VariationInfo *varinfo = Type->VarInfo[Variation]; - if (this->LayerVariation[image_layer] != -1 && this->LayerVariation[image_layer] < ((int) this->Type->LayerVarInfo[image_layer].size()) && this->Type->LayerVarInfo[image_layer][this->LayerVariation[image_layer]]->Sprite) { - return this->Type->LayerVarInfo[image_layer][this->LayerVariation[image_layer]]->Sprite; - } else if (varinfo && varinfo->LayerSprites[image_layer]) { - return varinfo->LayerSprites[image_layer]; - } else if (Type->LayerSprites[image_layer]) { - return Type->LayerSprites[image_layer]; + const CUnitTypeVariation *layer_variation = this->GetLayerVariation(image_layer); + if (layer_variation && layer_variation->Sprite) { + return layer_variation->Sprite; + } + + const CUnitTypeVariation *variation = this->GetVariation(); + if (variation && variation->LayerSprites[image_layer]) { + return variation->LayerSprites[image_layer]; + } else if (this->Type->LayerSprites[image_layer]) { + return this->Type->LayerSprites[image_layer]; } else { return nullptr; } @@ -6361,11 +6408,11 @@ std::string CUnit::GetTypeName() const return _("Deity"); } - VariationInfo *varinfo = Type->VarInfo[Variation]; - if (varinfo && !varinfo->TypeName.empty()) { - return _(varinfo->TypeName.c_str()); + const CUnitTypeVariation *variation = this->GetVariation(); + if (variation && !variation->TypeName.empty()) { + return _(variation->TypeName.c_str()); } else { - return _(Type->Name.c_str()); + return _(this->Type->Name.c_str()); } } diff --git a/src/unit/unit_draw.cpp b/src/unit/unit_draw.cpp index 72d5a3a98..a99bf0f2c 100644 --- a/src/unit/unit_draw.cpp +++ b/src/unit/unit_draw.cpp @@ -142,12 +142,12 @@ void DrawUnitSelection(const CViewport &vp, const CUnit &unit) int frame_height = type.Height; int sprite_width = (type.Sprite ? type.Sprite->Width : 0); int sprite_height = (type.Sprite ? type.Sprite->Height : 0); - VariationInfo *varinfo = type.VarInfo[unit.Variation]; - if (varinfo && varinfo->FrameWidth && varinfo->FrameHeight) { - frame_width = varinfo->FrameWidth; - frame_height = varinfo->FrameHeight; - sprite_width = (varinfo->Sprite ? varinfo->Sprite->Width : 0); - sprite_height = (varinfo->Sprite ? varinfo->Sprite->Height : 0); + const CUnitTypeVariation *variation = unit.GetVariation(); + if (variation && variation->FrameWidth && variation->FrameHeight) { + frame_width = variation->FrameWidth; + frame_height = variation->FrameHeight; + sprite_width = (variation->Sprite ? variation->Sprite->Width : 0); + sprite_height = (variation->Sprite ? variation->Sprite->Height : 0); } int x = screenPos.x - type.BoxWidth / 2 - (frame_width - sprite_width) / 2; int y = screenPos.y - type.BoxHeight / 2 - (frame_height - sprite_height) / 2; @@ -961,34 +961,18 @@ static void DrawConstructionShadow(const CUnit &unit, const CUnitType &type, con int frame, const PixelPos &screenPos) { PixelPos pos = screenPos; - //Wyrmgus start - VariationInfo *varinfo = type.VarInfo[unit.Variation]; - //Wyrmgus end + const CUnitTypeVariation *variation = unit.GetVariation(); if (cframe->File == ConstructionFileConstruction) { - //Wyrmgus start - /* - if (type.Construction->ShadowSprite) { - pos.x -= (type.Construction->Width - type.TileSize.x * Map.GetCurrentPixelTileSize().x) / 2; - pos.x += type.OffsetX; - pos.y -= (type.Construction->Height - type.TileSize.y * Map.GetCurrentPixelTileSize().y) / 2; - pos.y += type.OffsetY; - if (frame < 0) { - type.Construction->ShadowSprite->DrawFrameClipX(-frame - 1, pos.x, pos.y); - } else { - type.Construction->ShadowSprite->DrawFrameClip(frame, pos.x, pos.y); - } - } - */ - if (varinfo && varinfo->Construction) { - if (varinfo->Construction->ShadowSprite) { - pos.x -= (varinfo->Construction->Width - type.TileSize.x * Map.GetCurrentPixelTileSize().x) / 2; + if (variation && variation->Construction) { + if (variation->Construction->ShadowSprite) { + pos.x -= (variation->Construction->Width - type.TileSize.x * Map.GetCurrentPixelTileSize().x) / 2; pos.x += type.OffsetX; - pos.y -= (varinfo->Construction->Height - type.TileSize.y * Map.GetCurrentPixelTileSize().y) / 2; + pos.y -= (variation->Construction->Height - type.TileSize.y * Map.GetCurrentPixelTileSize().y) / 2; pos.y += type.OffsetY; if (frame < 0) { - varinfo->Construction->ShadowSprite->DrawFrameClipX(-frame - 1, pos.x, pos.y); + variation->Construction->ShadowSprite->DrawFrameClipX(-frame - 1, pos.x, pos.y); } else { - varinfo->Construction->ShadowSprite->DrawFrameClip(frame, pos.x, pos.y); + variation->Construction->ShadowSprite->DrawFrameClip(frame, pos.x, pos.y); } } } else { @@ -1004,22 +988,18 @@ static void DrawConstructionShadow(const CUnit &unit, const CUnitType &type, con } } } - //Wyrmgus end } else { - //Wyrmgus start - if (varinfo && varinfo->ShadowSprite) { + if (variation && variation->ShadowSprite) { pos.x -= (type.ShadowWidth - type.TileSize.x * Map.GetCurrentPixelTileSize().x) / 2; pos.x += type.ShadowOffsetX + type.OffsetX; pos.y -= (type.ShadowHeight - type.TileSize.y * Map.GetCurrentPixelTileSize().y) / 2; pos.y += type.ShadowOffsetY + type.OffsetY; if (frame < 0) { - varinfo->ShadowSprite->DrawFrameClipX(-frame - 1, pos.x, pos.y); + variation->ShadowSprite->DrawFrameClipX(-frame - 1, pos.x, pos.y); } else { - varinfo->ShadowSprite->DrawFrameClip(frame, pos.x, pos.y); + variation->ShadowSprite->DrawFrameClip(frame, pos.x, pos.y); } -// if (type.ShadowSprite) { } else if (type.ShadowSprite) { - //Wyrmgus end pos.x -= (type.ShadowWidth - type.TileSize.x * Map.GetCurrentPixelTileSize().x) / 2; pos.x += type.ShadowOffsetX + type.OffsetX; pos.y -= (type.ShadowHeight - type.TileSize.y * Map.GetCurrentPixelTileSize().y) / 2; @@ -1050,20 +1030,9 @@ static void DrawConstruction(const int player, const CConstructionFrame *cframe, { PixelPos pos = screenPos; if (cframe->File == ConstructionFileConstruction) { - //Wyrmgus start - /* - const CConstruction &construction = *type.Construction; - pos.x -= construction.Width / 2; - pos.y -= construction.Height / 2; - if (frame < 0) { - construction.Sprite->DrawPlayerColorFrameClipX(player, -frame - 1, pos.x, pos.y); - } else { - construction.Sprite->DrawPlayerColorFrameClip(player, frame, pos.x, pos.y); - } - */ - VariationInfo *varinfo = type.VarInfo[unit.Variation]; - if (varinfo && varinfo->Construction) { - const CConstruction &construction = *varinfo->Construction; + const CUnitTypeVariation *variation = unit.GetVariation(); + if (variation && variation->Construction) { + const CConstruction &construction = *variation->Construction; pos.x -= construction.Width / 2; pos.y -= construction.Height / 2; if (frame < 0) { @@ -1088,10 +1057,10 @@ static void DrawConstruction(const int player, const CConstructionFrame *cframe, // pos.y += type.OffsetY - type.Height / 2; int frame_width = type.Width; int frame_height = type.Height; - VariationInfo *varinfo = type.VarInfo[unit.Variation]; - if (varinfo && varinfo->FrameWidth && varinfo->FrameHeight) { - frame_width = varinfo->FrameWidth; - frame_height = varinfo->FrameHeight; + const CUnitTypeVariation *variation = unit.GetVariation(); + if (variation && variation->FrameWidth && variation->FrameHeight) { + frame_width = variation->FrameWidth; + frame_height = variation->FrameHeight; } pos.x += type.OffsetX - frame_width / 2; pos.y += type.OffsetY - frame_height / 2; @@ -1101,8 +1070,8 @@ static void DrawConstruction(const int player, const CConstructionFrame *cframe, } //Wyrmgus start // type.Sprite->DrawPlayerColorFrameClip(player, frame, pos.x, pos.y); - if (varinfo && varinfo->Sprite) { - varinfo->Sprite->DrawPlayerColorFrameClip(player, frame, pos.x, pos.y, false); + if (variation && variation->Sprite) { + variation->Sprite->DrawPlayerColorFrameClip(player, frame, pos.x, pos.y, false); } else { type.Sprite->DrawPlayerColorFrameClip(player, frame, pos.x, pos.y, false); } @@ -1192,9 +1161,7 @@ void CUnit::Draw(const CViewport &vp) const DrawUnitSelection(vp, *this); //Wyrmgus end - //Wyrmgus start - VariationInfo *varinfo = type->VarInfo[this->Variation]; - //Wyrmgus end + const CUnitTypeVariation *variation = this->GetVariation(); if (state == 1 && under_construction && cframe) { //Wyrmgus start @@ -1207,8 +1174,8 @@ void CUnit::Draw(const CViewport &vp) const //Wyrmgus end //Wyrmgus start // DrawShadow(*type, frame, screenPos); - if (varinfo && varinfo->ShadowSprite) { - DrawShadow(*type, varinfo->ShadowSprite, frame, screenPos); + if (variation && variation->ShadowSprite) { + DrawShadow(*type, variation->ShadowSprite, frame, screenPos); } else if (type->ShadowSprite) { DrawShadow(*type, type->ShadowSprite, frame, screenPos); } @@ -1290,18 +1257,18 @@ void CUnit::Draw(const CViewport &vp) const } //Wyrmgus start // Adjust sprite for variations. - if (varinfo) { - if (varinfo->Sprite) { - sprite = varinfo->Sprite; + if (variation) { + if (variation->Sprite) { + sprite = variation->Sprite; } if (type->BoolFlag[HARVESTER_INDEX].value && this->CurrentResource) { if (this->ResourcesHeld) { - if (varinfo->SpriteWhenLoaded[this->CurrentResource]) { - sprite = varinfo->SpriteWhenLoaded[this->CurrentResource]; + if (variation->SpriteWhenLoaded[this->CurrentResource]) { + sprite = variation->SpriteWhenLoaded[this->CurrentResource]; } } else { - if (varinfo->SpriteWhenEmpty[this->CurrentResource]) { - sprite = varinfo->SpriteWhenEmpty[this->CurrentResource]; + if (variation->SpriteWhenEmpty[this->CurrentResource]) { + sprite = variation->SpriteWhenEmpty[this->CurrentResource]; } } } @@ -1315,10 +1282,7 @@ void CUnit::Draw(const CViewport &vp) const if (state == 1) { if (under_construction && cframe) { const PixelPos pos(screenPos + type->GetHalfTilePixelSize(UI.CurrentMapLayer->ID)); - //Wyrmgus start -// DrawConstruction(player, cframe, *type, frame, pos); DrawConstruction(player, cframe, *this, *type, frame, pos); - //Wyrmgus end } else { DrawUnitType(*type, sprite, player, frame, screenPos); } @@ -1418,8 +1382,8 @@ void CUnit::Draw(const CViewport &vp) const DrawPlayerColorOverlay(*type, this->GetLayerSprite(BackpackImageLayer), player, frame, screenPos); } - if (varinfo && varinfo->LightSprite) { - DrawOverlay(*type, varinfo->LightSprite, player, frame, screenPos); + if (variation && variation->LightSprite) { + DrawOverlay(*type, variation->LightSprite, player, frame, screenPos); } else if (type->LightSprite) { DrawOverlay(*type, type->LightSprite, player, frame, screenPos); } diff --git a/src/unit/unittype.cpp b/src/unit/unittype.cpp index 611849445..5b02b73c2 100644 --- a/src/unit/unittype.cpp +++ b/src/unit/unittype.cpp @@ -605,9 +605,6 @@ CUnitType::CUnitType() : memset(GrandStrategyProductionEfficiencyModifier, 0, sizeof(GrandStrategyProductionEfficiencyModifier)); //Wyrmgus end memset(ResInfo, 0, sizeof(ResInfo)); - //Wyrmgus start - memset(VarInfo, 0, sizeof(VarInfo)); - //Wyrmgus end memset(MissileOffsets, 0, sizeof(MissileOffsets)); //Wyrmgus start memset(LayerSprites, 0, sizeof(LayerSprites)); @@ -663,20 +660,15 @@ CUnitType::~CUnitType() } } - //Wyrmgus start - for (int var = 0; var < VariationMax; ++var) { - if (this->VarInfo[var]) { - delete this->VarInfo[var]; - } + for (CUnitTypeVariation *variation : this->Variations) { + delete variation; } for (int i = 0; i < MaxImageLayers; ++i) { - for (size_t var = 0; var < LayerVarInfo[i].size(); ++var) { - delete this->LayerVarInfo[i][var]; + for (CUnitTypeVariation *layer_variation : this->LayerVariations[i]) { + delete layer_variation; } - LayerVarInfo[i].clear(); } - //Wyrmgus end CGraphic::Free(Sprite); CGraphic::Free(ShadowSprite); @@ -1088,6 +1080,19 @@ void CUnitType::ProcessConfigData(const CConfigData *config_data) std::string target = config_data->Ident; target = FindAndReplaceString(target, "_", "-"); DependRule::ProcessConfigData(child_config_data, DependRuleUnitType, target); + /* + } else if (child_config_data->Tag == "variation") { + this->DefaultStat.Variables[VARIATION_INDEX].Enable = 1; + this->DefaultStat.Variables[VARIATION_INDEX].Value = 0; + + CUnitTypeVariation *variation = new CUnitTypeVariation; + variation->ProcessConfigData(child_config_data); + + variation->ID = this->Variations.size(); + this->Variations.push_back(variation); + + this->DefaultStat.Variables[VARIATION_INDEX].Max = this->Variations.size(); + */ } else { std::string tag = SnakeCaseToPascalCase(child_config_data->Tag); @@ -1510,97 +1515,92 @@ void CUnitType::SetParent(CUnitType *parent_type) this->PersonalNames[iterator->first].push_back(iterator->second[i]); } } - for (unsigned int var_n = 0; var_n < VariationMax; ++var_n) { - if (parent_type->VarInfo[var_n]) { - VariationInfo *var = new VariationInfo; - - this->VarInfo[var_n] = var; - - var->VariationId = parent_type->VarInfo[var_n]->VariationId; - var->TypeName = parent_type->VarInfo[var_n]->TypeName; - var->File = parent_type->VarInfo[var_n]->File; - for (unsigned int i = 0; i < MaxCosts; ++i) { - var->FileWhenLoaded[i] = parent_type->VarInfo[var_n]->FileWhenLoaded[i]; - var->FileWhenEmpty[i] = parent_type->VarInfo[var_n]->FileWhenEmpty[i]; - } - var->ShadowFile = parent_type->VarInfo[var_n]->ShadowFile; - var->LightFile = parent_type->VarInfo[var_n]->LightFile; - var->FrameWidth = parent_type->VarInfo[var_n]->FrameWidth; - var->FrameHeight = parent_type->VarInfo[var_n]->FrameHeight; - var->ResourceMin = parent_type->VarInfo[var_n]->ResourceMin; - var->ResourceMax = parent_type->VarInfo[var_n]->ResourceMax; - var->Weight = parent_type->VarInfo[var_n]->Weight; - var->Icon.Name = parent_type->VarInfo[var_n]->Icon.Name; - var->Icon.Icon = nullptr; - if (!var->Icon.Name.empty()) { - var->Icon.Load(); - } - if (parent_type->VarInfo[var_n]->Animations) { - var->Animations = parent_type->VarInfo[var_n]->Animations; - } - var->Construction = parent_type->VarInfo[var_n]->Construction; - for (int u = 0; u < VariationMax; ++u) { - var->UpgradesRequired[u] = parent_type->VarInfo[var_n]->UpgradesRequired[u]; - var->UpgradesForbidden[u] = parent_type->VarInfo[var_n]->UpgradesForbidden[u]; - } - for (size_t i = 0; i < parent_type->VarInfo[var_n]->ItemClassesEquipped.size(); ++i) { - var->ItemClassesEquipped.push_back(parent_type->VarInfo[var_n]->ItemClassesEquipped[i]); - } - for (size_t i = 0; i < parent_type->VarInfo[var_n]->ItemClassesNotEquipped.size(); ++i) { - var->ItemClassesNotEquipped.push_back(parent_type->VarInfo[var_n]->ItemClassesNotEquipped[i]); - } - for (size_t i = 0; i < parent_type->VarInfo[var_n]->ItemsEquipped.size(); ++i) { - var->ItemsEquipped.push_back(parent_type->VarInfo[var_n]->ItemsEquipped[i]); - } - for (size_t i = 0; i < parent_type->VarInfo[var_n]->ItemsNotEquipped.size(); ++i) { - var->ItemsNotEquipped.push_back(parent_type->VarInfo[var_n]->ItemsNotEquipped[i]); - } - for (size_t i = 0; i < parent_type->VarInfo[var_n]->Terrains.size(); ++i) { - var->Terrains.push_back(parent_type->VarInfo[var_n]->Terrains[i]); - } - - for (int i = 0; i < MaxImageLayers; ++i) { - var->LayerFiles[i] = parent_type->VarInfo[var_n]->LayerFiles[i]; - } - for (std::map::iterator iterator = parent_type->VarInfo[var_n]->ButtonIcons.begin(); iterator != parent_type->VarInfo[var_n]->ButtonIcons.end(); ++iterator) { - var->ButtonIcons[iterator->first].Name = iterator->second.Name; - var->ButtonIcons[iterator->first].Icon = nullptr; - var->ButtonIcons[iterator->first].Load(); - var->ButtonIcons[iterator->first].Icon->Load(); - } - } else { - break; + for (CUnitTypeVariation *parent_variation : parent_type->Variations) { + CUnitTypeVariation *variation = new CUnitTypeVariation; + + variation->ID = this->Variations.size(); + this->Variations.push_back(variation); + + variation->VariationId = parent_variation->VariationId; + variation->TypeName = parent_variation->TypeName; + variation->File = parent_variation->File; + for (unsigned int i = 0; i < MaxCosts; ++i) { + variation->FileWhenLoaded[i] = parent_variation->FileWhenLoaded[i]; + variation->FileWhenEmpty[i] = parent_variation->FileWhenEmpty[i]; + } + variation->ShadowFile = parent_variation->ShadowFile; + variation->LightFile = parent_variation->LightFile; + variation->FrameWidth = parent_variation->FrameWidth; + variation->FrameHeight = parent_variation->FrameHeight; + variation->ResourceMin = parent_variation->ResourceMin; + variation->ResourceMax = parent_variation->ResourceMax; + variation->Weight = parent_variation->Weight; + variation->Icon.Name = parent_variation->Icon.Name; + variation->Icon.Icon = nullptr; + if (!variation->Icon.Name.empty()) { + variation->Icon.Load(); + } + if (parent_variation->Animations) { + variation->Animations = parent_variation->Animations; + } + variation->Construction = parent_variation->Construction; + variation->UpgradesRequired = parent_variation->UpgradesRequired; + variation->UpgradesForbidden = parent_variation->UpgradesForbidden; + for (size_t i = 0; i < parent_variation->ItemClassesEquipped.size(); ++i) { + variation->ItemClassesEquipped.push_back(parent_variation->ItemClassesEquipped[i]); + } + for (size_t i = 0; i < parent_variation->ItemClassesNotEquipped.size(); ++i) { + variation->ItemClassesNotEquipped.push_back(parent_variation->ItemClassesNotEquipped[i]); + } + for (size_t i = 0; i < parent_variation->ItemsEquipped.size(); ++i) { + variation->ItemsEquipped.push_back(parent_variation->ItemsEquipped[i]); + } + for (size_t i = 0; i < parent_variation->ItemsNotEquipped.size(); ++i) { + variation->ItemsNotEquipped.push_back(parent_variation->ItemsNotEquipped[i]); + } + for (size_t i = 0; i < parent_variation->Terrains.size(); ++i) { + variation->Terrains.push_back(parent_variation->Terrains[i]); + } + + for (int i = 0; i < MaxImageLayers; ++i) { + variation->LayerFiles[i] = parent_variation->LayerFiles[i]; + } + for (std::map::iterator iterator = parent_variation->ButtonIcons.begin(); iterator != parent_variation->ButtonIcons.end(); ++iterator) { + variation->ButtonIcons[iterator->first].Name = iterator->second.Name; + variation->ButtonIcons[iterator->first].Icon = nullptr; + variation->ButtonIcons[iterator->first].Load(); + variation->ButtonIcons[iterator->first].Icon->Load(); } } + for (int i = 0; i < MaxImageLayers; ++i) { this->LayerFiles[i] = parent_type->LayerFiles[i]; //inherit layer variations - for (size_t j = 0; j < parent_type->LayerVarInfo[i].size(); ++j) { - VariationInfo *var = new VariationInfo; - - this->LayerVarInfo[i].push_back(var); + for (CUnitTypeVariation *parent_variation : parent_type->LayerVariations[i]) { + CUnitTypeVariation *variation = new CUnitTypeVariation; + + variation->ID = this->LayerVariations[i].size(); + this->LayerVariations[i].push_back(variation); - var->VariationId = parent_type->LayerVarInfo[i][j]->VariationId; - var->File = parent_type->LayerVarInfo[i][j]->File; - for (int u = 0; u < VariationMax; ++u) { - var->UpgradesRequired[u] = parent_type->LayerVarInfo[i][j]->UpgradesRequired[u]; - var->UpgradesForbidden[u] = parent_type->LayerVarInfo[i][j]->UpgradesForbidden[u]; - } - for (size_t u = 0; u < parent_type->LayerVarInfo[i][j]->ItemClassesEquipped.size(); ++u) { - var->ItemClassesEquipped.push_back(parent_type->LayerVarInfo[i][j]->ItemClassesEquipped[u]); + variation->VariationId = parent_variation->VariationId; + variation->File = parent_variation->File; + variation->UpgradesRequired = parent_variation->UpgradesRequired; + variation->UpgradesForbidden = parent_variation->UpgradesForbidden; + for (size_t u = 0; u < parent_variation->ItemClassesEquipped.size(); ++u) { + variation->ItemClassesEquipped.push_back(parent_variation->ItemClassesEquipped[u]); } - for (size_t u = 0; u < parent_type->LayerVarInfo[i][j]->ItemClassesNotEquipped.size(); ++u) { - var->ItemClassesNotEquipped.push_back(parent_type->LayerVarInfo[i][j]->ItemClassesNotEquipped[u]); + for (size_t u = 0; u < parent_variation->ItemClassesNotEquipped.size(); ++u) { + variation->ItemClassesNotEquipped.push_back(parent_variation->ItemClassesNotEquipped[u]); } - for (size_t u = 0; u < parent_type->LayerVarInfo[i][j]->ItemsEquipped.size(); ++u) { - var->ItemsEquipped.push_back(parent_type->LayerVarInfo[i][j]->ItemsEquipped[u]); + for (size_t u = 0; u < parent_variation->ItemsEquipped.size(); ++u) { + variation->ItemsEquipped.push_back(parent_variation->ItemsEquipped[u]); } - for (size_t u = 0; u < parent_type->LayerVarInfo[i][j]->ItemsNotEquipped.size(); ++u) { - var->ItemsNotEquipped.push_back(parent_type->LayerVarInfo[i][j]->ItemsNotEquipped[u]); + for (size_t u = 0; u < parent_variation->ItemsNotEquipped.size(); ++u) { + variation->ItemsNotEquipped.push_back(parent_variation->ItemsNotEquipped[u]); } - for (size_t u = 0; u < parent_type->LayerVarInfo[i][j]->Terrains.size(); ++u) { - var->Terrains.push_back(parent_type->LayerVarInfo[i][j]->Terrains[u]); + for (size_t u = 0; u < parent_variation->Terrains.size(); ++u) { + variation->Terrains.push_back(parent_variation->Terrains[u]); } } } @@ -1716,43 +1716,41 @@ int CUnitType::GetResourceStep(const int resource, const int player) const return resource_step; } -VariationInfo *CUnitType::GetDefaultVariation(CPlayer &player, int image_layer) const +CUnitTypeVariation *CUnitType::GetDefaultVariation(CPlayer &player, int image_layer) const { - int variation_max = image_layer == -1 ? VariationMax : this->LayerVarInfo[image_layer].size(); - for (int i = 0; i < variation_max; ++i) { - VariationInfo *varinfo = image_layer == -1 ? this->VarInfo[i] : this->LayerVarInfo[image_layer][i]; - if (!varinfo) { - break; - } - bool UpgradesCheck = true; - for (int u = 0; u < VariationMax; ++u) { - if (!varinfo->UpgradesRequired[u].empty() && UpgradeIdentAllowed(player, varinfo->UpgradesRequired[u].c_str()) != 'R') { - UpgradesCheck = false; + const std::vector &variation_list = image_layer == -1 ? this->Variations : this->LayerVariations[image_layer]; + for (CUnitTypeVariation *variation : variation_list) { + bool upgrades_check = true; + for (const CUpgrade *required_upgrade : variation->UpgradesRequired) { + if (UpgradeIdentAllowed(player, required_upgrade->Ident.c_str()) != 'R') { + upgrades_check = false; break; } - if (!varinfo->UpgradesForbidden[u].empty() && UpgradeIdentAllowed(player, varinfo->UpgradesForbidden[u].c_str()) == 'R') { - UpgradesCheck = false; - break; + } + + if (upgrades_check) { + for (const CUpgrade *forbidden_upgrade : variation->UpgradesForbidden) { + if (UpgradeIdentAllowed(player, forbidden_upgrade->Ident.c_str()) == 'R') { + upgrades_check = false; + break; + } } } - if (UpgradesCheck == false) { + + if (upgrades_check == false) { continue; } - return varinfo; + return variation; } return nullptr; } -VariationInfo *CUnitType::GetVariation(const std::string &variation_name, int image_layer) const +CUnitTypeVariation *CUnitType::GetVariation(const std::string &variation_name, int image_layer) const { - int variation_max = image_layer == -1 ? VariationMax : this->LayerVarInfo[image_layer].size(); - for (int i = 0; i < variation_max; ++i) { - VariationInfo *varinfo = image_layer == -1 ? this->VarInfo[i] : this->LayerVarInfo[image_layer][i]; - if (!varinfo) { - break; - } - if (varinfo->VariationId == variation_name) { - return varinfo; + const std::vector &variation_list = image_layer == -1 ? this->Variations : this->LayerVariations[image_layer]; + for (CUnitTypeVariation *variation : variation_list) { + if (variation->VariationId == variation_name) { + return variation; } } return nullptr; @@ -1761,13 +1759,10 @@ VariationInfo *CUnitType::GetVariation(const std::string &variation_name, int im std::string CUnitType::GetRandomVariationIdent(int image_layer) const { std::vector variation_idents; - int variation_max = image_layer == -1 ? VariationMax : this->LayerVarInfo[image_layer].size(); - for (int i = 0; i < variation_max; ++i) { - VariationInfo *varinfo = image_layer == -1 ? this->VarInfo[i] : this->LayerVarInfo[image_layer][i]; - if (!varinfo) { - break; - } - variation_idents.push_back(varinfo->VariationId); + + const std::vector &variation_list = image_layer == -1 ? this->Variations : this->LayerVariations[image_layer]; + for (const CUnitTypeVariation *variation : variation_list) { + variation_idents.push_back(variation->VariationId); } if (variation_idents.size() > 0) { @@ -1779,9 +1774,9 @@ std::string CUnitType::GetRandomVariationIdent(int image_layer) const std::string CUnitType::GetDefaultName(CPlayer &player) const { - VariationInfo *varinfo = this->GetDefaultVariation(player); - if (varinfo && !varinfo->TypeName.empty()) { - return varinfo->TypeName; + CUnitTypeVariation *variation = this->GetDefaultVariation(player); + if (variation && !variation->TypeName.empty()) { + return variation->TypeName; } else { return this->Name; } @@ -1789,11 +1784,11 @@ std::string CUnitType::GetDefaultName(CPlayer &player) const CPlayerColorGraphic *CUnitType::GetDefaultLayerSprite(CPlayer &player, int image_layer) const { - VariationInfo *varinfo = this->GetDefaultVariation(player); - if (this->LayerVarInfo[image_layer].size() > 0 && this->GetDefaultVariation(player, image_layer)->Sprite) { + CUnitTypeVariation *variation = this->GetDefaultVariation(player); + if (this->LayerVariations[image_layer].size() > 0 && this->GetDefaultVariation(player, image_layer)->Sprite) { return this->GetDefaultVariation(player, image_layer)->Sprite; - } else if (varinfo && varinfo->LayerSprites[image_layer]) { - return varinfo->LayerSprites[image_layer]; + } else if (variation && variation->LayerSprites[image_layer]) { + return variation->LayerSprites[image_layer]; } else if (this->LayerSprites[image_layer]) { return this->LayerSprites[image_layer]; } else { @@ -2712,80 +2707,72 @@ void LoadUnitTypeSprite(CUnitType &type) //Wyrmgus end //Wyrmgus start - for (int i = 0; i < VariationMax; ++i) { - VariationInfo *varinfo = type.VarInfo[i]; - if (!varinfo) { - continue; - } + for (CUnitTypeVariation *variation : type.Variations) { int frame_width = type.Width; int frame_height = type.Height; - if (varinfo->FrameWidth && varinfo->FrameHeight) { - frame_width = varinfo->FrameWidth; - frame_height = varinfo->FrameHeight; - } - if (!varinfo->File.empty()) { - varinfo->Sprite = CPlayerColorGraphic::New(varinfo->File, - frame_width, frame_height); - varinfo->Sprite->Load(); + if (variation->FrameWidth && variation->FrameHeight) { + frame_width = variation->FrameWidth; + frame_height = variation->FrameHeight; + } + if (!variation->File.empty()) { + variation->Sprite = CPlayerColorGraphic::New(variation->File, frame_width, frame_height); + variation->Sprite->Load(); if (type.Flip) { - varinfo->Sprite->Flip(); + variation->Sprite->Flip(); } } - if (!varinfo->ShadowFile.empty()) { - varinfo->ShadowSprite = CGraphic::New(varinfo->ShadowFile, type.ShadowWidth, type.ShadowHeight); - varinfo->ShadowSprite->Load(); + if (!variation->ShadowFile.empty()) { + variation->ShadowSprite = CGraphic::New(variation->ShadowFile, type.ShadowWidth, type.ShadowHeight); + variation->ShadowSprite->Load(); if (type.Flip) { - varinfo->ShadowSprite->Flip(); + variation->ShadowSprite->Flip(); } - if (varinfo->ShadowSprite->Surface->format->BytesPerPixel == 1) { -// varinfo->ShadowSprite->MakeShadow(); + if (variation->ShadowSprite->Surface->format->BytesPerPixel == 1) { +// variation->ShadowSprite->MakeShadow(); } } - if (!varinfo->LightFile.empty()) { - varinfo->LightSprite = CGraphic::New(varinfo->LightFile, frame_width, frame_height); - varinfo->LightSprite->Load(); + if (!variation->LightFile.empty()) { + variation->LightSprite = CGraphic::New(variation->LightFile, frame_width, frame_height); + variation->LightSprite->Load(); if (type.Flip) { - varinfo->LightSprite->Flip(); + variation->LightSprite->Flip(); } } for (int j = 0; j < MaxImageLayers; ++j) { - if (!varinfo->LayerFiles[j].empty()) { - varinfo->LayerSprites[j] = CPlayerColorGraphic::New(varinfo->LayerFiles[j], frame_width, frame_height); - varinfo->LayerSprites[j]->Load(); + if (!variation->LayerFiles[j].empty()) { + variation->LayerSprites[j] = CPlayerColorGraphic::New(variation->LayerFiles[j], frame_width, frame_height); + variation->LayerSprites[j]->Load(); if (type.Flip) { - varinfo->LayerSprites[j]->Flip(); + variation->LayerSprites[j]->Flip(); } } } for (int j = 0; j < MaxCosts; ++j) { - if (!varinfo->FileWhenLoaded[j].empty()) { - varinfo->SpriteWhenLoaded[j] = CPlayerColorGraphic::New(varinfo->FileWhenLoaded[j], - frame_width, frame_height); - varinfo->SpriteWhenLoaded[j]->Load(); + if (!variation->FileWhenLoaded[j].empty()) { + variation->SpriteWhenLoaded[j] = CPlayerColorGraphic::New(variation->FileWhenLoaded[j], frame_width, frame_height); + variation->SpriteWhenLoaded[j]->Load(); if (type.Flip) { - varinfo->SpriteWhenLoaded[j]->Flip(); + variation->SpriteWhenLoaded[j]->Flip(); } } - if (!varinfo->FileWhenEmpty[j].empty()) { - varinfo->SpriteWhenEmpty[j] = CPlayerColorGraphic::New(varinfo->FileWhenEmpty[j], - frame_width, frame_height); - varinfo->SpriteWhenEmpty[j]->Load(); + if (!variation->FileWhenEmpty[j].empty()) { + variation->SpriteWhenEmpty[j] = CPlayerColorGraphic::New(variation->FileWhenEmpty[j], frame_width, frame_height); + variation->SpriteWhenEmpty[j]->Load(); if (type.Flip) { - varinfo->SpriteWhenEmpty[j]->Flip(); + variation->SpriteWhenEmpty[j]->Flip(); } } } } for (int i = 0; i < MaxImageLayers; ++i) { - for (size_t j = 0; j < type.LayerVarInfo[i].size(); ++j) { - VariationInfo *varinfo = type.LayerVarInfo[i][j]; - if (!varinfo->File.empty()) { - varinfo->Sprite = CPlayerColorGraphic::New(varinfo->File, type.Width, type.Height); - varinfo->Sprite->Load(); + for (CUnitTypeVariation *layer_variation : type.LayerVariations[i]) { + if (!layer_variation->File.empty()) { + layer_variation->Sprite = CPlayerColorGraphic::New(layer_variation->File, type.Width, type.Height); + layer_variation->Sprite->Load(); if (type.Flip) { - varinfo->Sprite->Flip(); + layer_variation->Sprite->Flip(); } } } @@ -2836,13 +2823,9 @@ void LoadUnitType(CUnitType &type) type.Icon.Load(); } - for (int j = 0; j < VariationMax; ++j) { - VariationInfo *varinfo = type.VarInfo[j]; - if (!varinfo) { - continue; - } - if (!varinfo->Icon.Name.empty()) { - varinfo->Icon.Load(); + for (CUnitTypeVariation *variation : type.Variations) { + if (!variation->Icon.Name.empty()) { + variation->Icon.Load(); } } @@ -2940,8 +2923,7 @@ void CleanUnitTypes() //Wyrmgus end } -//Wyrmgus start -VariationInfo::~VariationInfo() +CUnitTypeVariation::~CUnitTypeVariation() { if (this->Sprite) { CGraphic::Free(this->Sprite); @@ -2967,6 +2949,7 @@ VariationInfo::~VariationInfo() } } +//Wyrmgus start std::string GetUnitTypeStatsString(const std::string &unit_type_ident) { const CUnitType *unit_type = UnitTypeByIdent(unit_type_ident); diff --git a/src/upgrade/upgrade.cpp b/src/upgrade/upgrade.cpp index c2aeea9d4..8ea7cfada 100644 --- a/src/upgrade/upgrade.cpp +++ b/src/upgrade/upgrade.cpp @@ -1758,30 +1758,31 @@ static void ApplyUpgradeModifier(CPlayer &player, const CUpgradeModifier *um) } //change variation if current one becomes forbidden - VariationInfo *current_varinfo = UnitTypes[z]->VarInfo[unit.Variation]; - if (current_varinfo) { - bool forbidden_upgrade = false; - for (int u = 0; u < VariationMax; ++u) { - if (!current_varinfo->UpgradesForbidden[u].empty() && um->UpgradeId == CUpgrade::Get(current_varinfo->UpgradesForbidden[u])->ID) { - forbidden_upgrade = true; + const CUnitTypeVariation *current_variation = unit.GetVariation(); + if (current_variation) { + bool upgrade_forbidden = false; + for (const CUpgrade *forbidden_upgrade : current_variation->UpgradesForbidden) { + if (um->UpgradeId == forbidden_upgrade->ID) { + upgrade_forbidden = true; break; } } - if (forbidden_upgrade == true) { + if (upgrade_forbidden == true) { unit.ChooseVariation(); } } for (int i = 0; i < MaxImageLayers; ++i) { - if (unit.LayerVariation[i] != -1 && unit.LayerVariation[i] < ((int) unit.Type->LayerVarInfo[i].size())) { - VariationInfo *current_layer_varinfo = UnitTypes[z]->LayerVarInfo[i][unit.LayerVariation[i]]; - bool forbidden_upgrade = false; - for (int u = 0; u < VariationMax; ++u) { - if (!current_layer_varinfo->UpgradesForbidden[u].empty() && um->UpgradeId == CUpgrade::Get(current_layer_varinfo->UpgradesForbidden[u])->ID) { - forbidden_upgrade = true; + const CUnitTypeVariation *current_layer_variation = unit.GetLayerVariation(i); + if (current_layer_variation) { + bool upgrade_forbidden = false; + for (const CUpgrade *forbidden_upgrade : current_layer_variation->UpgradesForbidden) { + if (um->UpgradeId == forbidden_upgrade->ID) { + upgrade_forbidden = true; break; } } - if (forbidden_upgrade == true) { + + if (upgrade_forbidden == true) { unit.ChooseVariation(nullptr, false, i); } } @@ -2053,30 +2054,30 @@ static void RemoveUpgradeModifier(CPlayer &player, const CUpgradeModifier *um) } //change variation if current one becomes forbidden - VariationInfo *current_varinfo = UnitTypes[z]->VarInfo[unit.Variation]; - if (current_varinfo) { - bool required_upgrade = false; - for (int u = 0; u < VariationMax; ++u) { - if (!current_varinfo->UpgradesRequired[u].empty() && um->UpgradeId == CUpgrade::Get(current_varinfo->UpgradesRequired[u])->ID) { - required_upgrade = true; + const CUnitTypeVariation *current_variation = unit.GetVariation(); + if (current_variation) { + bool upgrade_required = false; + for (const CUpgrade *required_upgrade : current_variation->UpgradesRequired) { + if (um->UpgradeId == required_upgrade->ID) { + upgrade_required = true; break; } } - if (required_upgrade == true) { + if (upgrade_required == true) { unit.ChooseVariation(); } } for (int i = 0; i < MaxImageLayers; ++i) { - if (unit.LayerVariation[i] != -1 && unit.LayerVariation[i] < ((int) unit.Type->LayerVarInfo[i].size())) { - VariationInfo *current_layer_varinfo = UnitTypes[z]->LayerVarInfo[i][unit.LayerVariation[i]]; - bool required_upgrade = false; - for (int u = 0; u < VariationMax; ++u) { - if (!current_layer_varinfo->UpgradesRequired[u].empty() && um->UpgradeId == CUpgrade::Get(current_layer_varinfo->UpgradesRequired[u])->ID) { - required_upgrade = true; + const CUnitTypeVariation *current_layer_variation = unit.GetLayerVariation(i); + if (current_layer_variation) { + bool upgrade_required = false; + for (const CUpgrade *required_upgrade : current_layer_variation->UpgradesRequired) { + if (um->UpgradeId == required_upgrade->ID) { + upgrade_required = true; break; } } - if (required_upgrade == true) { + if (upgrade_required == true) { unit.ChooseVariation(nullptr, false, i); } } @@ -2162,30 +2163,30 @@ void ApplyIndividualUpgradeModifier(CUnit &unit, const CUpgradeModifier *um) //Wyrmgus start //change variation if current one becomes forbidden - VariationInfo *current_varinfo = unit.Type->VarInfo[unit.Variation]; - if (current_varinfo) { - bool forbidden_upgrade = false; - for (int u = 0; u < VariationMax; ++u) { - if (!current_varinfo->UpgradesForbidden[u].empty() && um->UpgradeId == CUpgrade::Get(current_varinfo->UpgradesForbidden[u])->ID) { - forbidden_upgrade = true; + const CUnitTypeVariation *current_variation = unit.GetVariation(); + if (current_variation) { + bool upgrade_forbidden = false; + for (const CUpgrade *forbidden_upgrade : current_variation->UpgradesForbidden) { + if (um->UpgradeId == forbidden_upgrade->ID) { + upgrade_forbidden = true; break; } } - if (forbidden_upgrade == true) { + if (upgrade_forbidden == true) { unit.ChooseVariation(); } } for (int i = 0; i < MaxImageLayers; ++i) { - if (unit.LayerVariation[i] != -1 && unit.LayerVariation[i] < ((int) unit.Type->LayerVarInfo[i].size())) { - VariationInfo *current_layer_varinfo = unit.Type->LayerVarInfo[i][unit.LayerVariation[i]]; - bool forbidden_upgrade = false; - for (int u = 0; u < VariationMax; ++u) { - if (!current_layer_varinfo->UpgradesForbidden[u].empty() && um->UpgradeId == CUpgrade::Get(current_layer_varinfo->UpgradesForbidden[u])->ID) { - forbidden_upgrade = true; + const CUnitTypeVariation *current_layer_variation = unit.GetLayerVariation(i); + if (current_layer_variation) { + bool upgrade_forbidden = false; + for (const CUpgrade *forbidden_upgrade : current_layer_variation->UpgradesForbidden) { + if (um->UpgradeId == forbidden_upgrade->ID) { + upgrade_forbidden = true; break; } } - if (forbidden_upgrade == true) { + if (upgrade_forbidden == true) { unit.ChooseVariation(nullptr, false, i); } } @@ -2264,30 +2265,30 @@ void RemoveIndividualUpgradeModifier(CUnit &unit, const CUpgradeModifier *um) //Wyrmgus start //change variation if current one becomes forbidden - VariationInfo *current_varinfo = unit.Type->VarInfo[unit.Variation]; - if (current_varinfo) { - bool required_upgrade = false; - for (int u = 0; u < VariationMax; ++u) { - if (!current_varinfo->UpgradesRequired[u].empty() && um->UpgradeId == CUpgrade::Get(current_varinfo->UpgradesRequired[u])->ID) { - required_upgrade = true; + const CUnitTypeVariation *current_variation = unit.GetVariation(); + if (current_variation) { + bool upgrade_required = false; + for (const CUpgrade *required_upgrade : current_variation->UpgradesRequired) { + if (um->UpgradeId == required_upgrade->ID) { + upgrade_required = true; break; } } - if (required_upgrade == true) { + if (upgrade_required == true) { unit.ChooseVariation(); } } for (int i = 0; i < MaxImageLayers; ++i) { - if (unit.LayerVariation[i] != -1 && unit.LayerVariation[i] < ((int) unit.Type->LayerVarInfo[i].size())) { - VariationInfo *current_layer_varinfo = unit.Type->LayerVarInfo[i][unit.LayerVariation[i]]; - bool required_upgrade = false; - for (int u = 0; u < VariationMax; ++u) { - if (!current_layer_varinfo->UpgradesRequired[u].empty() && um->UpgradeId == CUpgrade::Get(current_layer_varinfo->UpgradesRequired[u])->ID) { - required_upgrade = true; + const CUnitTypeVariation *current_layer_variation = unit.GetLayerVariation(i); + if (current_layer_variation) { + bool upgrade_required = false; + for (const CUpgrade *required_upgrade : current_layer_variation->UpgradesRequired) { + if (um->UpgradeId == required_upgrade->ID) { + upgrade_required = true; break; } } - if (required_upgrade == true) { + if (upgrade_required == true) { unit.ChooseVariation(nullptr, false, i); } }