Skip to content

Commit

Permalink
Added support for defining unit type variations in config files
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrettin committed Jan 10, 2019
1 parent e1a74d3 commit 1d2b700
Show file tree
Hide file tree
Showing 4 changed files with 286 additions and 14 deletions.
3 changes: 3 additions & 0 deletions src/include/unit/unit_type_variation.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ class CUnitTypeVariation

~CUnitTypeVariation();

void ProcessConfigData(const CConfigData *config_data);

int ID = -1; /// The variation's index within the appropriate variation vector of its unit type
int ImageLayer = -1; /// The image layer to which the variation belongs (if any)
std::string VariationId; /// Variation's name.
std::string TypeName; /// Type name.
std::string File; /// Variation's graphics.
Expand Down
19 changes: 9 additions & 10 deletions src/unit/script_unittype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,23 +747,22 @@ static int CclDefineUnitType(lua_State *l)
if (!lua_istable(l, -1)) {
LuaError(l, "incorrect argument (expected table for variations)");
}
int image_layer = -1;
const int subargs = lua_rawlen(l, -1);
for (int k = 0; k < subargs; ++k) {
value = LuaToString(l, -1, k + 1);
++k;
if (!strcmp(value, "layer")) {
std::string image_layer_name = LuaToString(l, -1, k + 1);
image_layer = GetImageLayerIdByName(image_layer_name);
if (image_layer != -1) {
variation->ID = type->LayerVariations[image_layer].size();
type->LayerVariations[image_layer].push_back(variation);
variation->ImageLayer = GetImageLayerIdByName(image_layer_name);
if (variation->ImageLayer != -1) {
variation->ID = type->LayerVariations[variation->ImageLayer].size();
type->LayerVariations[variation->ImageLayer].push_back(variation);
} else {
LuaError(l, "Image layer \"%s\" doesn't exist." _C_ image_layer_name.c_str());
}
} else if (!strcmp(value, "variation-id")) {
variation->VariationId = LuaToString(l, -1, k + 1);
if (image_layer == -1) {
if (variation->ImageLayer == -1) {
variation->ID = type->Variations.size();
type->Variations.push_back(variation);
}
Expand Down Expand Up @@ -844,31 +843,31 @@ static int CclDefineUnitType(lua_State *l)
}
} else if (!strcmp(value, "item-equipped")) {
std::string type_ident = LuaToString(l, -1, k + 1);
CUnitType *type = UnitTypeByIdent(type_ident);
const CUnitType *type = UnitTypeByIdent(type_ident);
if (type) {
variation->ItemsEquipped.push_back(type);
} else {
LuaError(l, "Unit type %s not defined" _C_ type_ident.c_str());
}
} else if (!strcmp(value, "item-not-equipped")) {
std::string type_ident = LuaToString(l, -1, k + 1);
CUnitType *type = UnitTypeByIdent(type_ident);
const CUnitType *type = UnitTypeByIdent(type_ident);
if (type) {
variation->ItemsNotEquipped.push_back(type);
} else {
LuaError(l, "Unit type %s not defined" _C_ type_ident.c_str());
}
} else if (!strcmp(value, "terrain")) {
std::string terrain_ident = LuaToString(l, -1, k + 1);
CTerrainType *terrain = CTerrainType::GetTerrainType(terrain_ident);
const CTerrainType *terrain = CTerrainType::GetTerrainType(terrain_ident);
if (terrain) {
variation->Terrains.push_back(terrain);
} else {
LuaError(l, "Terrain type \"%s\" doesn't exist." _C_ terrain_ident.c_str());
}
} else if (!strcmp(value, "terrain-forbidden")) {
std::string terrain_ident = LuaToString(l, -1, k + 1);
CTerrainType *terrain = CTerrainType::GetTerrainType(terrain_ident);
const CTerrainType *terrain = CTerrainType::GetTerrainType(terrain_ident);
if (terrain) {
variation->TerrainsForbidden.push_back(terrain);
} else {
Expand Down
267 changes: 267 additions & 0 deletions src/unit/unit_type_variation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@

#include "unit/unit_type_variation.h"

#include "animation.h"
#include "config.h"
#include "construct.h"
#include "map/terrain_type.h"
#include "mod.h"
#include "time/season.h"
#include "ui/button_action.h"
#include "video.h"

/*----------------------------------------------------------------------------
Expand Down Expand Up @@ -66,3 +73,263 @@ CUnitTypeVariation::~CUnitTypeVariation()
}
}
}

/**
** @brief Process data provided by a configuration file
**
** @param config_data The configuration data
*/
void CUnitTypeVariation::ProcessConfigData(const CConfigData *config_data)
{
for (size_t i = 0; i < config_data->Properties.size(); ++i) {
std::string key = config_data->Properties[i].first;
std::string value = config_data->Properties[i].second;

if (key == "variation_id") {
value = FindAndReplaceString(value, "_", "-");
this->VariationId = value;
} else if (key == "layer") {
value = FindAndReplaceString(value, "_", "-");
this->ImageLayer = GetImageLayerIdByName(value);
if (this->ImageLayer == -1) {
fprintf(stderr, "Invalid image layer: \"%s\".\n", value.c_str());
}
} else if (key == "type_name") {
this->TypeName = value;
} else if (key == "file") {
this->File = CMod::GetCurrentModPath() + value;
} else if (key == "shadow_file") {
this->ShadowFile = CMod::GetCurrentModPath() + value;
} else if (key == "light_file") {
this->LightFile = CMod::GetCurrentModPath() + value;
} else if (key == "frame_width") {
this->FrameWidth = std::stoi(value);
} else if (key == "frame_height") {
this->FrameHeight = std::stoi(value);
} else if (key == "icon") {
value = FindAndReplaceString(value, "_", "-");
this->Icon.Name = value;
this->Icon.Icon = nullptr;
this->Icon.Load();
this->Icon.Icon->Load();
} else if (key == "animations") {
value = FindAndReplaceString(value, "_", "-");
this->Animations = AnimationsByIdent(value);
if (!this->Animations) {
fprintf(stderr, "Invalid animations: \"%s\".\n", value.c_str());
}
} else if (key == "construction") {
value = FindAndReplaceString(value, "_", "-");
this->Construction = ConstructionByIdent(value);
if (!this->Construction) {
fprintf(stderr, "Invalid construction: \"%s\".\n", value.c_str());
}
} else if (key == "required_upgrade") {
value = FindAndReplaceString(value, "_", "-");
const CUpgrade *upgrade = CUpgrade::Get(value);
if (upgrade != nullptr) {
this->UpgradesRequired.push_back(upgrade);
} else {
fprintf(stderr, "Invalid upgrade: \"%s\".\n", value.c_str());
}
} else if (key == "forbidden_upgrade") {
value = FindAndReplaceString(value, "_", "-");
const CUpgrade *upgrade = CUpgrade::Get(value);
if (upgrade != nullptr) {
this->UpgradesForbidden.push_back(upgrade);
} else {
fprintf(stderr, "Invalid upgrade: \"%s\".\n", value.c_str());
}
} else if (key == "item_class_equipped") {
value = FindAndReplaceString(value, "_", "-");
const int item_class = GetItemClassIdByName(value);
if (item_class != -1) {
this->ItemClassesEquipped.push_back(item_class);
} else {
fprintf(stderr, "Invalid item class: \"%s\".\n", value.c_str());
}
} else if (key == "item_class_not_equipped") {
value = FindAndReplaceString(value, "_", "-");
const int item_class = GetItemClassIdByName(value);
if (item_class != -1) {
this->ItemClassesNotEquipped.push_back(item_class);
} else {
fprintf(stderr, "Invalid item class: \"%s\".\n", value.c_str());
}
} else if (key == "item_equipped") {
value = FindAndReplaceString(value, "_", "-");
const CUnitType *unit_type = UnitTypeByIdent(value);
if (unit_type != nullptr) {
this->ItemsEquipped.push_back(unit_type);
} else {
fprintf(stderr, "Invalid unit type: \"%s\".\n", value.c_str());
}
} else if (key == "item_not_equipped") {
value = FindAndReplaceString(value, "_", "-");
const CUnitType *unit_type = UnitTypeByIdent(value);
if (unit_type != nullptr) {
this->ItemsNotEquipped.push_back(unit_type);
} else {
fprintf(stderr, "Invalid unit type: \"%s\".\n", value.c_str());
}
} else if (key == "terrain") {
value = FindAndReplaceString(value, "_", "-");
const CTerrainType *terrain_type = CTerrainType::GetTerrainType(value);
if (terrain_type != nullptr) {
this->Terrains.push_back(terrain_type);
}
} else if (key == "forbidden_terrain") {
value = FindAndReplaceString(value, "_", "-");
const CTerrainType *terrain_type = CTerrainType::GetTerrainType(value);
if (terrain_type != nullptr) {
this->TerrainsForbidden.push_back(terrain_type);
}
} else if (key == "season") {
value = FindAndReplaceString(value, "_", "-");
const CSeason *season = CSeason::GetSeason(value);
if (season != nullptr) {
this->Seasons.push_back(season);
}
} else if (key == "forbidden_season") {
value = FindAndReplaceString(value, "_", "-");
const CSeason *season = CSeason::GetSeason(value);
if (season != nullptr) {
this->ForbiddenSeasons.push_back(season);
}
} else if (key == "resource_min") {
this->ResourceMin = std::stoi(value);
} else if (key == "resource_max") {
this->ResourceMax = std::stoi(value);
} else if (key == "weight") {
this->Weight = std::stoi(value);
} else {
fprintf(stderr, "Invalid unit type variation property: \"%s\".\n", key.c_str());
}
}

for (const CConfigData *child_config_data : config_data->Children) {
if (child_config_data->Tag == "file_when_loaded") {
std::string file;
int resource = -1;

for (size_t j = 0; j < child_config_data->Properties.size(); ++j) {
std::string key = child_config_data->Properties[j].first;
std::string value = child_config_data->Properties[j].second;

if (key == "file") {
file = CMod::GetCurrentModPath() + value;
} else if (key == "resource") {
value = FindAndReplaceString(value, "_", "-");
resource = GetResourceIdByName(value.c_str());
} else {
fprintf(stderr, "Invalid unit type variation file when loaded property: \"%s\".\n", key.c_str());
}
}

if (file.empty()) {
fprintf(stderr, "Unit type variation file when loaded has no file.\n");
continue;
}

if (resource == -1) {
fprintf(stderr, "Unit type variation file when loaded has no resource.\n");
continue;
}

this->FileWhenLoaded[resource] = file;
} else if (child_config_data->Tag == "file_when_empty") {
std::string file;
int resource = -1;

for (size_t j = 0; j < child_config_data->Properties.size(); ++j) {
std::string key = child_config_data->Properties[j].first;
std::string value = child_config_data->Properties[j].second;

if (key == "file") {
file = CMod::GetCurrentModPath() + value;
} else if (key == "resource") {
value = FindAndReplaceString(value, "_", "-");
resource = GetResourceIdByName(value.c_str());
} else {
fprintf(stderr, "Invalid unit type variation file when empty property: \"%s\".\n", key.c_str());
}
}

if (file.empty()) {
fprintf(stderr, "Unit type variation file when empty has no file.\n");
continue;
}

if (resource == -1) {
fprintf(stderr, "Unit type variation file when empty has no resource.\n");
continue;
}

this->FileWhenEmpty[resource] = file;
} else if (child_config_data->Tag == "layer_file") {
std::string file;
int image_layer = -1;

for (size_t j = 0; j < child_config_data->Properties.size(); ++j) {
std::string key = child_config_data->Properties[j].first;
std::string value = child_config_data->Properties[j].second;

if (key == "file") {
file = CMod::GetCurrentModPath() + value;
} else if (key == "image_layer") {
value = FindAndReplaceString(value, "_", "-");
image_layer = GetImageLayerIdByName(value);
} else {
fprintf(stderr, "Invalid unit type variation layer file property: \"%s\".\n", key.c_str());
}
}

if (file.empty()) {
fprintf(stderr, "Unit type variation layer file has no file.\n");
continue;
}

if (image_layer == -1) {
fprintf(stderr, "Unit type variation layer file has no image layer.\n");
continue;
}

this->LayerFiles[image_layer] = file;
} else if (child_config_data->Tag == "button_icon") {
std::string icon_ident;
int button_action = -1;

for (size_t j = 0; j < child_config_data->Properties.size(); ++j) {
std::string key = child_config_data->Properties[j].first;
std::string value = child_config_data->Properties[j].second;

if (key == "icon") {
value = FindAndReplaceString(value, "_", "-");
icon_ident = value;
} else if (key == "button_action") {
value = FindAndReplaceString(value, "_", "-");
button_action = GetButtonActionIdByName(value);
} else {
fprintf(stderr, "Invalid unit type variation button icon property: \"%s\".\n", key.c_str());
}
}

if (icon_ident.empty()) {
fprintf(stderr, "Unit type variation button icon has no icon.\n");
continue;
}

if (button_action == -1) {
fprintf(stderr, "Unit type variation button icon has no button action.\n");
continue;
}

this->ButtonIcons[button_action].Name = icon_ident;
this->ButtonIcons[button_action].Icon = nullptr;
this->ButtonIcons[button_action].Load();
this->ButtonIcons[button_action].Icon->Load();
} else {
fprintf(stderr, "Invalid unit type variation property: \"%s\".\n", child_config_data->Tag.c_str());
}
}
}
11 changes: 7 additions & 4 deletions src/unit/unittype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1079,19 +1079,22 @@ 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);
if (variation->ImageLayer == -1) {
variation->ID = this->Variations.size();
this->Variations.push_back(variation);
} else {
variation->ID = this->LayerVariations[variation->ImageLayer].size();
this->LayerVariations[variation->ImageLayer].push_back(variation);
}

this->DefaultStat.Variables[VARIATION_INDEX].Max = this->Variations.size();
*/
} else {
std::string tag = SnakeCaseToPascalCase(child_config_data->Tag);

Expand Down

0 comments on commit 1d2b700

Please sign in to comment.