void MenuPowers::loadUpgrade(FileParser &infile) { // @ATTR upgrade.id|integer|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 = static_cast<short>(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_physoff|integer|Upgrade requires Physical and Offense stat of this value. if (infile.key == "requires_physoff") power_cell_upgrade.back().requires_physoff = static_cast<short>(toInt(infile.val)); // @ATTR upgrade.requires_physdef|integer|Upgrade requires Physical and Defense stat of this value. else if (infile.key == "requires_physdef") power_cell_upgrade.back().requires_physdef = static_cast<short>(toInt(infile.val)); // @ATTR upgrade.requires_mentoff|integer|Upgrade requires Mental and Offense stat of this value. else if (infile.key == "requires_mentoff") power_cell_upgrade.back().requires_mentoff = static_cast<short>(toInt(infile.val)); // @ATTR upgrade.requires_mentdef|integer|Upgrade requires Mental and Defense stat of this value. else if (infile.key == "requires_mentdef") power_cell_upgrade.back().requires_mentdef = static_cast<short>(toInt(infile.val)); // @ATTR upgrade.requires_defense|integer|Upgrade requires Defense stat of this value. else if (infile.key == "requires_defense") power_cell_upgrade.back().requires_defense = static_cast<short>(toInt(infile.val)); // @ATTR upgrade.requires_offense|integer|Upgrade requires Offense stat of this value. else if (infile.key == "requires_offense") power_cell_upgrade.back().requires_offense = static_cast<short>(toInt(infile.val)); // @ATTR upgrade.requires_physical|integer|Upgrade requires Physical stat of this value. else if (infile.key == "requires_physical") power_cell_upgrade.back().requires_physical = static_cast<short>(toInt(infile.val)); // @ATTR upgrade.requires_mental|integer|Upgrade requires Mental stat of this value. else if (infile.key == "requires_mental") power_cell_upgrade.back().requires_mental = static_cast<short>(toInt(infile.val)); // @ATTR upgrade.requires_point|boolean|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|integer|Upgrade requires at least this level for the hero. else if (infile.key == "requires_level") power_cell_upgrade.back().requires_level = static_cast<short>(toInt(infile.val)); // @ATTR upgrade.requires_power|integer|Upgrade requires another power id. else if (infile.key == "requires_power") power_cell_upgrade.back().requires_power.push_back(static_cast<short>(toInt(infile.val))); // @ATTR upgrade.visible_requires_status|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|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()); }
void Map::loadLayer(FileParser &infile) { if (infile.key == "type") { // @ATTR layer.type|string|Map layer type. layers.resize(layers.size()+1); layers.back().resize(w); for (size_t i=0; i<layers.back().size(); ++i) { layers.back()[i].resize(h); } layernames.push_back(infile.val); if (infile.val == "collision") collision_layer = static_cast<int>(layernames.size())-1; } else if (infile.key == "format") { // @ATTR layer.format|string|Format for map layer, must be 'dec' if (infile.val != "dec") { infile.error("Map: The format of a layer must be 'dec'!"); logErrorDialog("Map: The format of a layer must be 'dec'!"); mods->resetModConfig(); Exit(1); } } else if (infile.key == "data") { // @ATTR layer.data|raw|Raw map layer data // layer map data handled as a special case // The next h lines must contain layer data. for (int j=0; j<h; j++) { std::string val = infile.getRawLine(); infile.incrementLineNum(); if (!val.empty() && val[val.length()-1] != ',') { val += ','; } // verify the width of this row int comma_count = 0; for (unsigned i=0; i<val.length(); ++i) { if (val[i] == ',') comma_count++; } if (comma_count != w) { infile.error("Map: A row of layer data has a width not equal to %d.", w); mods->resetModConfig(); Exit(1); } for (int i=0; i<w; i++) layers.back()[i][j] = static_cast<unsigned short>(popFirstInt(val)); } } else { infile.error("Map: '%s' is not a valid key.", infile.key.c_str()); } }
MenuExit::MenuExit() : Menu() { // Load config settings FileParser infile; if(infile.open("menus/exit.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; else infile.error("MenuExit: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } exitClicked = false; buttonExit = new WidgetButton(); if (SAVE_ONEXIT) buttonExit->label = msg->get("Save & Exit"); else buttonExit->label = msg->get("Exit"); buttonClose = new WidgetButton("images/menus/buttons/button_x.png"); setBackground("images/menus/confirm_bg.png"); tablist.add(buttonExit); tablist.add(buttonClose); align(); }
void GameStatePlay::loadTitles() { FileParser infile; // @CLASS GameStatePlay: Titles|Description of engine/titles.txt if (infile.open("engine/titles.txt")) { while (infile.next()) { if (infile.new_section && infile.section == "title") { Title t; titles.push_back(t); } if (titles.empty()) continue; // @ATTR title.title|string|The displayed title. if (infile.key == "title") titles.back().title = infile.val; // @ATTR title.level|int|Requires level. else if (infile.key == "level") titles.back().level = toInt(infile.val); // @ATTR title.power|power_id|Requires power. else if (infile.key == "power") titles.back().power = toInt(infile.val); // @ATTR title.requires_status|string|Requires status. else if (infile.key == "requires_status") titles.back().requires_status = infile.val; // @ATTR title.requires_not_status|string|Requires not status. else if (infile.key == "requires_not_status") titles.back().requires_not = infile.val; // @ATTR title.primary_stat|predefined_string, predefined_string : Primary stat, Lesser primary stat|Required primary stat(s). The lesser stat is optional. else if (infile.key == "primary_stat") { titles.back().primary_stat_1 = popFirstString(infile.val); titles.back().primary_stat_2 = popFirstString(infile.val); } else infile.error("GameStatePlay: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } }
MenuActiveEffects::MenuActiveEffects(StatBlock *_stats) : timer(NULL) , stats(_stats) , orientation(false) { // horizontal // Load config settings FileParser infile; // @CLASS MenuActiveEffects|Description of menus/activeeffects.txt if(infile.open("menus/activeeffects.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR orientation|bool|True is vertical orientation; False is horizontal orientation. if(infile.key == "orientation") { orientation = toBool(infile.val); } else { infile.error("MenuActiveEffects: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } loadGraphics(); align(); }
void MenuBook::loadText(FileParser &infile) { // @ATTR text.text_pos|int, int, int, ["left", "center", "right"] : X, Y, Width, Text justify|Position of the text. if (infile.key == "text_pos") { size.back().x = popFirstInt(infile.val); size.back().y = popFirstInt(infile.val); size.back().w = popFirstInt(infile.val); std::string _justify = popFirstString(infile.val); if (_justify == "left") justify.back() = JUSTIFY_LEFT; else if (_justify == "center") justify.back() = JUSTIFY_CENTER; else if (_justify == "right") justify.back() = JUSTIFY_RIGHT; } // @ATTR text.text_font|color, string : Font color, Font style|Font color and style. else if (infile.key == "text_font") { Color color; color.r = static_cast<Uint8>(popFirstInt(infile.val)); color.g = static_cast<Uint8>(popFirstInt(infile.val)); color.b = static_cast<Uint8>(popFirstInt(infile.val)); textColor.back() = color; textFont.back() = popFirstString(infile.val); } // @ATTR text.text|string|The text to be displayed. else if (infile.key == "text") { // we use substr here to remove the comma from the end textData.back() = msg->get(infile.val.substr(0, infile.val.length() - 1)); } else { infile.error("MenuBook: '%s' is not a valid key.", infile.key.c_str()); } }
void GameSwitcher::loadMusic() { if (AUDIO && MUSIC_VOLUME) { Mix_FreeMusic(music); music = NULL; std::string music_filename = ""; FileParser infile; // @CLASS GameSwitcher: Default music|Description of engine/default_music.txt if (infile.open("engine/default_music.txt", true, "")) { while (infile.next()) { // @ATTR music|string|Filename of a music file to play during game states that don't already have music. if (infile.key == "music") music_filename = infile.val; else infile.error("GameSwitcher: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } if (music_filename != "") { music = Mix_LoadMUS((mods->locate(music_filename)).c_str()); if (!music) logError("GameSwitcher: Mix_LoadMUS: %s\n", Mix_GetError()); } } if (music) { Mix_VolumeMusic(MUSIC_VOLUME); Mix_PlayMusic(music, -1); } }
MenuHUDLog::MenuHUDLog() : overlay_bg(NULL) , click_to_dismiss(false) , hide_overlay(false) { // Load config settings FileParser infile; if(infile.open("menus/hudlog.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; else infile.error("MenuHUDLog: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } align(); font->setFont("font_regular"); paragraph_spacing = font->getLineHeight()/2; color_normal = font->getColor("menu_normal"); }
CombatText::CombatText() { msg_color[MSG_GIVEDMG] = font->getColor(FontEngine::COLOR_COMBAT_GIVEDMG); msg_color[MSG_TAKEDMG] = font->getColor(FontEngine::COLOR_COMBAT_TAKEDMG); msg_color[MSG_CRIT] = font->getColor(FontEngine::COLOR_COMBAT_CRIT); msg_color[MSG_BUFF] = font->getColor(FontEngine::COLOR_COMBAT_BUFF); msg_color[MSG_MISS] = font->getColor(FontEngine::COLOR_COMBAT_MISS); duration = settings->max_frames_per_sec; // 1 second speed = 60.f / settings->max_frames_per_sec; offset = 48; // average height of flare-game enemies, so a sensible default // Load config settings FileParser infile; // @CLASS CombatText|Description of engine/combat_text.txt if(infile.open("engine/combat_text.txt", FileParser::MOD_FILE, FileParser::ERROR_NORMAL)) { while(infile.next()) { if(infile.key == "duration") { // @ATTR duration|duration|Duration of the combat text in 'ms' or 's'. duration = Parse::toDuration(infile.val); } else if(infile.key == "speed") { // @ATTR speed|int|Motion speed of the combat text. speed = static_cast<float>(Parse::toInt(infile.val) * 60) / settings->max_frames_per_sec; } else if (infile.key == "offset") { // @ATTR offset|int|The vertical offset for the combat text's starting position. offset = Parse::toInt(infile.val); } else { infile.error("CombatText: '%s' is not a valid key.",infile.key.c_str()); } } infile.close(); } }
CombatText::CombatText() { msg_color[COMBAT_MESSAGE_GIVEDMG] = font->getColor("combat_givedmg"); msg_color[COMBAT_MESSAGE_TAKEDMG] = font->getColor("combat_takedmg"); msg_color[COMBAT_MESSAGE_CRIT] = font->getColor("combat_crit"); msg_color[COMBAT_MESSAGE_BUFF] = font->getColor("combat_buff"); msg_color[COMBAT_MESSAGE_MISS] = font->getColor("combat_miss"); duration = MAX_FRAMES_PER_SEC; // 1 second speed = 60.f / MAX_FRAMES_PER_SEC; offset = 48; // average height of flare-game enemies, so a sensible default // Load config settings FileParser infile; // @CLASS CombatText|Description of engine/combat_text.txt if(infile.open("engine/combat_text.txt")) { while(infile.next()) { if(infile.key == "duration") { // @ATTR duration|duration|Duration of the combat text in 'ms' or 's'. duration = parse_duration(infile.val); } else if(infile.key == "speed") { // @ATTR speed|int|Motion speed of the combat text. speed = static_cast<float>(toInt(infile.val) * 60) / MAX_FRAMES_PER_SEC; } else if (infile.key == "offset") { // @ATTR offset|int|The vertical offset for the combat text's starting position. offset = toInt(infile.val); } else { infile.error("CombatText: '%s' is not a valid key.",infile.key.c_str()); } } infile.close(); } }
void MenuBook::loadText(FileParser &infile) { // @ATTR text.text_pos|x (integer), y (integer), w (integer), [left:center:right]|Position of the text. if (infile.key == "text_pos") { size.back().x = popFirstInt(infile.val); size.back().y = popFirstInt(infile.val); size.back().w = popFirstInt(infile.val); std::string _justify = popFirstString(infile.val); if (_justify == "left") justify.back() = JUSTIFY_LEFT; else if (_justify == "center") justify.back() = JUSTIFY_CENTER; else if (_justify == "right") justify.back() = JUSTIFY_RIGHT; } // @ATTR text.text_font|r (integer), g (integer), b (integer), style (string)|Font color and style. else if (infile.key == "text_font") { Color color; color.r = popFirstInt(infile.val); color.g = popFirstInt(infile.val); color.b = popFirstInt(infile.val); textColor.back() = color; textFont.back() = popFirstString(infile.val); } // @ATTR text.text|string|The text to be displayed. else if (infile.key == "text") { textData.back() = infile.val; // remove comma from the end textData.back() = textData.back().substr(0, textData.back().length() - 1); } else { infile.error("MenuBook: '%s' is not a valid key.", infile.key.c_str()); } }
void GameStateConfigBase::readConfig() { //Load the menu configuration from file FileParser infile; if (infile.open("menus/config.txt")) { while (infile.next()) { if (parseKeyButtons(infile)) continue; int x1 = popFirstInt(infile.val); int y1 = popFirstInt(infile.val); int x2 = popFirstInt(infile.val); int y2 = popFirstInt(infile.val); if (parseKey(infile, x1, y1, x2, y2)) continue; else if (parseStub(infile)) continue; else { infile.error("GameStateConfigBase: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } }
LootManager::LootManager() : sfx_loot(0) , drop_max(1) , drop_radius(1) , hero(NULL) , tooltip_margin(0) { tip = new WidgetTooltip(); FileParser infile; // load loot animation settings from engine config file // @CLASS Loot|Description of engine/loot.txt if (infile.open("engine/loot.txt")) { while (infile.next()) { if (infile.key == "tooltip_margin") { // @ATTR tooltip_margin|integer|Vertical offset of the loot tooltip from the loot itself. tooltip_margin = toInt(infile.val); } else if (infile.key == "autopickup_currency") { // @ATTR autopickup_currency|boolean|Enable autopickup for currency AUTOPICKUP_CURRENCY = toBool(infile.val); } else if (infile.key == "currency_name") { // @ATTR currenct_name|string|Define the name of currency in game CURRENCY = msg->get(infile.val); } else if (infile.key == "vendor_ratio") { // @ATTR vendor_ratio|integer|Prices ratio for vendors VENDOR_RATIO = toInt(infile.val) / 100.0f; } else if (infile.key == "sfx_loot") { // @ATTR sfx_loot|string|Sound effect for dropping loot. sfx_loot = snd->load(infile.val, "LootManager dropping loot"); } else if (infile.key == "drop_max") { // @ATTR drop_max|integer|The maximum number of random item stacks that can drop at once drop_max = toInt(infile.val); clampFloor(drop_max, 1); } else if (infile.key == "drop_radius") { // @ATTR drop_radius|integer|The distance (in tiles) away from the origin that loot can drop drop_radius = toInt(infile.val); clampFloor(drop_radius, 1); } else { infile.error("LootManager: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } // reset current map loot loot.clear(); loadGraphics(); full_msg = false; loadLootTables(); }
void Map::loadNPC(FileParser &infile) { std::string s; if (infile.key == "type") { // @ATTR npc.type|string|(IGNORED BY ENGINE) The "type" field, as used by Tiled and other mapping tools. npcs.back().type = infile.val; } else if (infile.key == "filename") { // @ATTR npc.filename|string|Filename of an NPC definition. npcs.back().id = infile.val; } else if (infile.key == "requires_status") { // @ATTR npc.requires_status|list(string)|Status required for NPC load. There can be multiple states, separated by comma while ( (s = popFirstString(infile.val)) != "") npcs.back().requires_status.push_back(s); } else if (infile.key == "requires_not_status") { // @ATTR npc.requires_not_status|list(string)|Status required to be missing for NPC load. There can be multiple states, separated by comma while ( (s = popFirstString(infile.val)) != "") npcs.back().requires_not_status.push_back(s); } else if (infile.key == "location") { // @ATTR npc.location|point|Location of NPC npcs.back().pos.x = static_cast<float>(popFirstInt(infile.val)) + 0.5f; npcs.back().pos.y = static_cast<float>(popFirstInt(infile.val)) + 0.5f; } else { infile.error("Map: '%s' is not a valid key.", infile.key.c_str()); } }
void GameSwitcher::loadFPS() { // Load FPS rendering settings FileParser infile; // @CLASS GameSwitcher: FPS counter|Description of menus/fps.txt if (infile.open("menus/fps.txt")) { while(infile.next()) { // @ATTR position|x (integer), y (integer), align (alignment)|Position of the fps counter. if(infile.key == "position") { fps_position.x = popFirstInt(infile.val); fps_position.y = popFirstInt(infile.val); fps_corner = parse_alignment(popFirstString(infile.val)); } // @ATTR color|r (integer), g (integer), b (integer)|Color of the fps counter text. else if(infile.key == "color") { fps_color = toRGB(infile.val); } else { infile.error("GameSwitcher: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } // this is a dummy string used to approximate the fps position when aligned to the right font->setFont("font_regular"); fps_position.w = font->calc_width("00 fps"); fps_position.h = font->getLineHeight(); // Delete the label object if it exists (we'll recreate this with showFPS()) if (label_fps) { delete label_fps; label_fps = NULL; } }
void GameStatePlay::loadTitles() { FileParser infile; // @CLASS GameStatePlay: Titles|Description of engine/titles.txt if (infile.open("engine/titles.txt")) { while (infile.next()) { if (infile.new_section && infile.section == "title") { Title t; titles.push_back(t); } if (titles.empty()) continue; // @ATTR title.title|string|The displayed title. if (infile.key == "title") titles.back().title = infile.val; // @ATTR title.level|int|Requires level. else if (infile.key == "level") titles.back().level = toInt(infile.val); // @ATTR title.power|power_id|Requires power. else if (infile.key == "power") titles.back().power = toInt(infile.val); // @ATTR title.requires_status|string|Requires status. else if (infile.key == "requires_status") titles.back().requires_status = infile.val; // @ATTR title.requires_not_status|string|Requires not status. else if (infile.key == "requires_not_status") titles.back().requires_not = infile.val; // @ATTR title.primary_stat|["physical", "mental", "offense", "defense", "physoff", "physment", "physdef", "mentoff", "offdef", "mentdef"]|Required primary stat. else if (infile.key == "primary_stat") titles.back().primary_stat = infile.val; else infile.error("GameStatePlay: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } }
void LootManager::loadLootTables() { std::vector<std::string> filenames = mods->list("loot", false); for (unsigned i=0; i<filenames.size(); i++) { FileParser infile; if (!infile.open(filenames[i])) continue; std::vector<Event_Component> *ec_list = &loot_tables[filenames[i]]; Event_Component *ec = NULL; bool skip_to_next = false; while (infile.next()) { if (infile.section == "") { if (infile.key == "loot") { ec_list->push_back(Event_Component()); ec = &ec_list->back(); parseLoot(infile.val, ec, ec_list); } } else if (infile.section == "loot") { if (infile.new_section) { ec_list->push_back(Event_Component()); ec = &ec_list->back(); ec->type = EC_LOOT; skip_to_next = false; } if (skip_to_next || ec == NULL) continue; if (infile.key == "id") { ec->s = infile.val; if (ec->s == "currency") ec->c = CURRENCY_ID; else if (toInt(ec->s, -1) != -1) ec->c = toInt(ec->s); else { skip_to_next = true; infile.error("LootManager: Invalid item id for loot."); } } else if (infile.key == "chance") { if (infile.val == "fixed") ec->z = 0; else ec->z = toInt(infile.val); } else if (infile.key == "quantity") { ec->a = std::max(popFirstInt(infile.val), 1); ec->b = std::max(popFirstInt(infile.val), ec->a); } } } infile.close(); } }
void LootManager::loadLootTables() { std::vector<std::string> filenames = mods->list("loot", !ModManager::LIST_FULL_PATHS); for (unsigned i=0; i<filenames.size(); i++) { FileParser infile; if (!infile.open(filenames[i], FileParser::MOD_FILE, FileParser::ERROR_NORMAL)) continue; std::vector<EventComponent> *ec_list = &loot_tables[filenames[i]]; EventComponent *ec = NULL; bool skip_to_next = false; while (infile.next()) { if (infile.section == "") { if (infile.key == "loot") { ec_list->push_back(EventComponent()); ec = &ec_list->back(); parseLoot(infile.val, ec, ec_list); } } else if (infile.section == "loot") { if (infile.new_section) { ec_list->push_back(EventComponent()); ec = &ec_list->back(); ec->type = EventComponent::LOOT; skip_to_next = false; } if (skip_to_next || ec == NULL) continue; if (infile.key == "id") { ec->s = infile.val; if (ec->s == "currency") ec->c = eset->misc.currency_id; else if (Parse::toInt(ec->s, -1) != -1) ec->c = Parse::toInt(ec->s); else { skip_to_next = true; infile.error("LootManager: Invalid item id for loot."); } } else if (infile.key == "chance") { if (infile.val == "fixed") ec->f = 0; else ec->f = Parse::toFloat(infile.val); } else if (infile.key == "quantity") { ec->a = std::max(Parse::popFirstInt(infile.val), 1); ec->b = std::max(Parse::popFirstInt(infile.val), ec->a); } } } infile.close(); } }
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()); }
MenuTalker::MenuTalker(MenuManager *_menu) : Menu() , menu(_menu) , portrait(NULL) , dialog_node(0) , event_cursor(0) , font_who("font_regular") , font_dialog("font_regular") , color_normal(font->getColor("menu_normal")) , npc(NULL) , advanceButton(new WidgetButton("images/menus/buttons/right.png")) , closeButton(new WidgetButton("images/menus/buttons/button_x.png")) { setBackground("images/menus/dialog_box.png"); // Load config settings FileParser infile; // @CLASS MenuTalker|Description of menus/talker.txt if(infile.open("menus/talker.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR close|x (integer), y (integer)|Position of the close button. if(infile.key == "close") close_pos = toPoint(infile.val); // @ATTR advance|x (integer), y (integer)|Position of the button to advance dialog. else if(infile.key == "advance") advance_pos = toPoint(infile.val); // @ATTR dialogbox|x (integer), y (integer), w (integer), h (integer)|Position and dimensions of the text box graphics. else if (infile.key == "dialogbox") dialog_pos = toRect(infile.val); // @ATTR dialogtext|x (integer), y (integer), w (integer), h (integer)|Rectangle where the dialog text is placed. else if (infile.key == "dialogtext") text_pos = toRect(infile.val); // @ATTR text_offset|x (integer), y (integer)|Margins for the left/right and top/bottom of the dialog text. else if (infile.key == "text_offset") text_offset = toPoint(infile.val); // @ATTR portrait_he|x (integer), y (integer), w (integer), h (integer)|Position and dimensions of the NPC portrait graphics. else if (infile.key == "portrait_he") portrait_he = toRect(infile.val); // @ATTR portrait_you|x (integer), y (integer), w (integer), h (integer)|Position and dimensions of the player's portrait graphics. else if (infile.key == "portrait_you") portrait_you = toRect(infile.val); // @ATTR font_who|string|Font style to use for the name of the currently talking person. else if (infile.key == "font_who") font_who = infile.val; // @ATTR font_dialog|string|Font style to use for the dialog text. else if (infile.key == "font_dialog") font_dialog = infile.val; else infile.error("MenuTalker: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } label_name = new WidgetLabel(); textbox = new WidgetScrollBox(text_pos.w, text_pos.h-(text_offset.y*2)); tablist.add(advanceButton); tablist.add(closeButton); tablist.add(textbox); align(); alignElements(); }
MenuDevConsole::MenuDevConsole() : Menu() { button_close = new WidgetButton("images/menus/buttons/button_x.png"); tablist.add(button_close); input_box = new WidgetInput("images/menus/input_console.png"); tablist.add(input_box); button_confirm = new WidgetButton(); button_confirm->label = msg->get("Execute"); tablist.add(button_confirm); // Load config settings FileParser infile; // @CLASS MenuDevConsole|Description of menus/devconsole.txt if(infile.open("menus/devconsole.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR close|x (integer), y (integer)|Position of the close button. if(infile.key == "close") { Point pos = toPoint(infile.val); button_close->setBasePos(pos.x, pos.y); } // @ATTR label_title|label|Position of the "Developer Console" label. else if(infile.key == "label_title") title = eatLabelInfo(infile.val); // @ATTR confirm|x (integer), y (integer)|Position of the "Execute" button. else if(infile.key == "confirm") { Point pos = toPoint(infile.val); button_confirm->setBasePos(pos.x, pos.y); } // @ATTR input|x (integer), y (integer)|Position of the command entry widget. else if(infile.key == "input") { Point pos = toPoint(infile.val); input_box->setBasePos(pos.x, pos.y); } // @ATTR history|x (integer), y (integer), w (integer), h (integer)|Position and dimensions of the command history. else if(infile.key == "history") history_area = toRect(infile.val); else infile.error("MenuDevConsole: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } log_history = new WidgetLog(history_area.w, history_area.h); log_history->setBasePos(history_area.x, history_area.y); tablist.add(log_history->getWidget()); setBackground("images/menus/dev_console.png"); color_echo = font->getColor("widget_disabled"); color_error = font->getColor("menu_penalty"); align(); input_box->inFocus = true; }
MenuLog::MenuLog() { visible = false; closeButton = new WidgetButton("images/menus/buttons/button_x.png"); // Load config settings FileParser infile; // @CLASS MenuLog|Description of menus/log.txt if(infile.open("menus/log.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR label_title|label|Position of the "Log" text. if(infile.key == "label_title") { title = eatLabelInfo(infile.val); } // @ATTR close|point|Position of the close button. else if(infile.key == "close") { Point pos = toPoint(infile.val); closeButton->setBasePos(pos.x, pos.y); } // @ATTR tab_area|rectangle|The position of the row of tabs, followed by the dimensions of the log text area. else if(infile.key == "tab_area") { tab_area = toRect(infile.val); } else { infile.error("MenuLog: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } // Initialize the tab control. tabControl = new WidgetTabControl(); tablist.add(tabControl); // Store the amount of displayed log messages on each log, and the maximum. tablist_log.resize(LOG_TYPE_COUNT); for (unsigned i=0; i<LOG_TYPE_COUNT; i++) { log[i] = new WidgetLog(tab_area.w,tab_area.h); log[i]->setBasePos(tab_area.x, tab_area.y + tabControl->getTabHeight()); tablist_log[i].add(log[i]->getWidget()); tablist_log[i].setPrevTabList(&tablist); tablist_log[i].lock(); } // Define the header. tabControl->setTabTitle(LOG_TYPE_MESSAGES, msg->get("Notes")); tabControl->setTabTitle(LOG_TYPE_QUESTS, msg->get("Quests")); setBackground("images/menus/log.png"); align(); }
CursorManager::CursorManager() : cursor_normal(NULL) , cursor_interact(NULL) , cursor_talk(NULL) , cursor_attack(NULL) , cursor_current(NULL) , offset_current(NULL) { Image *graphics; FileParser infile; // @CLASS CursorManager|Description of engine/mouse_cursor.txt if (infile.open("engine/mouse_cursor.txt", true, "")) { while (infile.next()) { if (infile.key == "normal") { // @ATTR normal|string|Filename of an image for the normal cursor. graphics = render_device->loadImage(popFirstString(infile.val)); if (graphics) { cursor_normal = graphics->createSprite(); graphics->unref(); } offset_normal = toPoint(infile.val); } else if (infile.key == "interact") { // @ATTR interact|string|Filename of an image for the object interaction cursor. graphics = render_device->loadImage(popFirstString(infile.val)); if (graphics) { cursor_interact = graphics->createSprite(); graphics->unref(); } offset_interact = toPoint(infile.val); } else if (infile.key == "talk") { // @ATTR talk|string|Filename of an image for the NPC interaction cursor. graphics = render_device->loadImage(popFirstString(infile.val)); if (graphics) { cursor_talk = graphics->createSprite(); graphics->unref(); } offset_talk = toPoint(infile.val); } else if (infile.key == "attack") { // @ATTR attack|string|Filename of an image for the cursor when attacking enemies. graphics = render_device->loadImage(popFirstString(infile.val)); if (graphics) { cursor_attack = graphics->createSprite(); graphics->unref(); } offset_attack = toPoint(infile.val); } else { infile.error("CursorManager: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } }
/** * Load avatar sprite layer definitions into vector. */ void Avatar::loadLayerDefinitions() { layer_def = vector<vector<unsigned> >(8, vector<unsigned>()); layer_reference_order = vector<string>(); FileParser infile; // @CLASS Avatar: Hero layers|Description of engine/hero_layers.txt if (infile.open("engine/hero_layers.txt")) { while(infile.next()) { if (infile.key == "layer") { // @ATTR layer|direction (integer), string, ...]|Defines the hero avatar sprite layer unsigned dir = popFirstInt(infile.val); if (dir>7) { infile.error("Avatar: Hero layer direction must be in range [0,7]"); SDL_Quit(); exit(1); } string layer = popFirstString(infile.val); while (layer != "") { // check if already in layer_reference: unsigned ref_pos; for (ref_pos = 0; ref_pos < layer_reference_order.size(); ++ref_pos) if (layer == layer_reference_order[ref_pos]) break; if (ref_pos == layer_reference_order.size()) layer_reference_order.push_back(layer); layer_def[dir].push_back(ref_pos); layer = popFirstString(infile.val); } } else { infile.error("Avatar: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } // There are the positions of the items relative to layer_reference_order // so if layer_reference_order=main,body,head,off // and we got a layer=3,off,body,head,main // then the layer_def[3] looks like (3,1,2,0) }
void StatBlock::loadHeroStats() { // Redefine numbers from config file if present FileParser infile; // @CLASS StatBlock: Hero stats|Description of engine/stats.txt if (infile.open("engine/stats.txt")) { while (infile.next()) { int value = toInt(infile.val); bool valid = loadCoreStat(&infile); if (infile.key == "max_points_per_stat") { // @ATTR max_points_per_stat|integer|Maximum points for each primary stat. max_points_per_stat = value; } else if (infile.key == "sfx_step") { // @ATTR sfx_step|string|An id for a set of step sound effects. See items/step_sounds.txt. sfx_step = infile.val; } else if (infile.key == "stat_points_per_level") { // @ATTR stat_points_per_level|integer|The amount of stat points awarded each level. stat_points_per_level = value; } else if (infile.key == "power_points_per_level") { // @ATTR power_points_per_level|integer|The amount of power points awarded each level. power_points_per_level = value; } else if (!valid) { infile.error("StatBlock: '%s' is not a valid key.", infile.key.c_str()); } } infile.close(); } if (max_points_per_stat == 0) max_points_per_stat = max_spendable_stat_points / 4 + 1; statsLoaded = true; // load the XP table // @CLASS StatBlock: XP table|Description of engine/xp_table.txt if (infile.open("engine/xp_table.txt")) { while(infile.next()) { unsigned key = toInt(infile.key); if (key > 0) { // @ATTR $LEVEL|integer|The amount of XP required for this level. if (key > xp_table.size()) xp_table.resize(key); xp_table[key - 1] = toInt(infile.val); } } infile.close(); } max_spendable_stat_points = xp_table.size() * stat_points_per_level; }
void GameSwitcher::loadBackgroundList() { background_list.clear(); freeBackground(); FileParser infile; // @CLASS GameSwitcher: Background images|Description of engine/menu_backgrounds.txt if (infile.open("engine/menu_backgrounds.txt", true, "")) { while (infile.next()) { // @ATTR background|string|Filename of a background image to be added to the pool of random menu backgrounds if (infile.key == "background") background_list.push_back(infile.val); else infile.error("GameSwitcher: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } }
void Map::loadHeader(FileParser &infile) { if (infile.key == "title") { // @ATTR title|string|Title of map this->title = msg->get(infile.val); } else if (infile.key == "width") { // @ATTR width|int|Width of map this->w = static_cast<unsigned short>(std::max(toInt(infile.val), 1)); } else if (infile.key == "height") { // @ATTR height|int|Height of map this->h = static_cast<unsigned short>(std::max(toInt(infile.val), 1)); } else if (infile.key == "tileset") { // @ATTR tileset|filename|Filename of a tileset definition to use for map this->tileset = infile.val; } else if (infile.key == "music") { // @ATTR music|filename|Filename of background music to use for map music_filename = infile.val; } else if (infile.key == "hero_pos") { // @ATTR hero_pos|point|The player will spawn in this location if no point was previously given. hero_pos.x = static_cast<float>(popFirstInt(infile.val)) + 0.5f; hero_pos.y = static_cast<float>(popFirstInt(infile.val)) + 0.5f; hero_pos_enabled = true; } else if (infile.key == "parallax_layers") { // @ATTR parallax_layers|filename|Filename of a parallax layers definition. parallax_filename = infile.val; } else if (infile.key == "background_color") { // @ATTR background_color|color, int : Color, alpha|Background color for the map. background_color = toRGBA(infile.val); } else if (infile.key == "tilewidth") { // @ATTR tilewidth|int|Inherited from Tiled map file. Unused by engine. } else if (infile.key == "tileheight") { // @ATTR tileheight|int|Inherited from Tiled map file. Unused by engine. } else if (infile.key == "orientation") { // this is only used by Tiled when importing Flare maps } else { infile.error("Map: '%s' is not a valid key.", infile.key.c_str()); } }
MenuPowers::MenuPowers(StatBlock *_stats, MenuActionBar *_action_bar) : stats(_stats) , action_bar(_action_bar) , skip_section(false) , powers_unlock(NULL) , overlay_disabled(NULL) , points_left(0) , default_background("") , tab_control(NULL) , tree_loaded(false) , prev_powers_list_size(0) , newPowerNotification(false) { closeButton = new WidgetButton("images/menus/buttons/button_x.png"); // Read powers data from config file FileParser infile; // @CLASS MenuPowers: Menu layout|Description of menus/powers.txt if (infile.open("menus/powers.txt")) { while (infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR label_title|label|Position of the "Powers" text. if (infile.key == "label_title") title = eatLabelInfo(infile.val); // @ATTR unspent_points|label|Position of the text that displays the amount of unused power points. else if (infile.key == "unspent_points") unspent_points = eatLabelInfo(infile.val); // @ATTR close|point|Position of the close button. else if (infile.key == "close") close_pos = toPoint(infile.val); // @ATTR tab_area|rectangle|Position and dimensions of the tree pages. else if (infile.key == "tab_area") tab_area = toRect(infile.val); else infile.error("MenuPowers: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } loadGraphics(); menu_powers = this; color_bonus = font->getColor("menu_bonus"); color_penalty = font->getColor("menu_penalty"); color_flavor = font->getColor("item_flavor"); align(); }
void ItemManager::parseBonus(BonusData& bdata, FileParser& infile) { std::string bonus_str = Parse::popFirstString(infile.val); bdata.value = Parse::popFirstInt(infile.val); if (bonus_str == "speed") { bdata.is_speed = true; return; } else if (bonus_str == "attack_speed") { bdata.is_attack_speed = true; return; } for (int i=0; i<Stats::COUNT; ++i) { if (bonus_str == Stats::KEY[i]) { bdata.stat_index = static_cast<Stats::STAT>(i); return; } } for (size_t i = 0; i < eset->damage_types.list.size(); ++i) { if (bonus_str == eset->damage_types.list[i].min) { bdata.damage_index_min = static_cast<int>(i); return; } else if (bonus_str == eset->damage_types.list[i].max) { bdata.damage_index_max = static_cast<int>(i); return; } } for (unsigned i=0; i<eset->elements.list.size(); ++i) { if (bonus_str == eset->elements.list[i].id + "_resist") { bdata.resist_index = i; return; } } for (size_t i = 0; i < eset->primary_stats.list.size(); ++i) { if (bonus_str == eset->primary_stats.list[i].id) { bdata.base_index = static_cast<int>(i); return; } } infile.error("ItemManager: Unknown bonus type '%s'.", bonus_str.c_str()); }
MenuNPCActions::MenuNPCActions() : Menu() , npc(NULL) , is_selected(false) , is_empty(true) , first_dialog_node(-1) , current_action(-1) , action_menu(NULL) , vendor_label(msg->get("Trade")) , cancel_label(msg->get("Cancel")) , dialog_selected(false) , vendor_selected(false) , cancel_selected(false) , selected_dialog_node(-1) { // Load config settings FileParser infile; // @CLASS MenuNPCActions|Description of menus/npc.txt if (infile.open("menus/npc.txt")) { while(infile.next()) { if (parseMenuKey(infile.key, infile.val)) continue; // @ATTR background_color|r (integer), g (integer), b (integer), a (integer)|Color and alpha of the menu's background. if(infile.key == "background_color") background_color = toRGBA(infile.val); // @ATTR topic_normal_color|r (integer), g (integer), b (integer)|The normal color of a generic topic text. else if(infile.key == "topic_normal_color") topic_normal_color = toRGB(infile.val); // @ATTR topic_hilight_color|r (integer), g (integer), b (integer)|The color of generic topic text when it's hovered over or selected. else if(infile.key == "topic_hilight_color") topic_hilight_color = toRGB(infile.val); // @ATTR vendor_normal_color|r (integer), g (integer), b (integer)|The normal color of the vendor option text. else if(infile.key == "vendor_normal_color") vendor_normal_color = toRGB(infile.val); // @ATTR vendor_hilight_color|r (integer), g (integer), b (integer)|The color of vendor option text when it's hovered over or selected. else if(infile.key == "vendor_hilight_color") vendor_hilight_color = toRGB(infile.val); // @ATTR cancel_normal_color|r (integer), g (integer), b (integer)|The normal color of the option to close the menu. else if(infile.key == "cancel_normal_color") cancel_normal_color = toRGB(infile.val); // @ATTR cancel_hilight_color|r (integer), g (integer), b (integer)|The color of the option to close the menu when it's hovered over or selected. else if(infile.key == "cancel_hilight_color") cancel_hilight_color = toRGB(infile.val); else infile.error("MenuNPCActions: '%s' is not a valid key.", infile.key.c_str()); } infile.close(); } // save the x/y pos coordinates here, since we call align() during each update() call base_pos.x = window_area.x; base_pos.y = window_area.y; }