本文整理汇总了C++中FileParser::next方法的典型用法代码示例。如果您正苦于以下问题:C++ FileParser::next方法的具体用法?C++ FileParser::next怎么用?C++ FileParser::next使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类FileParser
的用法示例。
在下文中一共展示了FileParser::next方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: load
/**
* Load a specific items file
*
* @param filename The full path and name of the file to load
*/
void ItemManager::load(const string& filename) {
FileParser infile;
int id = 0;
string s;
int bonus_counter = 0;
if (infile.open(filename)) {
while (infile.next()) {
if (infile.key == "id") {
id = atoi(infile.val.c_str());
// new item, reset bonus counter
bonus_counter = 0;
}
else if (infile.key == "name")
items[id].name = msg->get(infile.val);
else if (infile.key == "level")
items[id].level = atoi(infile.val.c_str());
else if (infile.key == "icon") {
items[id].icon32 = atoi(infile.nextValue().c_str());
items[id].icon64 = atoi(infile.nextValue().c_str());
}
else if (infile.key == "quality") {
if (infile.val == "low")
items[id].quality = ITEM_QUALITY_LOW;
else if (infile.val == "high")
items[id].quality = ITEM_QUALITY_HIGH;
else if (infile.val == "epic")
items[id].quality = ITEM_QUALITY_EPIC;
}
else if (infile.key == "type") {
if (infile.val == "main")
items[id].type = ITEM_TYPE_MAIN;
else if (infile.val == "body")
items[id].type = ITEM_TYPE_BODY;
else if (infile.val == "off")
items[id].type = ITEM_TYPE_OFF;
else if (infile.val == "artifact")
items[id].type = ITEM_TYPE_ARTIFACT;
else if (infile.val == "consumable")
items[id].type = ITEM_TYPE_CONSUMABLE;
else if (infile.val == "gem")
items[id].type = ITEM_TYPE_GEM;
else if (infile.val == "quest")
items[id].type = ITEM_TYPE_QUEST;
}
else if (infile.key == "dmg") {
items[id].dmg_min = atoi(infile.nextValue().c_str());
if (infile.val.length() > 0)
items[id].dmg_max = atoi(infile.nextValue().c_str());
else
items[id].dmg_max = items[id].dmg_min;
}
else if (infile.key == "abs") {
items[id].abs_min = atoi(infile.nextValue().c_str());
if (infile.val.length() > 0)
items[id].abs_max = atoi(infile.nextValue().c_str());
else
items[id].abs_max = items[id].abs_min;
}
else if (infile.key == "req") {
s = infile.nextValue();
if (s == "p")
items[id].req_stat = REQUIRES_PHYS;
else if (s == "m")
items[id].req_stat = REQUIRES_MENT;
else if (s == "o")
items[id].req_stat = REQUIRES_OFF;
else if (s == "d")
items[id].req_stat = REQUIRES_DEF;
items[id].req_val = atoi(infile.nextValue().c_str());
}
else if (infile.key == "bonus") {
if (bonus_counter < ITEM_MAX_BONUSES) {
items[id].bonus_stat[bonus_counter] = infile.nextValue();
items[id].bonus_val[bonus_counter] = atoi(infile.nextValue().c_str());
bonus_counter++;
}
}
else if (infile.key == "sfx") {
if (infile.val == "book")
items[id].sfx = SFX_BOOK;
else if (infile.val == "cloth")
items[id].sfx = SFX_CLOTH;
else if (infile.val == "coins")
items[id].sfx = SFX_COINS;
else if (infile.val == "gem")
items[id].sfx = SFX_GEM;
else if (infile.val == "leather")
items[id].sfx = SFX_LEATHER;
else if (infile.val == "metal")
items[id].sfx = SFX_METAL;
else if (infile.val == "page")
items[id].sfx = SFX_PAGE;
//.........这里部分代码省略.........
示例2: if
MenuDevConsole::MenuDevConsole()
: Menu()
, input_scrollback_pos(0)
{
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");
color_hint = font->getColor("menu_bonus");
align();
input_box->inFocus = true;
}
示例3: load
/**
* load a statblock, typically for an enemy definition
*/
void StatBlock::load(string filename) {
FileParser infile;
int num;
if (infile.open(PATH_DATA + filename)) {
while (infile.next()) {
if (isInt(infile.val)) num = atoi(infile.val.c_str());
if (infile.key == "name") name = infile.val;
else if (infile.key == "sfx_prefix") sfx_prefix = infile.val;
else if (infile.key == "gfx_prefix") gfx_prefix = infile.val;
else if (infile.key == "level") level = num;
// enemy death rewards and events
else if (infile.key == "xp") xp = num;
else if (infile.key == "loot_chance") loot_chance = num;
else if (infile.key == "defeat_status") defeat_status = infile.val;
else if (infile.key == "first_defeat_loot") first_defeat_loot = num;
else if (infile.key == "quest_loot") {
quest_loot_requires = infile.nextValue();
quest_loot_not = infile.nextValue();
quest_loot_id = atoi(infile.nextValue().c_str());
}
// combat stats
else if (infile.key == "hp") {
hp = num;
maxhp = num;
}
else if (infile.key == "mp") {
mp = num;
maxmp = num;
}
else if (infile.key == "cooldown") cooldown = num;
else if (infile.key == "accuracy") accuracy = num;
else if (infile.key == "avoidance") avoidance = num;
else if (infile.key == "dmg_melee_min") dmg_melee_min = num;
else if (infile.key == "dmg_melee_max") dmg_melee_max = num;
else if (infile.key == "dmg_ment_min") dmg_ment_min = num;
else if (infile.key == "dmg_ment_max") dmg_ment_max = num;
else if (infile.key == "dmg_ranged_min") dmg_ranged_min = num;
else if (infile.key == "dmg_ranged_max") dmg_ranged_max = num;
else if (infile.key == "absorb_min") absorb_min = num;
else if (infile.key == "absorb_max") absorb_max = num;
// behavior stats
else if (infile.key == "speed") speed = num;
else if (infile.key == "dspeed") dspeed = num;
else if (infile.key == "dir_favor") dir_favor = num;
else if (infile.key == "chance_pursue") chance_pursue = num;
else if (infile.key == "chance_flee") chance_flee = num;
else if (infile.key == "chance_melee_phys") power_chance[MELEE_PHYS] = num;
else if (infile.key == "chance_melee_ment") power_chance[MELEE_MENT] = num;
else if (infile.key == "chance_ranged_phys") power_chance[RANGED_PHYS] = num;
else if (infile.key == "chance_ranged_ment") power_chance[RANGED_MENT] = num;
else if (infile.key == "power_melee_phys") power_index[MELEE_PHYS] = num;
else if (infile.key == "power_melee_ment") power_index[MELEE_MENT] = num;
else if (infile.key == "power_ranged_phys") power_index[RANGED_PHYS] = num;
else if (infile.key == "power_ranged_ment") power_index[RANGED_MENT] = num;
else if (infile.key == "power_beacon") power_index[BEACON] = num;
else if (infile.key == "cooldown_melee_phys") power_cooldown[MELEE_PHYS] = num;
else if (infile.key == "cooldown_melee_ment") power_cooldown[MELEE_MENT] = num;
else if (infile.key == "cooldown_ranged_phys") power_cooldown[RANGED_PHYS] = num;
else if (infile.key == "cooldown_ranged_ment") power_cooldown[RANGED_MENT] = num;
else if (infile.key == "melee_range") melee_range = num;
else if (infile.key == "threat_range") threat_range = num;
else if (infile.key == "attunement_fire") attunement_fire=num;
else if (infile.key == "attunement_ice") attunement_ice=num;
// animation stats
else if (infile.key == "melee_weapon_power") melee_weapon_power = num;
else if (infile.key == "mental_weapon_power") mental_weapon_power = num;
else if (infile.key == "ranged_weapon_power") ranged_weapon_power = num;
else if (infile.key == "animations") animations = infile.val;
else if (infile.key == "animation_speed") animationSpeed = num;
}
infile.close();
}
}
示例4: loadItems
/**
* Load a specific items file
*
* @param filename The (full) path and name of the file to load
*/
void ItemManager::loadItems(const std::string& filename) {
FileParser infile;
// @CLASS ItemManager: Items|Description about the class and it usage, items/items.txt...
if (!infile.open(filename, FileParser::MOD_FILE, FileParser::ERROR_NORMAL))
return;
// used to clear vectors when overriding items
bool clear_req_stat = true;
bool clear_bonus = true;
bool clear_loot_anim = true;
bool clear_replace_power = true;
int id = 0;
bool id_line = false;
while (infile.next()) {
if (infile.key == "id") {
// @ATTR id|item_id|An uniq id of the item used as reference from other classes.
id_line = true;
id = Parse::toInt(infile.val);
addUnknownItem(id);
items[id].max_quantity = 1;
clear_req_stat = true;
clear_bonus = true;
clear_loot_anim = true;
clear_replace_power = true;
}
else id_line = false;
if (id < 1) {
if (id_line) infile.error("ItemManager: Item index out of bounds 1-%d, skipping item.", INT_MAX);
continue;
}
if (id_line) continue;
assert(items.size() > std::size_t(id));
if (infile.key == "name") {
// @ATTR name|string|Item name displayed on long and short tooltips.
items[id].name = msg->get(infile.val);
items[id].has_name = true;
}
else if (infile.key == "flavor")
// @ATTR flavor|string|A description of the item.
items[id].flavor = msg->get(infile.val);
else if (infile.key == "level")
// @ATTR level|int|The item's level. Has no gameplay impact. (Deprecated?)
items[id].level = Parse::toInt(infile.val);
else if (infile.key == "icon") {
// @ATTR icon|icon_id|An id for the icon to display for this item.
items[id].icon = Parse::toInt(infile.val);
}
else if (infile.key == "book") {
// @ATTR book|filename|A book file to open when this item is activated.
items[id].book = infile.val;
}
else if (infile.key == "book_is_readable") {
// @ATTR book_is_readable|bool|If true, "read" is displayed in the tooltip instead of "use". Defaults to true.
items[id].book_is_readable = Parse::toBool(infile.val);
}
else if (infile.key == "quality") {
// @ATTR quality|predefined_string|Item quality matching an id in items/qualities.txt
items[id].quality = infile.val;
}
else if (infile.key == "item_type") {
// @ATTR item_type|predefined_string|Equipment slot matching an id in items/types.txt
items[id].type = infile.val;
}
else if (infile.key == "equip_flags") {
// @ATTR equip_flags|list(predefined_string)|A comma separated list of flags to set when this item is equipped. See engine/equip_flags.txt.
items[id].equip_flags.clear();
std::string flag = Parse::popFirstString(infile.val);
while (flag != "") {
items[id].equip_flags.push_back(flag);
flag = Parse::popFirstString(infile.val);
}
}
else if (infile.key == "dmg") {
// @ATTR dmg|predefined_string, int, int : Damage type, Min, Max|Defines the item's base damage type and range. Max may be ommitted and will default to Min.
std::string dmg_type_str = Parse::popFirstString(infile.val);
size_t dmg_type = eset->damage_types.list.size();
for (size_t i = 0; i < eset->damage_types.list.size(); ++i) {
if (dmg_type_str == eset->damage_types.list[i].id) {
dmg_type = i;
break;
}
}
if (dmg_type == eset->damage_types.list.size()) {
infile.error("ItemManager: '%s' is not a known damage type id.", dmg_type_str.c_str());
}
else {
//.........这里部分代码省略.........
示例5: load
/**
* load a statblock, typically for an enemy definition
*/
void StatBlock::load(const string& filename) {
FileParser infile;
int num = 0;
if (infile.open(mods->locate(filename))) {
while (infile.next()) {
if (isInt(infile.val)) num = atoi(infile.val.c_str());
if (infile.key == "name") name = msg->get(infile.val);
else if (infile.key == "humanoid") {
if (infile.val == "true") humanoid = true;
}
else if (infile.key == "sfx_prefix") sfx_prefix = infile.val;
else if (infile.key == "gfx_prefix") gfx_prefix = infile.val;
else if (infile.key == "level") level = num;
// enemy death rewards and events
else if (infile.key == "xp") xp = num;
else if (infile.key == "loot_chance") loot_chance = num;
else if (infile.key == "loot_type") {
string str;
while ((str = infile.nextValue()) != "") {
if (!isInt(str)) {
loot_types.push_back(str);
loot_prob.push_back(1);
loot_prob_sum++;
}
else {
num = atoi(str.c_str());
loot_prob[loot_types.size()-1] = num;
loot_prob_sum += num - 1; // one was already added, so add one less
}
}
}
else if (infile.key == "defeat_status") defeat_status = infile.val;
else if (infile.key == "first_defeat_loot") first_defeat_loot = num;
else if (infile.key == "quest_loot") {
quest_loot_requires = infile.nextValue();
quest_loot_not = infile.nextValue();
quest_loot_id = atoi(infile.nextValue().c_str());
}
// combat stats
else if (infile.key == "hp") {
hp = num;
maxhp = num;
}
else if (infile.key == "mp") {
mp = num;
maxmp = num;
}
else if (infile.key == "cooldown") cooldown = num;
else if (infile.key == "accuracy") accuracy = num;
else if (infile.key == "avoidance") avoidance = num;
else if (infile.key == "dmg_melee_min") dmg_melee_min = num;
else if (infile.key == "dmg_melee_max") dmg_melee_max = num;
else if (infile.key == "dmg_ment_min") dmg_ment_min = num;
else if (infile.key == "dmg_ment_max") dmg_ment_max = num;
else if (infile.key == "dmg_ranged_min") dmg_ranged_min = num;
else if (infile.key == "dmg_ranged_max") dmg_ranged_max = num;
else if (infile.key == "absorb_min") absorb_min = num;
else if (infile.key == "absorb_max") absorb_max = num;
// behavior stats
else if (infile.key == "flying") {
if (num == 1) flying = true;
}
else if (infile.key == "intangible") {
if (num == 1) intangible = true;
}
else if (infile.key == "facing") {
if (num == 0) facing = false;
}
else if (infile.key == "waypoint_pause") waypoint_pause = num;
else if (infile.key == "speed") speed = num;
else if (infile.key == "dspeed") dspeed = num;
else if (infile.key == "turn_delay") turn_delay = num;
else if (infile.key == "chance_pursue") chance_pursue = num;
else if (infile.key == "chance_flee") chance_flee = num;
else if (infile.key == "chance_melee_phys") power_chance[MELEE_PHYS] = num;
else if (infile.key == "chance_melee_ment") power_chance[MELEE_MENT] = num;
else if (infile.key == "chance_ranged_phys") power_chance[RANGED_PHYS] = num;
else if (infile.key == "chance_ranged_ment") power_chance[RANGED_MENT] = num;
else if (infile.key == "power_melee_phys") power_index[MELEE_PHYS] = num;
else if (infile.key == "power_melee_ment") power_index[MELEE_MENT] = num;
else if (infile.key == "power_ranged_phys") power_index[RANGED_PHYS] = num;
else if (infile.key == "power_ranged_ment") power_index[RANGED_MENT] = num;
else if (infile.key == "power_beacon") power_index[BEACON] = num;
else if (infile.key == "cooldown_melee_phys") power_cooldown[MELEE_PHYS] = num;
else if (infile.key == "cooldown_melee_ment") power_cooldown[MELEE_MENT] = num;
else if (infile.key == "cooldown_ranged_phys") power_cooldown[RANGED_PHYS] = num;
else if (infile.key == "cooldown_ranged_ment") power_cooldown[RANGED_MENT] = num;
else if (infile.key == "power_on_hit") power_index[ON_HIT] = num;
else if (infile.key == "power_on_death") power_index[ON_DEATH] = num;
//.........这里部分代码省略.........
示例6: if
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)
, vendor_visible(false)
, advanceButton(new WidgetButton("images/menus/buttons/right.png"))
, closeButton(new WidgetButton("images/menus/buttons/button_x.png")) {
background = loadGraphicSurface("images/menus/dialog_box.png");
// Load config settings
FileParser infile;
if(infile.open("menus/talker.txt")) {
while(infile.next()) {
infile.val = infile.val + ',';
if(infile.key == "close") {
close_pos.x = eatFirstInt(infile.val,',');
close_pos.y = eatFirstInt(infile.val,',');
}
else if(infile.key == "advance") {
advance_pos.x = eatFirstInt(infile.val,',');
advance_pos.y = eatFirstInt(infile.val,',');
}
else if (infile.key == "dialogbox") {
dialog_pos.x = eatFirstInt(infile.val,',');
dialog_pos.y = eatFirstInt(infile.val,',');
dialog_pos.w = eatFirstInt(infile.val,',');
dialog_pos.h = eatFirstInt(infile.val,',');
}
else if (infile.key == "dialogtext") {
text_pos.x = eatFirstInt(infile.val,',');
text_pos.y = eatFirstInt(infile.val,',');
text_pos.w = eatFirstInt(infile.val,',');
text_pos.h = eatFirstInt(infile.val,',');
}
else if (infile.key == "text_offset") {
text_offset.x = eatFirstInt(infile.val,',');
text_offset.y = eatFirstInt(infile.val,',');
}
else if (infile.key == "portrait_he") {
portrait_he.x = eatFirstInt(infile.val,',');
portrait_he.y = eatFirstInt(infile.val,',');
portrait_he.w = eatFirstInt(infile.val,',');
portrait_he.h = eatFirstInt(infile.val,',');
}
else if (infile.key == "portrait_you") {
portrait_you.x = eatFirstInt(infile.val,',');
portrait_you.y = eatFirstInt(infile.val,',');
portrait_you.w = eatFirstInt(infile.val,',');
portrait_you.h = eatFirstInt(infile.val,',');
}
else if (infile.key == "font_who") {
font_who = eatFirstString(infile.val,',');
}
else if (infile.key == "font_dialog") {
font_dialog = eatFirstString(infile.val,',');
}
}
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);
}
示例7: loadMiscSettings
void loadMiscSettings() {
// reset to defaults
ELEMENTS.clear();
EQUIP_FLAGS.clear();
HERO_CLASSES.clear();
FRAME_W = 0;
FRAME_H = 0;
ICON_SIZE = 0;
AUTOPICKUP_CURRENCY = false;
MAX_ABSORB = 90;
MAX_RESIST = 90;
MAX_BLOCK = 100;
MAX_AVOIDANCE = 99;
MIN_ABSORB = 0;
MIN_RESIST = 0;
MIN_BLOCK = 0;
MIN_AVOIDANCE = 0;
CURRENCY = "Gold";
VENDOR_RATIO = 0.25;
DEATH_PENALTY = true;
DEATH_PENALTY_PERMADEATH = false;
DEATH_PENALTY_CURRENCY = 50;
DEATH_PENALTY_XP = 0;
DEATH_PENALTY_XP_CURRENT = 0;
DEATH_PENALTY_ITEM = false;
MENUS_PAUSE = false;
SAVE_HPMP = false;
ENABLE_PLAYGAME = false;
CORPSE_TIMEOUT = 60*MAX_FRAMES_PER_SEC;
SELL_WITHOUT_VENDOR = true;
AIM_ASSIST = 0;
WINDOW_TITLE = "Flare";
SOUND_FALLOFF = 15;
PARTY_EXP_PERCENTAGE = 100;
ENABLE_ALLY_COLLISION_AI = true;
ENABLE_ALLY_COLLISION = true;
CURRENCY_ID = 1;
INTERACT_RANGE = 3;
FileParser infile;
// @CLASS Settings: Misc|Description of engine/misc.txt
if (infile.open("engine/misc.txt")) {
while (infile.next()) {
// @ATTR save_hpmp|boolean|When saving the game, keep the hero's current HP and MP.
if (infile.key == "save_hpmp")
SAVE_HPMP = toBool(infile.val);
// @ATTR corpse_timeout|duration|Duration that a corpse can exist on the map.
else if (infile.key == "corpse_timeout")
CORPSE_TIMEOUT = parse_duration(infile.val);
// @ATTR sell_without_vendor|boolean|Allows selling items when not at a vendor via CTRL-Click.
else if (infile.key == "sell_without_vendor")
SELL_WITHOUT_VENDOR = toBool(infile.val);
// @ATTR aim_assist|integer|The pixel offset for powers that use aim_assist.
else if (infile.key == "aim_assist")
AIM_ASSIST = toInt(infile.val);
// @ATTR window_title|string|Sets the text in the window's titlebar.
else if (infile.key == "window_title")
WINDOW_TITLE = infile.val;
// @ATTR save_prefix|string|A string that's prepended to save filenames to prevent conflicts between mods.
else if (infile.key == "save_prefix")
SAVE_PREFIX = infile.val;
// @ATTR sound_falloff|integer|The maximum radius in tiles that any single sound is audible.
else if (infile.key == "sound_falloff")
SOUND_FALLOFF = toInt(infile.val);
// @ATTR party_exp_percentage|integer|The percentage of XP given to allies.
else if (infile.key == "party_exp_percentage")
PARTY_EXP_PERCENTAGE = toInt(infile.val);
// @ATTR enable_ally_collision|boolean|Allows allies to block the player's path.
else if (infile.key == "enable_ally_collision")
ENABLE_ALLY_COLLISION = toBool(infile.val);
// @ATTR enable_ally_collision_ai|boolean|Allows allies to block the path of other AI creatures.
else if (infile.key == "enable_ally_collision_ai")
ENABLE_ALLY_COLLISION_AI = toBool(infile.val);
else if (infile.key == "currency_id") {
// @ATTR currency_id|integer|An item id that will be used as currency.
CURRENCY_ID = toInt(infile.val);
if (CURRENCY_ID < 1) {
CURRENCY_ID = 1;
fprintf(stderr, "Currency ID below the minimum allowed value. Resetting it to %d\n", CURRENCY_ID);
}
}
// @ATTR interact_range|float|Distance where the player can interact with objects and NPCs.
else if (infile.key == "interact_range")
INTERACT_RANGE = toFloat(infile.val);
// @ATTR menus_pause|boolean|Opening any menu will pause the game.
else if (infile.key == "menus_pause")
MENUS_PAUSE = toBool(infile.val);
}
infile.close();
}
// @CLASS Settings: Resolution|Description of engine/resolutions.txt
if (infile.open("engine/resolutions.txt")) {
while (infile.next()) {
// @ATTR menu_frame_width|integer|Width of frame for New Game, Configuration, etc. menus.
if (infile.key == "menu_frame_width")
FRAME_W = toInt(infile.val);
// @ATTR menu_frame_width|integer|Height of frame for New Game, Configuration, etc. menus.
else if (infile.key == "menu_frame_height")
//.........这里部分代码省略.........
示例8: loadPowers
/**
* Powers are defined in [mod]/powers/powers.txt
*
* @param filename The full path and filename to this powers.txt file
*/
void PowerManager::loadPowers(const std::string& filename) {
FileParser infile;
if (!infile.open(filename)) {
fprintf(stderr, "Unable to open %s!\n", filename.c_str());
return;
}
int input_id = 0;
bool skippingEntry = false;
while (infile.next()) {
// id needs to be the first component of each power. That is how we write
// data to the correct power.
if (infile.key == "id") {
input_id = toInt(infile.val);
skippingEntry = input_id < 1;
if (skippingEntry)
fprintf(stderr, "Power index out of bounds 1-%d, skipping\n", INT_MAX);
if (static_cast<int>(powers.size()) < input_id + 1)
powers.resize(input_id + 1);
continue;
}
if (skippingEntry)
continue;
if (infile.key == "type") {
if (infile.val == "fixed") powers[input_id].type = POWTYPE_FIXED;
else if (infile.val == "missile") powers[input_id].type = POWTYPE_MISSILE;
else if (infile.val == "repeater") powers[input_id].type = POWTYPE_REPEATER;
else if (infile.val == "spawn") powers[input_id].type = POWTYPE_SPAWN;
else if (infile.val == "transform") powers[input_id].type = POWTYPE_TRANSFORM;
else if (infile.val == "effect") powers[input_id].type = POWTYPE_EFFECT;
else fprintf(stderr, "unknown type %s\n", infile.val.c_str());
}
else if (infile.key == "name")
powers[input_id].name = msg->get(infile.val);
else if (infile.key == "description")
powers[input_id].description = msg->get(infile.val);
else if (infile.key == "tag")
powers[input_id].tag = infile.val;
else if (infile.key == "icon")
powers[input_id].icon = toInt(infile.val);
else if (infile.key == "new_state") {
if (infile.val == "swing") powers[input_id].new_state = POWSTATE_SWING;
else if (infile.val == "shoot") powers[input_id].new_state = POWSTATE_SHOOT;
else if (infile.val == "cast") powers[input_id].new_state = POWSTATE_CAST;
else if (infile.val == "block") powers[input_id].new_state = POWSTATE_BLOCK;
else if (infile.val == "instant") powers[input_id].new_state = POWSTATE_INSTANT;
else fprintf(stderr, "unknown new_state %s\n", infile.val.c_str());
}
else if (infile.key == "face")
powers[input_id].face = toBool(infile.val);
else if (infile.key == "source_type") {
if (infile.val == "hero") powers[input_id].source_type = SOURCE_TYPE_HERO;
else if (infile.val == "neutral") powers[input_id].source_type = SOURCE_TYPE_NEUTRAL;
else if (infile.val == "enemy") powers[input_id].source_type = SOURCE_TYPE_ENEMY;
else fprintf(stderr, "unknown source_type %s\n", infile.val.c_str());
}
else if (infile.key == "beacon")
powers[input_id].beacon = toBool(infile.val);
else if (infile.key == "count")
powers[input_id].count = toInt(infile.val);
else if (infile.key == "passive")
powers[input_id].passive = toBool(infile.val);
else if (infile.key == "passive_trigger") {
if (infile.val == "on_block") powers[input_id].passive_trigger = TRIGGER_BLOCK;
else if (infile.val == "on_hit") powers[input_id].passive_trigger = TRIGGER_HIT;
else if (infile.val == "on_halfdeath") powers[input_id].passive_trigger = TRIGGER_HALFDEATH;
else if (infile.val == "on_joincombat") powers[input_id].passive_trigger = TRIGGER_JOINCOMBAT;
else if (infile.val == "on_death") powers[input_id].passive_trigger = TRIGGER_DEATH;
else fprintf(stderr, "unknown passive trigger %s\n", infile.val.c_str());
}
// power requirements
else if (infile.key == "requires_physical_weapon")
powers[input_id].requires_physical_weapon = toBool(infile.val);
else if (infile.key == "requires_mental_weapon")
powers[input_id].requires_mental_weapon = toBool(infile.val);
else if (infile.key == "requires_offense_weapon")
powers[input_id].requires_offense_weapon = toBool(infile.val);
else if (infile.key == "requires_mp")
powers[input_id].requires_mp = toInt(infile.val);
else if (infile.key == "requires_hp")
powers[input_id].requires_hp = toInt(infile.val);
else if (infile.key == "sacrifice")
powers[input_id].sacrifice = toBool(infile.val);
else if (infile.key == "requires_los")
powers[input_id].requires_los = toBool(infile.val);
else if (infile.key == "requires_empty_target")
powers[input_id].requires_empty_target = toBool(infile.val);
else if (infile.key == "requires_item")
powers[input_id].requires_item = toInt(infile.val);
else if (infile.key == "requires_equipped_item")
powers[input_id].requires_equipped_item = toInt(infile.val);
else if (infile.key == "requires_targeting")
powers[input_id].requires_targeting = toBool(infile.val);
//.........这里部分代码省略.........
示例9: loadPowerTree
/**
* Loads a given power tree and sets up the menu accordingly
*
* @param filename Path to the file that will be loaded
*/
void MenuPowers::loadPowerTree(const std::string &filename) {
// only load the power tree once per instance
if (tree_loaded) return;
// First, parse the power tree file
FileParser infile;
// @CLASS MenuPowers: Power tree layout|Description of powers/trees/
if (infile.open(filename)) {
while (infile.next()) {
if (infile.new_section) {
// for sections that are stored in collections, add a new object here
if (infile.section == "power") {
slots.push_back(NULL);
upgradeButtons.push_back(NULL);
power_cell.push_back(Power_Menu_Cell());
}
else if (infile.section == "upgrade")
power_cell_upgrade.push_back(Power_Menu_Cell());
else if (infile.section == "tab")
tabs.push_back(Power_Menu_Tab());
}
if (infile.section == "") {
// @ATTR background|filename|Filename of the default background image
if (infile.key == "background") default_background = infile.val;
}
else if (infile.section == "tab")
loadTab(infile);
else if (infile.section == "power")
loadPower(infile);
else if (infile.section == "upgrade")
loadUpgrade(infile);
}
infile.close();
}
// save a copy of the base level powers, as they get overwritten during upgrades
power_cell_base = power_cell;
// store the appropriate level for all upgrades
for (size_t i=0; i<power_cell_upgrade.size(); ++i) {
for (size_t j=0; j<power_cell_base.size(); j++) {
std::vector<int>::iterator it = std::find(power_cell_base[j].upgrades.begin(), power_cell_base[j].upgrades.end(), power_cell_upgrade[i].id);
if (it != power_cell_base[j].upgrades.end()) {
power_cell_upgrade[i].upgrade_level = static_cast<int>(std::distance(power_cell_base[j].upgrades.begin(), it) + 2);
break;
}
}
}
// combine base and upgrade powers into a single list
for (size_t i=0; i<power_cell_base.size(); ++i) {
power_cell_all.push_back(power_cell_base[i]);
}
for (size_t i=0; i<power_cell_upgrade.size(); ++i) {
power_cell_all.push_back(power_cell_upgrade[i]);
}
// save cell indexes for required powers
for (size_t i=0; i<power_cell_all.size(); ++i) {
for (size_t j=0; j<power_cell_all[i].requires_power.size(); ++j) {
int cell_index = getCellByPowerIndex(power_cell_all[i].requires_power[j], power_cell_all);
power_cell_all[i].requires_power_cell.push_back(cell_index);
}
}
// load any specified graphics into the tree_surf vector
Image *graphics;
if (tabs.empty() && default_background != "") {
graphics = render_device->loadImage(default_background);
if (graphics) {
tree_surf.push_back(graphics->createSprite());
graphics->unref();
}
}
else {
for (size_t i=0; i<tabs.size(); ++i) {
if (tabs[i].background == "")
tabs[i].background = default_background;
if (tabs[i].background == "") {
tree_surf.push_back(NULL);
continue;
}
graphics = render_device->loadImage(tabs[i].background);
if (graphics) {
tree_surf.push_back(graphics->createSprite());
graphics->unref();
}
else {
tree_surf.push_back(NULL);
}
}
//.........这里部分代码省略.........
示例10: load
bool GameStateCutscene::load(std::string filename) {
FileParser infile;
// @CLASS Cutscene|Description of cutscenes in cutscenes/
if (!infile.open("cutscenes/" + filename, true, false))
return false;
// parse the cutscene file
while (infile.next()) {
if (infile.new_section) {
if (infile.section == "scene")
scenes.push(Scene());
}
if (infile.section.empty()) {
// allow having an empty section (globals such as scale_gfx might be set here
}
else if (infile.section == "scene") {
SceneComponent sc = SceneComponent();
if (infile.key == "caption") {
// @ATTR scene.caption|string|A caption that will be shown.
sc.type = infile.key;
sc.s = msg->get(infile.val);
}
else if (infile.key == "image") {
// @ATTR scene.image|string|An image that will be shown.
sc.type = infile.key;
sc.i.setGraphics(loadImage(infile.val));
sc.i.keep_graphics = true;
if (sc.i.graphicsIsNull())
sc.type = "";
}
else if (infile.key == "pause") {
// @ATTR scene.pause|integer|Pause before next component
sc.type = infile.key;
sc.x = toInt(infile.val);
}
else if (infile.key == "soundfx") {
// @ATTR scene.soundfx|string|A sound that will be played
sc.type = infile.key;
sc.s = infile.val;
}
if (sc.type != "")
scenes.back().components.push(sc);
}
else {
fprintf(stderr, "unknown section %s in file %s\n", infile.section.c_str(), infile.getFileName().c_str());
}
if (infile.key == "scale_gfx") {
// @ATTR scale_gfx|bool|The graphics will be scaled to fit screen width
scale_graphics = toBool(infile.val);
}
else if (infile.key == "caption_margins") {
// @ATTR caption_margins|[x,y]|Percentage-based margins for the caption text based on screen size
caption_margins.x = toFloat(infile.nextValue())/100.0f;
caption_margins.y = toFloat(infile.val)/100.0f;
}
}
if (scenes.empty()) {
fprintf(stderr, "No scenes defined in cutscene file %s\n", filename.c_str());
return false;
}
return true;
}
示例11: load
/**
* NPCs are stored in simple config files
*
* @param npc_id Config file loaded at npcs/[npc_id].txt
*/
void NPC::load(const string& npc_id, int hero_level) {
FileParser infile;
ItemStack stack;
string filename_portrait = "";
if (infile.open(mods->locate("npcs/" + npc_id + ".txt"))) {
while (infile.next()) {
if (infile.section == "dialog") {
if (infile.new_section) {
dialog.push_back(vector<Event_Component>());
}
Event_Component e;
e.type = infile.key;
if (infile.key == "requires_status")
e.s = infile.val;
else if (infile.key == "requires_not")
e.s = infile.val;
else if (infile.key == "requires_level")
e.x = toInt(infile.val);
else if (infile.key == "requires_not_level")
e.x = toInt(infile.val);
else if (infile.key == "requires_item")
e.x = toInt(infile.val);
else if (infile.key == "him" || infile.key == "her")
e.s = msg->get(infile.val);
else if (infile.key == "you")
e.s = msg->get(infile.val);
else if (infile.key == "reward_item") {
// id,count
e.x = toInt(infile.nextValue());
e.y = toInt(infile.val);
}
else if (infile.key == "reward_xp")
e.x = toInt(infile.val);
else if (infile.key == "restore")
e.s = infile.val;
else if (infile.key == "reward_currency")
e.x = toInt(infile.val);
else if (infile.key == "remove_item")
e.x = toInt(infile.val);
else if (infile.key == "set_status")
e.s = infile.val;
else if (infile.key == "unset_status")
e.s = infile.val;
else if (infile.key == "voice") {
e.x = loadSound(infile.val, NPC_VOX_QUEST);
}
else if (infile.key == "topic") {
e.s = msg->get(infile.val);
}
else if (infile.key == "group") {
e.s = infile.val;
}
dialog.back().push_back(e);
}
else {
filename = npc_id;
if (infile.key == "name") {
name = msg->get(infile.val);
}
else if (infile.key == "level") {
if (infile.val == "hero")
level = hero_level;
else
level = toInt(infile.val);
}
else if (infile.key == "gfx") {
gfx = infile.val;
}
// handle talkers
else if (infile.key == "talker") {
if (infile.val == "true") talker = true;
}
else if (infile.key == "portrait") {
filename_portrait = infile.val;
}
// handle vendors
else if (infile.key == "vendor") {
if (infile.val == "true") vendor = true;
}
else if (infile.key == "constant_stock") {
stack.quantity = 1;
while (infile.val != "") {
stack.item = toInt(infile.nextValue());
stock.add(stack);
}
}
else if (infile.key == "status_stock") {
if (map->camp->checkStatus(infile.nextValue())) {
stack.quantity = 1;
//.........这里部分代码省略.........
示例12: loadHeroStats
void StatBlock::loadHeroStats() {
// Redefine numbers from config file if present
FileParser infile;
if (!infile.open(mods->locate("engine/stats.txt"))) {
fprintf(stderr, "Unable to open engine/stats.txt!\n");
return;
}
while (infile.next()) {
int value = toInt(infile.val);
if (infile.key == "max_points_per_stat") {
max_points_per_stat = value;
} else if (infile.key == "hp_base") {
hp_base = value;
} else if (infile.key == "hp_per_level") {
hp_per_level = value;
} else if (infile.key == "hp_per_physical") {
hp_per_physical = value;
} else if (infile.key == "hp_regen_base") {
hp_regen_base = value;
} else if (infile.key == "hp_regen_per_level") {
hp_regen_per_level = value;
} else if (infile.key == "hp_regen_per_physical") {
hp_regen_per_physical = value;
} else if (infile.key == "mp_base") {
mp_base = value;
} else if (infile.key == "mp_per_level") {
mp_per_level = value;
} else if (infile.key == "mp_per_mental") {
mp_per_mental = value;
} else if (infile.key == "mp_regen_base") {
mp_regen_base = value;
} else if (infile.key == "mp_regen_per_level") {
mp_regen_per_level = value;
} else if (infile.key == "mp_regen_per_mental") {
mp_regen_per_mental = value;
} else if (infile.key == "accuracy_base") {
accuracy_base = value;
} else if (infile.key == "accuracy_per_level") {
accuracy_per_level = value;
} else if (infile.key == "accuracy_per_offense") {
accuracy_per_offense = value;
} else if (infile.key == "avoidance_base") {
avoidance_base = value;
} else if (infile.key == "avoidance_per_level") {
avoidance_per_level = value;
} else if (infile.key == "avoidance_per_defense") {
avoidance_per_defense = value;
} else if (infile.key == "crit_base") {
crit_base = value;
} else if (infile.key == "crit_per_level") {
crit_per_level = value;
} else if (infile.key == "dmg_melee_min") {
dmg_melee_min = dmg_melee_min_default = value;
} else if (infile.key == "dmg_melee_max") {
dmg_melee_max = dmg_melee_max_default = value;
} else if (infile.key == "dmg_ranged_min") {
dmg_ranged_min = dmg_ranged_min_default = value;
} else if (infile.key == "dmg_ranged_max") {
dmg_ranged_max = dmg_ranged_max_default = value;
} else if (infile.key == "dmg_ment_min") {
dmg_ment_min = dmg_ment_min_default = value;
} else if (infile.key == "dmg_ment_max") {
dmg_ment_max = dmg_ment_max_default = value;
} else if (infile.key == "absorb_min") {
absorb_min = absorb_min_default = value;
} else if (infile.key == "absorb_max") {
absorb_max = absorb_max_default = value;
} else if (infile.key == "speed") {
speed = speed_default = value;
} else if (infile.key == "dspeed") {
dspeed = dspeed_default = value;
} else if (infile.key == "bonus_per_physical") {
bonus_per_physical = value;
} else if (infile.key == "bonus_per_mental") {
bonus_per_mental = value;
} else if (infile.key == "bonus_per_offense") {
bonus_per_offense = value;
} else if (infile.key == "bonus_per_defense") {
bonus_per_defense = value;
} else if (infile.key == "sfx_step") {
sfx_step = infile.val;
} else if (infile.key == "stat_points_per_level") {
stat_points_per_level = value;
} else if (infile.key == "power_points_per_level") {
power_points_per_level = value;
} else if (infile.key == "cooldown_hit") {
cooldown_hit = value;
}
}
infile.close();
if (max_points_per_stat == 0) max_points_per_stat = max_spendable_stat_points / 4 + 1;
statsLoaded = true;
// Load the XP table as well
if (!infile.open(mods->locate("engine/xp_table.txt"))) {
fprintf(stderr, "Unable to open engine/xp_table.txt!\n");
return;
}
//.........这里部分代码省略.........
示例13: load
/**
* load a statblock, typically for an enemy definition
*/
void StatBlock::load(const string& filename) {
FileParser infile;
if (!infile.open(mods->locate(filename))) {
fprintf(stderr, "Unable to open %s!\n", filename.c_str());
return;
}
int num = 0;
string loot_token;
while (infile.next()) {
if (isInt(infile.val)) num = toInt(infile.val);
bool valid = false;
for (unsigned int i=0; i<ELEMENTS.size(); i++) {
if (infile.key == "vulnerable_" + ELEMENTS[i].name) {
vulnerable[i] = vulnerable_base[i] = num;
valid = true;
}
}
if (infile.key == "name") name = msg->get(infile.val);
else if (infile.key == "humanoid") {
if (infile.val == "true") humanoid = true;
}
else if (infile.key == "sfx_prefix") sfx_prefix = infile.val;
else if (infile.key == "level") level = num;
// enemy death rewards and events
else if (infile.key == "xp") xp = num;
else if (infile.key == "loot") {
// loot entries format:
// loot=[id],[percent_chance]
// optionally allow range:
// loot=[id],[percent_chance],[count_min],[count_max]
EnemyLoot el;
std::string loot_id = infile.nextValue();
// id 0 means currency. The keyword "currency" can also be used.
if (loot_id == "currency")
el.id = 0;
else
el.id = toInt(loot_id);
el.chance = toInt(infile.nextValue());
// check for optional range.
loot_token = infile.nextValue();
if (loot_token != "") {
el.count_min = toInt(loot_token);
el.count_max = el.count_min;
}
loot_token = infile.nextValue();
if (loot_token != "") {
el.count_max = toInt(loot_token);
}
loot.push_back(el);
}
else if (infile.key == "defeat_status") defeat_status = infile.val;
else if (infile.key == "first_defeat_loot") first_defeat_loot = num;
else if (infile.key == "quest_loot") {
quest_loot_requires = infile.nextValue();
quest_loot_not = infile.nextValue();
quest_loot_id = toInt(infile.nextValue());
}
// combat stats
else if (infile.key == "hp") hp = hp_base = maxhp = num;
else if (infile.key == "mp") mp = mp_base = maxmp = num;
else if (infile.key == "cooldown") cooldown = parse_duration(infile.val);
else if (infile.key == "accuracy") accuracy = accuracy_base = num;
else if (infile.key == "avoidance") avoidance = avoidance_base = num;
else if (infile.key == "dmg_melee_min") dmg_melee_min = num;
else if (infile.key == "dmg_melee_max") dmg_melee_max = num;
else if (infile.key == "dmg_ment_min") dmg_ment_min = num;
else if (infile.key == "dmg_ment_max") dmg_ment_max = num;
else if (infile.key == "dmg_ranged_min") dmg_ranged_min = num;
else if (infile.key == "dmg_ranged_max") dmg_ranged_max = num;
else if (infile.key == "absorb_min") absorb_min = num;
else if (infile.key == "absorb_max") absorb_max = num;
else if (infile.key == "poise") poise = poise_base = num;
// behavior stats
else if (infile.key == "flying") {
if (num == 1) flying = true;
}
else if (infile.key == "intangible") {
if (num == 1) intangible = true;
}
else if (infile.key == "facing") {
if (num == 0) facing = false;
}
else if (infile.key == "waypoint_pause") waypoint_pause = num;
//.........这里部分代码省略.........
示例14: load
void AnimationSet::load() {
assert(!loaded);
loaded = true;
FileParser parser;
// @CLASS AnimationSet|Description of animations in animations/
if (!parser.open(name, true, "Error loading animation definition: " + name))
return;
std::string _name = "";
unsigned short position = 0;
unsigned short frames = 0;
unsigned short duration = 0;
Point render_size;
Point render_offset;
std::string type = "";
std::string starting_animation = "";
bool first_section=true;
bool compressed_loading=false; // is reset every section to false, set by frame keyword
Animation *newanim = NULL;
std::vector<short> active_frames;
unsigned short parent_anim_frames = 0;
// Parse the file and on each new section create an animation object from the data parsed previously
while (parser.next()) {
// create the animation if finished parsing a section
if (parser.new_section) {
if (!first_section && !compressed_loading) {
Animation *a = new Animation(_name, type, sprite);
a->setupUncompressed(render_size, render_offset, position, frames, duration);
if (!active_frames.empty())
a->setActiveFrames(active_frames);
active_frames.clear();
animations.push_back(a);
}
first_section = false;
compressed_loading = false;
if (parent) {
parent_anim_frames = static_cast<unsigned short>(parent->getAnimationFrames(parser.section));
}
}
if (parser.key == "image") {
// @ATTR image|filename|Filename of sprite-sheet image.
if (sprite != NULL) {
parser.error("AnimationSet: Multiple images specified. Dragons be here!");
Exit(128);
}
sprite = render_device->loadImage(parser.val);
}
else if (parser.key == "position") {
// @ATTR position|int|Number of frames to the right to use as the first frame. Unpacked animations only.
position = static_cast<unsigned short>(toInt(parser.val));
}
else if (parser.key == "frames") {
// @ATTR frames|int|The total number of frames
frames = static_cast<unsigned short>(toInt(parser.val));
if (parent && frames != parent_anim_frames) {
parser.error("AnimationSet: Frame count %d != %d for matching animation in %s", frames, parent_anim_frames, parent->getName().c_str());
frames = parent_anim_frames;
}
}
else if (parser.key == "duration") {
// @ATTR duration|duration|The duration of the entire animation in 'ms' or 's'.
duration = static_cast<unsigned short>(parse_duration(parser.val));
}
else if (parser.key == "type")
// @ATTR type|["play_once", "back_forth", "looped"]|How to loop (or not loop) this animation.
type = parser.val;
else if (parser.key == "render_size") {
// @ATTR render_size|int, int : Width, Height|Width and height of animation.
render_size.x = toInt(parser.nextValue());
render_size.y = toInt(parser.nextValue());
}
else if (parser.key == "render_offset") {
// @ATTR render_offset|int, int : X offset, Y offset|Render x/y offset.
render_offset.x = toInt(parser.nextValue());
render_offset.y = toInt(parser.nextValue());
}
else if (parser.key == "active_frame") {
// @ATTR active_frame|[list(int), "all"]|A list of frames marked as "active". Also, "all" can be used to mark all frames as active.
active_frames.clear();
std::string nv = parser.nextValue();
if (nv == "all") {
active_frames.push_back(-1);
}
else {
while (nv != "") {
active_frames.push_back(static_cast<short>(toInt(nv)));
nv = parser.nextValue();
}
std::sort(active_frames.begin(), active_frames.end());
active_frames.erase(std::unique(active_frames.begin(), active_frames.end()), active_frames.end());
}
}
else if (parser.key == "frame") {
// @ATTR frame|int, int, int, int, int, int, int, int : Index, Direction, X, Y, Width, Height, X offset, Y offset|A single frame of a compressed animation.
if (compressed_loading == false) { // first frame statement in section
//.........这里部分代码省略.........
示例15: load
/**
* load a statblock, typically for an enemy definition
*/
void StatBlock::load(const std::string& filename) {
// @CLASS StatBlock: Enemies|Description of enemies in enemies/
FileParser infile;
if (!infile.open(filename))
return;
bool clear_loot = true;
while (infile.next()) {
if (infile.new_section) {
// APPENDed file
clear_loot = true;
}
int num = toInt(infile.val);
float fnum = toFloat(infile.val);
bool valid = loadCoreStat(&infile) || loadSfxStat(&infile);
// @ATTR name|string|Name
if (infile.key == "name") name = msg->get(infile.val);
// @ATTR humanoid|boolean|This creature gives human traits when transformed into, such as the ability to talk with NPCs.
else if (infile.key == "humanoid") humanoid = toBool(infile.val);
// @ATTR level|integer|Level
else if (infile.key == "level") level = num;
// enemy death rewards and events
// @ATTR xp|integer|XP awarded upon death.
else if (infile.key == "xp") xp = num;
else if (infile.key == "loot") {
// @ATTR loot|[currency:item (integer)], chance (integer), min (integer), max (integer)|Possible loot that can be dropped on death.
// loot entries format:
// loot=[id],[percent_chance]
// optionally allow range:
// loot=[id],[percent_chance],[count_min],[count_max]
if (clear_loot) {
loot_table.clear();
clear_loot = false;
}
loot_table.push_back(Event_Component());
loot->parseLoot(infile, &loot_table.back(), &loot_table);
}
// @ATTR defeat_status|string|Campaign status to set upon death.
else if (infile.key == "defeat_status") defeat_status = infile.val;
// @ATTR convert_status|string|Campaign status to set upon being converted to a player ally.
else if (infile.key == "convert_status") convert_status = infile.val;
// @ATTR first_defeat_loot|integer|Drops this item upon first death.
else if (infile.key == "first_defeat_loot") first_defeat_loot = num;
// @ATTR quest_loot|[requires status (string), requires not status (string), item (integer)|Drops this item when campaign status is met.
else if (infile.key == "quest_loot") {
quest_loot_requires_status = infile.nextValue();
quest_loot_requires_not_status = infile.nextValue();
quest_loot_id = toInt(infile.nextValue());
}
// combat stats
// @ATTR cooldown|integer|Cooldown between attacks in 'ms' or 's'.
else if (infile.key == "cooldown") cooldown = parse_duration(infile.val);
// behavior stats
// @ATTR flying|boolean|Creature can move over gaps/water.
else if (infile.key == "flying") flying = toBool(infile.val);
// @ATTR intangible|boolean|Creature can move through walls.
else if (infile.key == "intangible") intangible = toBool(infile.val);
// @ATTR facing|boolean|Creature can turn to face their target.
else if (infile.key == "facing") facing = toBool(infile.val);
// @ATTR waypoint_pause|duration|Duration to wait at each waypoint in 'ms' or 's'.
else if (infile.key == "waypoint_pause") waypoint_pause = parse_duration(infile.val);
// @ATTR turn_delay|duration|Duration it takes for this creature to turn and face their target in 'ms' or 's'.
else if (infile.key == "turn_delay") turn_delay = parse_duration(infile.val);
// @ATTR chance_pursue|integer|Percentage change that the creature will chase their target.
else if (infile.key == "chance_pursue") chance_pursue = num;
// @ATTR chance_flee|integer|Percentage chance that the creature will run away from their target.
else if (infile.key == "chance_flee") chance_flee = num;
// @ATTR chance_melee_phys|integer|Percentage chance that the creature will use their physical melee power.
else if (infile.key == "chance_melee_phys") power_chance[MELEE_PHYS] = num;
// @ATTR chance_melee_ment|integer|Percentage chance that the creature will use their mental melee power.
else if (infile.key == "chance_melee_ment") power_chance[MELEE_MENT] = num;
// @ATTR chance_ranged_phys|integer|Percentage chance that the creature will use their physical ranged power.
else if (infile.key == "chance_ranged_phys") power_chance[RANGED_PHYS] = num;
// @ATTR chance_ranged_ment|integer|Percentage chance that the creature will use their mental ranged power.
else if (infile.key == "chance_ranged_ment") power_chance[RANGED_MENT] = num;
// @ATTR power_melee_phys|integer|Power index for the physical melee power.
else if (infile.key == "power_melee_phys") power_index[MELEE_PHYS] = num;
// @ATTR power_melee_ment|integer|Power index for the mental melee power.
else if (infile.key == "power_melee_ment") power_index[MELEE_MENT] = num;
// @ATTR power_ranged_phys|integer|Power index for the physical ranged power.
else if (infile.key == "power_ranged_phys") power_index[RANGED_PHYS] = num;
// @ATTR power_ranged_ment|integer|Power index for the mental ranged power.
else if (infile.key == "power_ranged_ment") power_index[RANGED_MENT] = num;
// @ATTR power_beacon|integer|Power index of a "beacon" power used to aggro nearby creatures.
else if (infile.key == "power_beacon") power_index[BEACON] = num;
//.........这里部分代码省略.........