void MenuPowers::loadUpgrade(FileParser &infile) { // @ATTR upgrade.id|int|A power id from powers/powers.txt for this upgrade. if (infile.key == "id") { int id = popFirstInt(infile.val); if (id > 0) { skip_section = false; power_cell_upgrade.back().id = (id); } else { skip_section = true; power_cell_upgrade.pop_back(); infile.error("MenuPowers: Power index out of bounds 1-%d, skipping power.", INT_MAX); } return; } if (skip_section) return; // @ATTR upgrade.requires_primary|predefined_string, int : Primary stat name, Required value|Upgrade requires this primary stat to be at least the specificed value. if (infile.key == "requires_primary") { std::string prim_stat = popFirstString(infile.val); size_t prim_stat_index = getPrimaryStatIndex(prim_stat); if (prim_stat_index != PRIMARY_STATS.size()) { power_cell_upgrade.back().requires_primary[prim_stat_index] = toInt(infile.val); } else { infile.error("MenuPowers: '%s' is not a valid primary stat.", prim_stat.c_str()); } } // @ATTR upgrade.requires_point|bool|Upgrade requires a power point to unlock. else if (infile.key == "requires_point") power_cell_upgrade.back().requires_point = toBool(infile.val); // @ATTR upgrade.requires_level|int|Upgrade requires at least this level for the hero. else if (infile.key == "requires_level") power_cell_upgrade.back().requires_level = toInt(infile.val); // @ATTR upgrade.requires_power|int|Upgrade requires another power id. else if (infile.key == "requires_power") power_cell_upgrade.back().requires_power.push_back(toInt(infile.val)); // @ATTR upgrade.visible_requires_status|repeatable(string)|Hide the upgrade if we don't have this campaign status. else if (infile.key == "visible_requires_status") power_cell_upgrade.back().visible_requires_status.push_back(infile.val); // @ATTR upgrade.visible_requires_not_status|repeatable(string)|Hide the upgrade if we have this campaign status. else if (infile.key == "visible_requires_not_status") power_cell_upgrade.back().visible_requires_not.push_back(infile.val); else infile.error("MenuPowers: '%s' is not a valid key.", infile.key.c_str()); }
bool StatBlock::loadCoreStat(FileParser *infile) { // @CLASS StatBlock: Core stats|Description of engine/stats.txt and enemies in enemies/ if (infile->key == "speed") { // @ATTR speed|float|Movement speed float fvalue = toFloat(infile->val, 0); speed = speed_default = fvalue / MAX_FRAMES_PER_SEC; return true; } else if (infile->key == "cooldown") { // @ATTR cooldown|int|Cooldown between attacks in 'ms' or 's'. cooldown = parse_duration(infile->val); return true; } else if (infile->key == "cooldown_hit") { // @ATTR cooldown_hit|duration|Duration of cooldown after being hit in 'ms' or 's'. cooldown_hit = parse_duration(infile->val); return true; } else if (infile->key == "stat") { // @ATTR stat|string, int : Stat name, Value|The starting value for this stat. std::string stat = popFirstString(infile->val); int value = popFirstInt(infile->val); for (size_t i=0; i<STAT_COUNT; ++i) { if (STAT_KEY[i] == stat) { starting[i] = value; return true; } } for (size_t i = 0; i < DAMAGE_TYPES.size(); ++i) { if (DAMAGE_TYPES[i].min == stat) { starting[STAT_COUNT + (i*2)] = value; return true; } else if (DAMAGE_TYPES[i].max == stat) { starting[STAT_COUNT + (i*2) + 1] = value; return true; } } } else if (infile->key == "stat_per_level") { // @ATTR stat_per_level|predefined_string, int : Stat name, Value|The value for this stat added per level. std::string stat = popFirstString(infile->val); int value = popFirstInt(infile->val); for (unsigned i=0; i<STAT_COUNT; i++) { if (STAT_KEY[i] == stat) { per_level[i] = value; return true; } } for (size_t i = 0; i < DAMAGE_TYPES.size(); ++i) { if (DAMAGE_TYPES[i].min == stat) { per_level[STAT_COUNT + (i*2)] = value; return true; } else if (DAMAGE_TYPES[i].max == stat) { per_level[STAT_COUNT + (i*2) + 1] = value; return true; } } } else if (infile->key == "stat_per_primary") { // @ATTR stat_per_primary|predefined_string, predefined_string, int : Primary Stat, Stat name, Value|The value for this stat added for every point allocated to this primary stat. std::string prim_stat = popFirstString(infile->val); size_t prim_stat_index = getPrimaryStatIndex(prim_stat); std::string stat = popFirstString(infile->val); int value = popFirstInt(infile->val); for (unsigned i=0; i<STAT_COUNT; i++) { if (STAT_KEY[i] == stat) { per_primary[prim_stat_index][i] = value; return true; } } for (size_t i = 0; i < DAMAGE_TYPES.size(); ++i) { if (DAMAGE_TYPES[i].min == stat) { per_primary[prim_stat_index][STAT_COUNT + (i*2)] = value; return true; } else if (DAMAGE_TYPES[i].max == stat) { per_primary[prim_stat_index][STAT_COUNT + (i*2) + 1] = value; return true; } } } else if (infile->key == "vulnerable") { // @ATTR vulnerable|predefined_string, int : Element, Value|Percentage weakness to this element. std::string element = popFirstString(infile->val); int value = popFirstInt(infile->val); for (unsigned int i=0; i<ELEMENTS.size(); i++) { if (element == ELEMENTS[i].id) { vulnerable[i] = vulnerable_base[i] = value; return true; } } } else if (infile->key == "power_filter") { // @ATTR power_filter|list(power_id)|Only these powers are allowed to hit this entity. std::string power_id = popFirstString(infile->val); while (!power_id.empty()) { power_filter.push_back(toInt(power_id)); power_id = popFirstString(infile->val); } return true; } return false; }
void MenuPowers::loadPower(FileParser &infile) { // @ATTR power.id|int|A power id from powers/powers.txt for this slot. if (infile.key == "id") { int id = popFirstInt(infile.val); if (id > 0) { skip_section = false; power_cell.back().id = id; } else { infile.error("MenuPowers: Power index out of bounds 1-%d, skipping power.", INT_MAX); } return; } if (power_cell.back().id <= 0) { skip_section = true; power_cell.pop_back(); slots.pop_back(); upgradeButtons.pop_back(); logError("MenuPowers: There is a power without a valid id as the first attribute. IDs must be the first attribute in the power menu definition."); } if (skip_section) return; // @ATTR power.tab|int|Tab index to place this power on, starting from 0. if (infile.key == "tab") power_cell.back().tab = toInt(infile.val); // @ATTR power.position|point|Position of this power icon; relative to MenuPowers "pos". else if (infile.key == "position") power_cell.back().pos = toPoint(infile.val); // @ATTR power.requires_primary|predefined_string, int : Primary stat name, Required value|Power requires this primary stat to be at least the specificed value. else if (infile.key == "requires_primary") { std::string prim_stat = popFirstString(infile.val); size_t prim_stat_index = getPrimaryStatIndex(prim_stat); if (prim_stat_index != PRIMARY_STATS.size()) { power_cell.back().requires_primary[prim_stat_index] = toInt(infile.val); } else { infile.error("MenuPowers: '%s' is not a valid primary stat.", prim_stat.c_str()); } } // @ATTR power.requires_point|bool|Power requires a power point to unlock. else if (infile.key == "requires_point") power_cell.back().requires_point = toBool(infile.val); // @ATTR power.requires_level|int|Power requires at least this level for the hero. else if (infile.key == "requires_level") power_cell.back().requires_level = toInt(infile.val); // @ATTR power.requires_power|power_id|Power requires another power id. else if (infile.key == "requires_power") power_cell.back().requires_power.push_back(toInt(infile.val)); // @ATTR power.visible_requires_status|repeatable(string)|Hide the power if we don't have this campaign status. else if (infile.key == "visible_requires_status") power_cell.back().visible_requires_status.push_back(infile.val); // @ATTR power.visible_requires_not_status|repeatable(string)|Hide the power if we have this campaign status. else if (infile.key == "visible_requires_not_status") power_cell.back().visible_requires_not.push_back(infile.val); // @ATTR power.upgrades|list(power_id)|A list of upgrade power ids that this power slot can upgrade to. Each of these powers should have a matching upgrade section. else if (infile.key == "upgrades") { if (power_cell.back().upgrades.empty()) { upgradeButtons.back() = new WidgetButton("images/menus/buttons/button_plus.png"); } std::string repeat_val = popFirstString(infile.val); while (repeat_val != "") { power_cell.back().upgrades.push_back(toInt(repeat_val)); repeat_val = popFirstString(infile.val); } if (!power_cell.back().upgrades.empty()) power_cell.back().upgrade_level = 1; } else infile.error("MenuPowers: '%s' is not a valid key.", infile.key.c_str()); }