Пример #1
0
/**
 * 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;
                else if (infile.val == "maille")
                    items[id].sfx = SFX_MAILLE;
                else if (infile.val == "object")
                    items[id].sfx = SFX_OBJECT;
                else if (infile.val == "heavy")
                    items[id].sfx = SFX_HEAVY;
                else if (infile.val == "wood")
                    items[id].sfx = SFX_WOOD;
                else if (infile.val == "potion")
                    items[id].sfx = SFX_POTION;
            }
            else if (infile.key == "gfx")
                items[id].gfx = infile.val;
            else if (infile.key == "loot")
                items[id].loot = infile.val;
            else if (infile.key == "power")
                items[id].power = atoi(infile.val.c_str());
            else if (infile.key == "power_mod")
                items[id].power_mod = atoi(infile.val.c_str());
            else if (infile.key == "power_desc")
                items[id].power_desc = msg->get(infile.val);
            else if (infile.key == "price")
                items[id].price = atoi(infile.val.c_str());
            else if (infile.key == "price_sell")
                items[id].price_sell = atoi(infile.val.c_str());
            else if (infile.key == "max_quantity")
                items[id].max_quantity = atoi(infile.val.c_str());
            else if (infile.key == "rand_loot")
                items[id].rand_loot = atoi(infile.val.c_str());
            else if (infile.key == "rand_vendor")
                items[id].rand_vendor = atoi(infile.val.c_str());
            else if (infile.key == "pickup_status")
                items[id].pickup_status = infile.val;
            else if (infile.key == "stepfx")
                items[id].stepfx = infile.val;

        }
        infile.close();
    }
}
Пример #2
0
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
0
/**
 * 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
0
/**
 * 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 {
				items[id].dmg_min[dmg_type] = Parse::popFirstInt(infile.val);
				if (infile.val.length() > 0)
					items[id].dmg_max[dmg_type] = Parse::popFirstInt(infile.val);
				else
					items[id].dmg_max[dmg_type] = items[id].dmg_min[dmg_type];
			}
		}
		else if (infile.key == "abs") {
			// @ATTR abs|int, int : Min, Max|Defines the item absorb value, if only min is specified the absorb value is fixed.
			items[id].abs_min = Parse::popFirstInt(infile.val);
			if (infile.val.length() > 0)
				items[id].abs_max = Parse::popFirstInt(infile.val);
			else
				items[id].abs_max = items[id].abs_min;
		}
		else if (infile.key == "requires_level") {
			// @ATTR requires_level|int|The hero's level must match or exceed this value in order to equip this item.
			items[id].requires_level = Parse::toInt(infile.val);
		}
		else if (infile.key == "requires_stat") {
			// @ATTR requires_stat|repeatable(predefined_string, int) : Primary stat name, Value|Make item require specific stat level ex. requires_stat=physical,6 will require hero to have level 6 in physical stats
			if (clear_req_stat) {
				items[id].req_stat.clear();
				items[id].req_val.clear();
				clear_req_stat = false;
			}
			std::string s = Parse::popFirstString(infile.val);
			size_t req_stat_index = eset->primary_stats.getIndexByID(s);
			if (req_stat_index != eset->primary_stats.list.size())
				items[id].req_stat.push_back(req_stat_index);
			else
				infile.error("ItemManager: '%s' is not a valid primary stat.", s.c_str());
			items[id].req_val.push_back(Parse::popFirstInt(infile.val));
		}
		else if (infile.key == "requires_class") {
			// @ATTR requires_class|predefined_string|The hero's base class (engine/classes.txt) must match for this item to be equipped.
			items[id].requires_class = infile.val;
		}
		else if (infile.key == "bonus") {
			// @ATTR bonus|repeatable(predefined_string, int) : Stat name, Value|Adds a bonus to the item by stat name, example: bonus=hp, 50
			if (clear_bonus) {
				items[id].bonus.clear();
				clear_bonus = false;
			}
			BonusData bdata;
			parseBonus(bdata, infile);
			items[id].bonus.push_back(bdata);
		}
		else if (infile.key == "bonus_power_level") {
			// @ATTR bonus_power_level|repeatable(power_id, int) : Base power, Bonus levels|Grants bonus levels to a given base power.
			BonusData bdata;
			bdata.power_id = Parse::popFirstInt(infile.val);
			bdata.value = Parse::popFirstInt(infile.val);
			items[id].bonus.push_back(bdata);
		}
		else if (infile.key == "soundfx") {
			// @ATTR soundfx|filename|Sound effect filename to play for the specific item.
			items[id].sfx = infile.val;
			items[id].sfx_id = snd->load(items[id].sfx, "ItemManager");
		}
		else if (infile.key == "gfx")
			// @ATTR gfx|filename|Filename of an animation set to display when the item is equipped.
			items[id].gfx = infile.val;
		else if (infile.key == "loot_animation") {
			// @ATTR loot_animation|repeatable(filename, int, int) : Loot image, Min quantity, Max quantity|Specifies the loot animation file for the item. The max quantity, or both quantity values, may be omitted.
			if (clear_loot_anim) {
				items[id].loot_animation.clear();
				clear_loot_anim = false;
			}
			LootAnimation la;
			la.name = Parse::popFirstString(infile.val);
			la.low = Parse::popFirstInt(infile.val);
			la.high = Parse::popFirstInt(infile.val);
			items[id].loot_animation.push_back(la);
		}
		else if (infile.key == "power") {
			// @ATTR power|power_id|Adds a specific power to the item which makes it usable as a power and can be placed in action bar.
			if (Parse::toInt(infile.val) > 0)
				items[id].power = Parse::toInt(infile.val);
			else
				infile.error("ItemManager: Power index out of bounds 1-%d, skipping power.", INT_MAX);
		}
		else if (infile.key == "replace_power") {
			// @ATTR replace_power|repeatable(int, int) : Old power, New power|Replaces the old power id with the new power id in the action bar when equipped.
			if (clear_replace_power) {
				items[id].replace_power.clear();
				clear_replace_power = false;
			}
			Point power_ids = Parse::toPoint(infile.val);
			items[id].replace_power.push_back(power_ids);
		}
		else if (infile.key == "power_desc")
			// @ATTR power_desc|string|A string describing the additional power.
			items[id].power_desc = msg->get(infile.val);
		else if (infile.key == "price")
			// @ATTR price|int|The amount of currency the item costs, if set to 0 the item cannot be sold.
			items[id].price = Parse::toInt(infile.val);
		else if (infile.key == "price_per_level")
			// @ATTR price_per_level|int|Additional price for each player level above 1
			items[id].price_per_level = Parse::toInt(infile.val);
		else if (infile.key == "price_sell")
			// @ATTR price_sell|int|The amount of currency the item is sold for, if set to 0 the sell prices is prices*vendor_ratio.
			items[id].price_sell = Parse::toInt(infile.val);
		else if (infile.key == "max_quantity")
			// @ATTR max_quantity|int|Max item count per stack.
			items[id].max_quantity = Parse::toInt(infile.val);
		else if (infile.key == "pickup_status")
			// @ATTR pickup_status|string|Set a campaign status when item is picked up, this is used for quest items.
			items[id].pickup_status = infile.val;
		else if (infile.key == "stepfx")
			// @ATTR stepfx|predefined_string|Sound effect when walking, this applies only to armors.
			items[id].stepfx = infile.val;
		else if (infile.key == "disable_slots") {
			// @ATTR disable_slots|list(predefined_string)|A comma separated list of equip slot types to disable when this item is equipped.
			items[id].disable_slots.clear();
			std::string slot_type = Parse::popFirstString(infile.val);

			while (slot_type != "") {
				items[id].disable_slots.push_back(slot_type);
				slot_type = Parse::popFirstString(infile.val);
			}
		}
		else if (infile.key == "quest_item") {
			// @ATTR quest_item|bool|If true, this item is a quest item and can not be dropped, stashed, or sold.
			items[id].quest_item = Parse::toBool(infile.val);
		}
		else if (infile.key == "no_stash") {
			// @ATTR no_stash|bool|If true, this item can not be stashed.
			items[id].no_stash = Parse::toBool(infile.val);
		}
		else {
			infile.error("ItemManager: '%s' is not a valid key.", infile.key.c_str());
		}

	}
	infile.close();
}
Пример #5
0
/**
 * 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;
			else if (infile.key == "power_on_half_dead") power_index[ON_HALF_DEAD] = num;
			else if (infile.key == "power_on_debuff") power_index[ON_DEBUFF] = num;
			else if (infile.key == "power_on_join_combat") power_index[ON_JOIN_COMBAT] = num;
			else if (infile.key == "chance_on_hit") power_chance[ON_HIT] = num;
			else if (infile.key == "chance_on_death") power_chance[ON_DEATH] = num;
			else if (infile.key == "chance_on_half_dead") power_chance[ON_HALF_DEAD] = num;
			else if (infile.key == "chance_on_debuff") power_chance[ON_DEBUFF] = num;
			else if (infile.key == "chance_on_join_combat") power_chance[ON_JOIN_COMBAT] = 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();
	}
}
Пример #6
0
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
0
void loadMiscSettings() {
	FileParser infile;
	// load miscellaneous settings from engine config
	// misc.txt
	if (infile.open(mods->locate("engine/misc.txt").c_str())) {
		while (infile.next()) {
			if (infile.key == "save_hpmp") {
				SAVE_HPMP = toInt(infile.val);
			} else if (infile.key == "default_name") {
				DEFAULT_NAME = infile.val.c_str();
			} else if (infile.key == "corpse_timeout") {
				CORPSE_TIMEOUT = toInt(infile.val);
			} else if (infile.key == "sell_without_vendor") {
				SELL_WITHOUT_VENDOR = toInt(infile.val);
			}
		}
		infile.close();
	} else fprintf(stderr, "Unable to open engine/misc.txt!\n");
	// resolutions.txt
	if (infile.open(mods->locate("engine/resolutions.txt").c_str())) {
		while (infile.next()) {
			if (infile.key == "menu_frame_width")
				FRAME_W = toInt(infile.val);
			else if (infile.key == "menu_frame_height")
				FRAME_H = toInt(infile.val);
			else if (infile.key == "icon_size")
				ICON_SIZE = toInt(infile.val);
			else if (infile.key == "required_width") {
				MIN_VIEW_W = toInt(infile.val);
				if (VIEW_W < MIN_VIEW_W) VIEW_W = MIN_VIEW_W;
				VIEW_W_HALF = VIEW_W/2;
			} else if (infile.key == "required_height") {
				MIN_VIEW_H = toInt(infile.val);
				if (VIEW_H < MIN_VIEW_H) VIEW_H = MIN_VIEW_H;
				VIEW_H_HALF = VIEW_H/2;
			}
		}
		infile.close();
	} else fprintf(stderr, "Unable to open engine/resolutions.txt!\n");
	// gameplay.txt
	if (infile.open(mods->locate("engine/gameplay.txt").c_str())) {
		while (infile.next()) {
			if (infile.key == "enable_playgame") {
				ENABLE_PLAYGAME = toInt(infile.val);
			}
		}
		infile.close();
	} else fprintf(stderr, "Unable to open engine/gameplay.txt!\n");
	// combat.txt
	if (infile.open(mods->locate("engine/combat.txt").c_str())) {
		while (infile.next()) {
			if (infile.key == "max_absorb_percent") {
				MAX_ABSORB = toInt(infile.val);
			} else if (infile.key == "max_resist_percent") {
				MAX_RESIST = toInt(infile.val);
			} else if (infile.key == "max_block_percent") {
				MAX_BLOCK = toInt(infile.val);
			} else if (infile.key == "max_avoidance_percent") {
				MAX_AVOIDANCE = toInt(infile.val);
			}
		}
		infile.close();
	} else fprintf(stderr, "Unable to open engine/combat.txt!\n");
	// elements.txt
	if (infile.open(mods->locate("engine/elements.txt").c_str())) {
		Element e;
		ELEMENTS.clear();
		while (infile.next()) {
			if (infile.key == "name") e.name = infile.val;
			else if (infile.key == "resist") e.resist = infile.val;

			if (e.name != "" && e.resist != "") {
				ELEMENTS.push_back(e);
				e.name = e.resist = "";
			}
		}
		infile.close();
	} else fprintf(stderr, "Unable to open engine/elements.txt!\n");
	// classes.txt
	if (infile.open(mods->locate("engine/classes.txt").c_str())) {
		HeroClass c;
		HERO_CLASSES.clear();
		while (infile.next()) {
			if (infile.key == "name") c.name = infile.val;

			if (c.name != "") {
				HERO_CLASSES.push_back(c);
				c.name = "";
			}

			if (!HERO_CLASSES.empty()) {
				if (infile.key == "description") HERO_CLASSES.back().description = infile.val;
				else if (infile.key == "currency") HERO_CLASSES.back().currency = toInt(infile.val);
				else if (infile.key == "equipment") HERO_CLASSES.back().equipment = infile.val;
				else if (infile.key == "physical") HERO_CLASSES.back().physical = toInt(infile.val);
				else if (infile.key == "mental") HERO_CLASSES.back().mental = toInt(infile.val);
				else if (infile.key == "offense") HERO_CLASSES.back().offense = toInt(infile.val);
				else if (infile.key == "defense") HERO_CLASSES.back().defense = toInt(infile.val);
				else if (infile.key == "actionbar") {
					for (int i=0; i<12; i++) {
						HERO_CLASSES.back().hotkeys[i] = toInt(infile.nextValue());
					}
				}
				else if (infile.key == "powers") {
					string power;
					while ( (power = infile.nextValue()) != "") {
						HERO_CLASSES.back().powers.push_back(toInt(power));
					}
				}
			}
		}
		infile.close();
	} else fprintf(stderr, "Unable to open engine/classes.txt!\n");

	// Make a default hero class if none were found
	if (HERO_CLASSES.empty()) {
		HeroClass c;
		c.name = msg->get("Adventurer");
		HERO_CLASSES.push_back(c);
	}
}
Пример #8
0
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")
				FRAME_H = toInt(infile.val);
			// @ATTR icon_size|integer|Size of icons.
			else if (infile.key == "icon_size")
				ICON_SIZE = toInt(infile.val);
			// @ATTR required_width|integer|Minimum window/screen resolution width.
			else if (infile.key == "required_width") {
				MIN_VIEW_W = toInt(infile.val);
				if (VIEW_W < MIN_VIEW_W) VIEW_W = MIN_VIEW_W;
				VIEW_W_HALF = VIEW_W/2;
			}
			// @ATTR required_width|integer|Minimum window/screen resolution height.
			else if (infile.key == "required_height") {
				MIN_VIEW_H = toInt(infile.val);
				if (VIEW_H < MIN_VIEW_H) VIEW_H = MIN_VIEW_H;
				VIEW_H_HALF = VIEW_H/2;
			}
		}
		infile.close();
	}

	// @CLASS Settings: Gameplay|Description of engine/gameplay.txt
	if (infile.open("engine/gameplay.txt")) {
		while (infile.next()) {
			if (infile.key == "enable_playgame") {
				// @ATTR enable_playgame|boolean|Enables the "Play Game" button on the main menu.
				ENABLE_PLAYGAME = toBool(infile.val);
			}
		}
		infile.close();
	}

	// @CLASS Settings: Combat|Description of engine/combat.txt
	if (infile.open("engine/combat.txt")) {
		while (infile.next()) {
			// @ATTR max_absorb_percent|integer|Maximum percentage of damage that can be absorbed.
			if (infile.key == "max_absorb_percent") MAX_ABSORB = toInt(infile.val);
			// @ATTR max_resist_percent|integer|Maximum percentage of elemental damage that can be resisted.
			else if (infile.key == "max_resist_percent") MAX_RESIST = toInt(infile.val);
			// @ATTR max_block_percent|integer|Maximum percentage of damage that can be blocked.
			else if (infile.key == "max_block_percent") MAX_BLOCK = toInt(infile.val);
			// @ATTR max_avoidance_percent|integer|Maximum percentage chance that hazards can be avoided.
			else if (infile.key == "max_avoidance_percent") MAX_AVOIDANCE = toInt(infile.val);
			// @ATTR min_absorb_percent|integer|Minimum percentage of damage that can be absorbed.
			else if (infile.key == "min_absorb_percent") MIN_ABSORB = toInt(infile.val);
			// @ATTR min_resist_percent|integer|Minimum percentage of elemental damage that can be resisted.
			else if (infile.key == "min_resist_percent") MIN_RESIST = toInt(infile.val);
			// @ATTR min_block_percent|integer|Minimum percentage of damage that can be blocked.
			else if (infile.key == "min_block_percent") MIN_BLOCK = toInt(infile.val);
			// @ATTR min_avoidance_percent|integer|Minimum percentage chance that hazards can be avoided.
			else if (infile.key == "min_avoidance_percent") MIN_AVOIDANCE = toInt(infile.val);
		}
		infile.close();
	}

	// @CLASS Settings: Elements|Description of engine/elements.txt
	if (infile.open("engine/elements.txt")) {
		Element e;
		while (infile.next()) {
			// @ATTR name|string|An identifier for this element.
			if (infile.key == "name") e.name = infile.val;
			// @ATTR dscription|string|The displayed name of this element.
			else if (infile.key == "description") e.description = infile.val;

			if (e.name != "" && e.description != "") {
				ELEMENTS.push_back(e);
				e.name = e.description = "";
			}
		}
		infile.close();
	}

	// @CLASS Settings: Equip flags|Description of engine/equip_flags.txt
	if (infile.open("engine/equip_flags.txt")) {
		string type,description;
		type = description = "";

		while (infile.next()) {
			// @ATTR name|string|An identifier for this equip flag.
			if (infile.key == "name") type = infile.val;
			// @ATTR dscription|string|The displayed name of this equip flag.
			else if (infile.key == "description") description = infile.val;

			if (type != "" && description != "") {
				EQUIP_FLAGS[type] = description;
				type = description = "";
			}
		}
		infile.close();
	}

	// @CLASS Settings: Classes|Description of engine/classes.txt
	if (infile.open("engine/classes.txt")) {
		HeroClass c;
		while (infile.next()) {
			// @ATTR name|string|The displayed name of this class.
			if (infile.key == "name") c.name = infile.val;

			if (c.name != "") {
				HERO_CLASSES.push_back(c);
				c.name = "";
			}

			if (!HERO_CLASSES.empty()) {
				// @ATTR description|string|A description of this class.
				if (infile.key == "description") HERO_CLASSES.back().description = infile.val;
				// @ATTR currency|integer|The amount of currency this class will start with.
				else if (infile.key == "currency") HERO_CLASSES.back().currency = toInt(infile.val);
				// @ATTR equipment|item (integer), ...|A list of items that are equipped when starting with this class.
				else if (infile.key == "equipment") HERO_CLASSES.back().equipment = infile.val;
				// @ATTR physical|integer|Class starts with this physical stat.
				else if (infile.key == "physical") HERO_CLASSES.back().physical = toInt(infile.val);
				// @ATTR mental|integer|Class starts with this mental stat.
				else if (infile.key == "mental") HERO_CLASSES.back().mental = toInt(infile.val);
				// @ATTR offense|integer|Class starts with this offense stat.
				else if (infile.key == "offense") HERO_CLASSES.back().offense = toInt(infile.val);
				// @ATTR defense|integer|Class starts with this defense stat.
				else if (infile.key == "defense") HERO_CLASSES.back().defense = toInt(infile.val);

				else if (infile.key == "actionbar") {
					// @ATTR actionbar|power (integer), ...|A list of powers to place in the action bar for the class.
					for (int i=0; i<12; i++) {
						HERO_CLASSES.back().hotkeys[i] = toInt(infile.nextValue());
					}
				}
				else if (infile.key == "powers") {
					// @ATTR powers|power (integer), ...|A list of powers that are unlocked when starting this class.
					string power;
					while ( (power = infile.nextValue()) != "") {
						HERO_CLASSES.back().powers.push_back(toInt(power));
					}
				}
				else if (infile.key == "campaign") {
					// @ATTR campaign|status (string), ...|A list of campaign statuses that are set when starting this class.
					string status;
					while ( (status = infile.nextValue()) != "") {
						HERO_CLASSES.back().statuses.push_back(status);
					}
				}
			}
		}
		infile.close();
	}
	// Make a default hero class if none were found
	if (HERO_CLASSES.empty()) {
		HeroClass c;
		c.name = msg->get("Adventurer");
		HERO_CLASSES.push_back(c);
	}

	// @CLASS Settings: Death penalty|Description of engine/death_penalty.txt
	if (infile.open("engine/death_penalty.txt")) {
		while (infile.next()) {
			// @ATTR enable|boolean|Enable the death penalty.
			if (infile.key == "enable") DEATH_PENALTY = toBool(infile.val);
			// @ATTR permadeath|boolean|Force permadeath for all new saves.
			else if (infile.key == "permadeath") DEATH_PENALTY_PERMADEATH = toBool(infile.val);
			// @ATTR currency|integer|Remove this percentage of currency.
			else if (infile.key == "currency") DEATH_PENALTY_CURRENCY = toInt(infile.val);
			// @ATTR xp_total|integer|Remove this percentage of total XP.
			else if (infile.key == "xp_total") DEATH_PENALTY_XP = toInt(infile.val);
			// @ATTR xp_current_level|integer|Remove this percentage of the XP gained since the last level.
			else if (infile.key == "xp_current_level") DEATH_PENALTY_XP_CURRENT = toInt(infile.val);
			// @ATTR random_item|integer|Removes a random item from the player's inventory.
			else if (infile.key == "random_item") DEATH_PENALTY_ITEM = toBool(infile.val);
		}
		infile.close();
	}
}
Пример #9
0
/**
 * 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);
		else if (infile.key == "cooldown")
			powers[input_id].cooldown = parse_duration(infile.val);
		// animation info
		else if (infile.key == "animation")
			powers[input_id].animation_name = "animations/powers/" + infile.val;
		else if (infile.key == "soundfx")
			powers[input_id].sfx_index = loadSFX(infile.val);
		else if (infile.key == "directional")
			powers[input_id].directional = toBool(infile.val);
		else if (infile.key == "visual_random")
			powers[input_id].visual_random = toInt(infile.val);
		else if (infile.key == "visual_option")
			powers[input_id].visual_option = toInt(infile.val);
		else if (infile.key == "aim_assist")
			powers[input_id].aim_assist = toBool(infile.val);
		else if (infile.key == "speed")
			powers[input_id].speed = toInt(infile.val);
		else if (infile.key == "lifespan")
			powers[input_id].lifespan = parse_duration(infile.val);
		else if (infile.key == "floor")
			powers[input_id].floor = toBool(infile.val);
		else if (infile.key == "complete_animation")
			powers[input_id].complete_animation = toBool(infile.val);
		// hazard traits
		else if (infile.key == "use_hazard")
			powers[input_id].use_hazard = toBool(infile.val);
		else if (infile.key == "no_attack")
			powers[input_id].no_attack = toBool(infile.val);
		else if (infile.key == "radius")
			powers[input_id].radius = toInt(infile.val);
		else if (infile.key == "base_damage") {
			if (infile.val == "none")        powers[input_id].base_damage = BASE_DAMAGE_NONE;
			else if (infile.val == "melee")  powers[input_id].base_damage = BASE_DAMAGE_MELEE;
			else if (infile.val == "ranged") powers[input_id].base_damage = BASE_DAMAGE_RANGED;
			else if (infile.val == "ment")   powers[input_id].base_damage = BASE_DAMAGE_MENT;
			else fprintf(stderr, "unknown base_damage %s\n", infile.val.c_str());
		}
		else if (infile.key == "damage_multiplier")
			powers[input_id].damage_multiplier = toInt(infile.val);
		else if (infile.key == "starting_pos") {
			if (infile.val == "source")      powers[input_id].starting_pos = STARTING_POS_SOURCE;
			else if (infile.val == "target") powers[input_id].starting_pos = STARTING_POS_TARGET;
			else if (infile.val == "melee")  powers[input_id].starting_pos = STARTING_POS_MELEE;
			else fprintf(stderr, "unknown starting_pos %s\n", infile.val.c_str());
		}
		else if (infile.key == "multitarget")
			powers[input_id].multitarget = toBool(infile.val);
		else if (infile.key == "trait_armor_penetration")
			powers[input_id].trait_armor_penetration = toBool(infile.val);
		else if (infile.key == "trait_crits_impaired")
			powers[input_id].trait_crits_impaired = toInt(infile.val);
		else if (infile.key == "trait_elemental") {
			for (unsigned int i=0; i<ELEMENTS.size(); i++) {
				if (infile.val == ELEMENTS[i].name) powers[input_id].trait_elemental = i;
			}
		}
		else if (infile.key == "range")
			powers[input_id].range = toInt(infile.nextValue());
		//steal effects
		else if (infile.key == "hp_steal")
			powers[input_id].hp_steal = toInt(infile.val);
		else if (infile.key == "mp_steal")
			powers[input_id].mp_steal = toInt(infile.val);
		//missile modifiers
		else if (infile.key == "missile_angle")
			powers[input_id].missile_angle = toInt(infile.val);
		else if (infile.key == "angle_variance")
			powers[input_id].angle_variance = toInt(infile.val);
		else if (infile.key == "speed_variance")
			powers[input_id].speed_variance = toInt(infile.val);
		//repeater modifiers
		else if (infile.key == "delay")
			powers[input_id].delay = parse_duration(infile.val);
		// buff/debuff durations
		else if (infile.key == "transform_duration")
			powers[input_id].transform_duration = toInt(infile.val);
		else if (infile.key == "manual_untransform")
			powers[input_id].manual_untransform = toBool(infile.val);
		else if (infile.key == "keep_equipment")
			powers[input_id].keep_equipment = toBool(infile.val);
		// buffs
		else if (infile.key == "buff")
			powers[input_id].buff= toBool(infile.val);
		else if (infile.key == "buff_teleport")
			powers[input_id].buff_teleport = toBool(infile.val);
		else if (infile.key == "post_effect") {
			infile.val = infile.val + ',';
			PostEffect pe;
			pe.id = eatFirstInt(infile.val, ',');
			pe.magnitude = eatFirstInt(infile.val, ',');
			pe.duration = eatFirstInt(infile.val, ',');
			powers[input_id].post_effects.push_back(pe);
		}
		else if (infile.key == "effect_type")
			powers[input_id].effect_type = infile.val;
		else if (infile.key == "effect_additive")
			powers[input_id].effect_additive = toBool(infile.val);
		else if (infile.key == "effect_render_above")
			powers[input_id].effect_render_above = toBool(infile.val);
		// pre and post power effects
		else if (infile.key == "post_power")
			powers[input_id].post_power = toInt(infile.val);
		else if (infile.key == "wall_power")
			powers[input_id].wall_power = toInt(infile.val);
		else if (infile.key == "allow_power_mod")
			powers[input_id].allow_power_mod = toBool(infile.val);
		// spawn info
		else if (infile.key == "spawn_type")
			powers[input_id].spawn_type = infile.val;
		else if (infile.key == "target_neighbor")
			powers[input_id].target_neighbor = toInt(infile.val);
		else
			fprintf(stderr, "ignoring unknown key %s set to %s\n", infile.key.c_str(), infile.val.c_str());
	}
	infile.close();
}
Пример #10
0
/**
 * 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);
			}
		}
	}

	// If we have more than one tab, create tab_control
	if (!tabs.empty()) {
		tab_control = new WidgetTabControl();

		if (tab_control) {
			// Initialize the tab control.
			tab_control->setMainArea(window_area.x+tab_area.x, window_area.y+tab_area.y, tab_area.w, tab_area.h);

			// Define the header.
			for (size_t i=0; i<tabs.size(); i++)
				tab_control->setTabTitle(static_cast<unsigned>(i), msg->get(tabs[i].title));
			tab_control->updateHeader();

			tablist.add(tab_control);
		}

		tablist_pow.resize(tabs.size());
	}

	// create power slots
	for (size_t i=0; i<slots.size(); i++) {
		if (static_cast<size_t>(power_cell[i].id) < powers->powers.size()) {
			slots[i] = new WidgetSlot(powers->powers[power_cell[i].id].icon);
			slots[i]->setBasePos(power_cell[i].pos.x, power_cell[i].pos.y);

			if (!tablist_pow.empty()) {
				tablist_pow[power_cell[i].tab].add(slots[i]);
				tablist_pow[power_cell[i].tab].setPrevTabList(&tablist);
				tablist_pow[power_cell[i].tab].lock();
			}
			else {
				tablist.add(slots[i]);
			}

			if (upgradeButtons[i] != NULL) {
				upgradeButtons[i]->setBasePos(power_cell[i].pos.x + ICON_SIZE, power_cell[i].pos.y);
			}
		}
	}

	applyPowerUpgrades();

	tree_loaded = true;

	align();
}
Пример #11
0
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;
}
Пример #12
0
/**
 * 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;
						while (infile.val != "") {
							stack.item = toInt(infile.nextValue());
							stock.add(stack);
						}
					}
				}

				// handle vocals
				else if (infile.key == "vox_intro") {
					loadSound(infile.val, NPC_VOX_INTRO);
				}
			}
		}
		infile.close();
	} else fprintf(stderr, "Unable to open npcs/%s.txt!\n", npc_id.c_str());
	loadGraphics(filename_portrait);
}
Пример #13
0
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;
	}
	while(infile.next()) {
		xp_table[toInt(infile.key) - 1] = toInt(infile.val);
	}
	max_spendable_stat_points = toInt(infile.key) * stat_points_per_level;
	infile.close();
}
Пример #14
0
/**
 * 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;

		else if (infile.key == "speed") speed = speed_default = num;
		else if (infile.key == "dspeed") dspeed = dspeed_default = 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] = parse_duration(infile.val);
		else if (infile.key == "cooldown_melee_ment") power_cooldown[MELEE_MENT] = parse_duration(infile.val);
		else if (infile.key == "cooldown_ranged_phys") power_cooldown[RANGED_PHYS] = parse_duration(infile.val);
		else if (infile.key == "cooldown_ranged_ment") power_cooldown[RANGED_MENT] = parse_duration(infile.val);
		else if (infile.key == "power_on_hit") power_index[ON_HIT] = num;
		else if (infile.key == "power_on_death") power_index[ON_DEATH] = num;
		else if (infile.key == "power_on_half_dead") power_index[ON_HALF_DEAD] = num;
		else if (infile.key == "power_on_debuff") power_index[ON_DEBUFF] = num;
		else if (infile.key == "power_on_join_combat") power_index[ON_JOIN_COMBAT] = num;
		else if (infile.key == "chance_on_hit") power_chance[ON_HIT] = num;
		else if (infile.key == "chance_on_death") power_chance[ON_DEATH] = num;
		else if (infile.key == "chance_on_half_dead") power_chance[ON_HALF_DEAD] = num;
		else if (infile.key == "chance_on_debuff") power_chance[ON_DEBUFF] = num;
		else if (infile.key == "chance_on_join_combat") power_chance[ON_JOIN_COMBAT] = num;
		else if (infile.key == "cooldown_hit") cooldown_hit = num;

		else if (infile.key == "passive_powers") {
			std::string p = infile.nextValue();
			while (p != "") {
				powers_passive.push_back(toInt(p));
				p = infile.nextValue();
			}
		}

		else if (infile.key == "melee_range") melee_range = num;
		else if (infile.key == "threat_range") threat_range = 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;

		// hide enemy HP bar
		else if (infile.key == "suppress_hp") {
			if (num == 1)
				suppress_hp = true;
			else
				suppress_hp = false;
		}

		// these are only used for EnemyGroupManager
		// we check for them here so that we don't get an error saying they are invalid
		else if (infile.key == "categories") valid = true;
		else if (infile.key == "rarity") valid = true;

		else if (!valid) {
			fprintf(stderr, "%s=%s not a valid StatBlock parameter\n", infile.key.c_str(), infile.val.c_str());
		}
	}
	infile.close();

	// sort loot table
	std::sort(loot.begin(), loot.end(), sortLoot);
}
Пример #15
0
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
				newanim = new Animation(_name, type, sprite);
				newanim->setup(frames, duration);
				if (!active_frames.empty())
					newanim->setActiveFrames(active_frames);
				active_frames.clear();
				animations.push_back(newanim);
				compressed_loading = true;
			}
			// frame = index, direction, x, y, w, h, offsetx, offsety
			Rect r;
			Point offset;
			const unsigned short index = static_cast<unsigned short>(toInt(parser.nextValue()));
			const unsigned short direction = static_cast<unsigned short>(toInt(parser.nextValue()));
			r.x = toInt(parser.nextValue());
			r.y = toInt(parser.nextValue());
			r.w = toInt(parser.nextValue());
			r.h = toInt(parser.nextValue());
			offset.x = toInt(parser.nextValue());
			offset.y = toInt(parser.nextValue());
			newanim->addFrame(index, direction, r, offset);
		}
		else {
			parser.error("AnimationSet: '%s' is not a valid key.", parser.key.c_str());
		}

		if (_name == "") {
			// This is the first animation
			starting_animation = parser.section;
		}
		_name = parser.section;
	}
	parser.close();

	if (!compressed_loading) {
		// add final animation
		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);
	}

	if (starting_animation != "") {
		Animation *a = getAnimation(starting_animation);
		delete defaultAnimation;
		defaultAnimation = a;
	}
}
Пример #16
0
/**
 * 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;
		// @ATTR power_on_hit|integer|Power index that is triggered when hit.
		else if (infile.key == "power_on_hit") power_index[ON_HIT] = num;
		// @ATTR power_on_death|integer|Power index that is triggered when dead.
		else if (infile.key == "power_on_death") power_index[ON_DEATH] = num;
		// @ATTR power_on_half_dead|integer|Power index that is triggered when at half health.
		else if (infile.key == "power_on_half_dead") power_index[ON_HALF_DEAD] = num;
		// @ATTR power_on_debuff|integer|Power index that is triggered when under a negative status effect.
		else if (infile.key == "power_on_debuff") power_index[ON_DEBUFF] = num;
		// @ATTR power_on_join_combat|integer|Power index that is triggered when initiating combat.
		else if (infile.key == "power_on_join_combat") power_index[ON_JOIN_COMBAT] = num;
		// @ATTR chance_on_hit|integer|Percentage chance that power_on_hit will be triggered.
		else if (infile.key == "chance_on_hit") power_chance[ON_HIT] = num;
		// @ATTR chance_on_death|integer|Percentage chance that power_on_death will be triggered.
		else if (infile.key == "chance_on_death") power_chance[ON_DEATH] = num;
		// @ATTR chance_on_half_dead|integer|Percentage chance that power_on_half_dead will be triggered.
		else if (infile.key == "chance_on_half_dead") power_chance[ON_HALF_DEAD] = num;
		// @ATTR chance_on_debuff|integer|Percentage chance that power_on_debuff will be triggered.
		else if (infile.key == "chance_on_debuff") power_chance[ON_DEBUFF] = num;
		// @ATTR chance_on_join_combat|integer|Percentage chance that power_on_join_combat will be triggered.
		else if (infile.key == "chance_on_join_combat") power_chance[ON_JOIN_COMBAT] = num;
		// @ATTR cooldown_hit|duration|Duration of cooldown after being hit in 'ms' or 's'.
		else if (infile.key == "cooldown_hit") cooldown_hit = parse_duration(infile.val);

		else if (infile.key == "passive_powers") {
			// @ATTR passive_powers|power (integer), ...|A list of passive powers this creature has.
			powers_passive.clear();
			std::string p = infile.nextValue();
			while (p != "") {
				powers_passive.push_back(toInt(p));
				p = infile.nextValue();
			}
		}

		// @ATTR melee_range|float|Minimum distance from target required to use melee powers.
		else if (infile.key == "melee_range") melee_range = fnum;
		// @ATTR threat_range|float|Radius of the area this creature will be able to start chasing the hero.
		else if (infile.key == "threat_range") threat_range = fnum;
		// @ATTR combat_style|[default:aggressive:passive]|How the creature will enter combat. Default is within range of the hero; Aggressive is always in combat; Passive must be attacked to enter combat.
		else if (infile.key == "combat_style") {
			if (infile.val == "default") combat_style = COMBAT_DEFAULT;
			else if (infile.val == "aggressive") combat_style = COMBAT_AGGRESSIVE;
			else if (infile.val == "passive") combat_style = COMBAT_PASSIVE;
			else infile.error("StatBlock: Unknown combat style '%s'", infile.val.c_str());
		}

		// @ATTR animations|string|Filename of an animation definition.
		else if (infile.key == "animations") animations = infile.val;

		// @ATTR suppress_hp|boolean|Hides the enemy HP bar for this creature.
		else if (infile.key == "suppress_hp") suppress_hp = toBool(infile.val);

		else if (infile.key == "categories") {
			// @ATTR categories|category (string), ...|Categories that this enemy belongs to.
			categories.clear();
			std::string cat;
			while ((cat = infile.nextValue()) != "") {
				categories.push_back(cat);
			}
		}

		// this is only used for EnemyGroupManager
		// we check for them here so that we don't get an error saying they are invalid
		else if (infile.key == "rarity") ; // but do nothing

		else if (!valid) {
			infile.error("StatBlock: '%s' is not a valid key.", infile.key.c_str());
		}
	}
	infile.close();

	hp = starting[STAT_HP_MAX];
	mp = starting[STAT_MP_MAX];

	applyEffects();
}
Пример #17
0
/**
 * When loading the game, load from file if possible
 */
void GameStatePlay::loadGame() {
	int saved_hp = 0;
	int saved_mp = 0;
	int currency = 0;

	// game slots are currently 1-4
	if (game_slot == 0) return;

	FileParser infile;
	int hotkeys[12];

	for (int i=0; i<12; i++) {
		hotkeys[i] = -1;
	}

	stringstream ss;
	ss.str("");
	ss << PATH_USER;
	if (GAME_PREFIX.length() > 0)
		ss << GAME_PREFIX << "_";
	ss << "save" << game_slot << ".txt";

	if (infile.open(ss.str(), false)) {
		while (infile.next()) {
			if (infile.key == "name") pc->stats.name = infile.val;
			else if (infile.key == "permadeath") {
				pc->stats.permadeath = toBool(infile.val);
			}
			else if (infile.key == "option") {
				pc->stats.gfx_base = infile.nextValue();
				pc->stats.gfx_head = infile.nextValue();
				pc->stats.gfx_portrait = infile.nextValue();
			}
			else if (infile.key == "class") {
				pc->stats.character_class = infile.nextValue();
			}
			else if (infile.key == "xp") {
				pc->stats.xp = toUnsignedLong(infile.val);
			}
			else if (infile.key == "hpmp") {
				saved_hp = toInt(infile.nextValue());
				saved_mp = toInt(infile.nextValue());
			}
			else if (infile.key == "build") {
				pc->stats.physical_character = toInt(infile.nextValue());
				pc->stats.mental_character = toInt(infile.nextValue());
				pc->stats.offense_character = toInt(infile.nextValue());
				pc->stats.defense_character = toInt(infile.nextValue());
				if (pc->stats.physical_character < 0 || pc->stats.physical_character > pc->stats.max_points_per_stat ||
						pc->stats.mental_character < 0 || pc->stats.mental_character > pc->stats.max_points_per_stat ||
						pc->stats.offense_character < 0 || pc->stats.offense_character > pc->stats.max_points_per_stat ||
						pc->stats.defense_character < 0 || pc->stats.defense_character > pc->stats.max_points_per_stat) {

					fprintf(stderr, "Some basic stats are out of bounds, setting to zero\n");
					pc->stats.physical_character = 0;
					pc->stats.mental_character = 0;
					pc->stats.offense_character = 0;
					pc->stats.defense_character = 0;
				}
			}
			else if (infile.key == "currency") {
				currency = toInt(infile.val);
			}
			else if (infile.key == "equipped") {
				menu->inv->inventory[EQUIPMENT].setItems(infile.val);
			}
			else if (infile.key == "equipped_quantity") {
				menu->inv->inventory[EQUIPMENT].setQuantities(infile.val);
			}
			else if (infile.key == "carried") {
				menu->inv->inventory[CARRIED].setItems(infile.val);
			}
			else if (infile.key == "carried_quantity") {
				menu->inv->inventory[CARRIED].setQuantities(infile.val);
			}
			else if (infile.key == "spawn") {
				mapr->teleport_mapname = infile.nextValue();
				if (fileExists(mods->locate(mapr->teleport_mapname))) {
					mapr->teleport_destination.x = toInt(infile.nextValue()) + 0.5f;
					mapr->teleport_destination.y = toInt(infile.nextValue()) + 0.5f;
					mapr->teleportation = true;
					// prevent spawn.txt from putting us on the starting map
					mapr->clearEvents();
				}
				else {
					fprintf(stderr, "Unable to find %s, loading maps/spawn.txt\n", mapr->teleport_mapname.c_str());
					mapr->teleport_mapname = "maps/spawn.txt";
					mapr->teleport_destination.x = 1;
					mapr->teleport_destination.y = 1;
					mapr->teleportation = true;
				}
			}
			else if (infile.key == "actionbar") {
				for (int i=0; i<12; i++) {
					hotkeys[i] = toInt(infile.nextValue());
					if (hotkeys[i] < 0) {
						fprintf(stderr, "Hotkey power on position %d has negative id, skipping\n", i);
						hotkeys[i] = 0;
					}
					else if ((unsigned)hotkeys[i] > powers->powers.size()-1) {
						fprintf(stderr, "Hotkey power id (%d) out of bounds 1-%d, skipping\n", hotkeys[i], (int)powers->powers.size());
						hotkeys[i] = 0;
					}
					else if (hotkeys[i] != 0 && powers->powers[hotkeys[i]].name == "") {
						fprintf(stderr, "Hotkey power with id=%d, found on position %d does not exist, skipping\n", hotkeys[i], i);
						hotkeys[i] = 0;
					}
				}
				menu->act->set(hotkeys);
			}
			else if (infile.key == "transformed") {
				pc->stats.transform_type = infile.nextValue();
				if (pc->stats.transform_type != "") {
					pc->stats.transform_duration = -1;
					pc->stats.manual_untransform = toBool(infile.nextValue());
				}
			}
			else if (infile.key == "powers") {
				string power;
				while ( (power = infile.nextValue()) != "") {
					if (toInt(power) > 0)
						pc->stats.powers_list.push_back(toInt(power));
				}
			}
			else if (infile.key == "campaign") camp->setAll(infile.val);
		}

		infile.close();
	}
	else fprintf(stderr, "Unable to open %s!\n", ss.str().c_str());


	menu->inv->fillEquipmentSlots();
	menu->inv->addCurrency(currency);

	// remove items with zero quantity from inventory
	menu->inv->inventory[EQUIPMENT].clean();
	menu->inv->inventory[CARRIED].clean();

	// Load stash
	loadStash();

	// initialize vars
	pc->stats.recalc();
	menu->inv->applyEquipment(menu->inv->inventory[EQUIPMENT].storage);
	// trigger passive effects here? Saved HP/MP values might depend on passively boosted HP/MP
	// powers->activatePassives(pc->stats);
	pc->stats.logic(); // run stat logic once to apply items bonuses
	if (SAVE_HPMP) {
		if (saved_hp < 0 || saved_hp > pc->stats.get(STAT_HP_MAX)) {
			fprintf(stderr, "HP value is out of bounds, setting to maximum\n");
			pc->stats.hp = pc->stats.get(STAT_HP_MAX);
		}
		else pc->stats.hp = saved_hp;

		if (saved_mp < 0 || saved_mp > pc->stats.get(STAT_MP_MAX)) {
			fprintf(stderr, "MP value is out of bounds, setting to maximum\n");
			pc->stats.mp = pc->stats.get(STAT_MP_MAX);
		}
		else pc->stats.mp = saved_mp;
	}
	else {
		pc->stats.hp = pc->stats.get(STAT_HP_MAX);
		pc->stats.mp = pc->stats.get(STAT_MP_MAX);
	}

	// reset character menu
	menu->chr->refreshStats();

	// just for aesthetics, turn the hero to face the camera
	pc->stats.direction = 6;

	// set up MenuTalker for this hero
	menu->talker->setHero(pc->stats.name, pc->stats.character_class, pc->stats.gfx_portrait);

	// load sounds (gender specific)
	pc->loadSounds();

	// apply power upgrades
	menu->pow->applyPowerUpgrades();
}
Пример #18
0
void GameStateConfig::readConfig () {
	//Load the menu configuration from file

	int offset_x = 0;
	int offset_y = 0;

	FileParser infile;
	if (infile.open("menus/config.txt")) {
		while (infile.next()) {

			infile.val = infile.val + ',';
			int x1 = eatFirstInt(infile.val, ',');
			int y1 = eatFirstInt(infile.val, ',');
			int x2 = eatFirstInt(infile.val, ',');
			int y2 = eatFirstInt(infile.val, ',');

			int setting_num = -1;

			if (infile.key == "listbox_scrollbar_offset") {
				activemods_lstb->scrollbar_offset = x1;
				inactivemods_lstb->scrollbar_offset = x1;
				joystick_device_lstb->scrollbar_offset = x1;
				resolution_lstb->scrollbar_offset = x1;
				language_lstb->scrollbar_offset = x1;
			}
			//checkboxes
			else if (infile.key == "fullscreen") {
				placeLabeledCheckbox( fullscreen_lb, fullscreen_cb, x1, y1, x2, y2, msg->get("Full Screen Mode"), 0);
			}
			else if (infile.key == "mouse_move") {
				placeLabeledCheckbox( mouse_move_lb, mouse_move_cb, x1, y1, x2, y2, msg->get("Move hero using mouse"), 3);
			}
			else if (infile.key == "combat_text") {
				placeLabeledCheckbox( combat_text_lb, combat_text_cb, x1, y1, x2, y2, msg->get("Show combat text"), 2);
			}
			else if (infile.key == "hwsurface") {
				placeLabeledCheckbox( hwsurface_lb, hwsurface_cb, x1, y1, x2, y2, msg->get("Hardware surfaces"), 0);
			}
			else if (infile.key == "doublebuf") {
				placeLabeledCheckbox( doublebuf_lb, doublebuf_cb, x1, y1, x2, y2, msg->get("Double buffering"), 0);
			}
			else if (infile.key == "enable_joystick") {
				placeLabeledCheckbox( enable_joystick_lb, enable_joystick_cb, x1, y1, x2, y2, msg->get("Use joystick"), 3);
			}
			else if (infile.key == "texture_quality") {
				placeLabeledCheckbox( texture_quality_lb, texture_quality_cb, x1, y1, x2, y2, msg->get("High Quality Textures"), 0);
			}
			else if (infile.key == "change_gamma") {
				placeLabeledCheckbox( change_gamma_lb, change_gamma_cb, x1, y1, x2, y2, msg->get("Allow changing gamma"), 0);
			}
			else if (infile.key == "animated_tiles") {
				placeLabeledCheckbox( animated_tiles_lb, animated_tiles_cb, x1, y1, x2, y2, msg->get("Animated tiles"), 0);
			}
			else if (infile.key == "mouse_aim") {
				placeLabeledCheckbox( mouse_aim_lb, mouse_aim_cb, x1, y1, x2, y2, msg->get("Mouse aim"), 3);
			}
			else if (infile.key == "no_mouse") {
				placeLabeledCheckbox( no_mouse_lb, no_mouse_cb, x1, y1, x2, y2, msg->get("Do not use mouse"), 3);
			}
			else if (infile.key == "show_fps") {
				placeLabeledCheckbox( show_fps_lb, show_fps_cb, x1, y1, x2, y2, msg->get("Show FPS"), 2);
			}
			else if (infile.key == "show_hotkeys") {
				placeLabeledCheckbox( show_hotkeys_lb, show_hotkeys_cb, x1, y1, x2, y2, msg->get("Show Hotkeys Labels"), 2);
			}
			else if (infile.key == "colorblind") {
				placeLabeledCheckbox( colorblind_lb, colorblind_cb, x1, y1, x2, y2, msg->get("Colorblind Mode"), 2);
			}
			//sliders
			else if (infile.key == "music_volume") {
				music_volume_sl->pos.x = frame.x + x2;
				music_volume_sl->pos.y = frame.y + y2;
				child_widget.push_back(music_volume_sl);
				optiontab[child_widget.size()-1] = 1;

				music_volume_lb->setX(frame.x + x1);
				music_volume_lb->setY(frame.y + y1);
				music_volume_lb->set(msg->get("Music Volume"));
				music_volume_lb->setJustify(JUSTIFY_RIGHT);
				child_widget.push_back(music_volume_lb);
				optiontab[child_widget.size()-1] = 1;
			}
			else if (infile.key == "sound_volume") {
				sound_volume_sl->pos.x = frame.x + x2;
				sound_volume_sl->pos.y = frame.y + y2;
				child_widget.push_back(sound_volume_sl);
				optiontab[child_widget.size()-1] = 1;

				sound_volume_lb->setX(frame.x + x1);
				sound_volume_lb->setY(frame.y + y1);
				sound_volume_lb->set(msg->get("Sound Volume"));
				sound_volume_lb->setJustify(JUSTIFY_RIGHT);
				child_widget.push_back(sound_volume_lb);
				optiontab[child_widget.size()-1] = 1;
			}
			else if (infile.key == "gamma") {
				gamma_sl->pos.x = frame.x + x2;
				gamma_sl->pos.y = frame.y + y2;
				child_widget.push_back(gamma_sl);
				optiontab[child_widget.size()-1] = 0;

				gamma_lb->setX(frame.x + x1);
				gamma_lb->setY(frame.y + y1);
				gamma_lb->set(msg->get("Gamma"));
				gamma_lb->setJustify(JUSTIFY_RIGHT);
				child_widget.push_back(gamma_lb);
				optiontab[child_widget.size()-1] = 0;
			}
			else if (infile.key == "joystick_deadzone") {
				joystick_deadzone_sl->pos.x = frame.x + x2;
				joystick_deadzone_sl->pos.y = frame.y + y2;
				child_widget.push_back(joystick_deadzone_sl);
				optiontab[child_widget.size()-1] = 3;

				joystick_deadzone_lb->setX(frame.x + x1);
				joystick_deadzone_lb->setY(frame.y + y1);
				joystick_deadzone_lb->set(msg->get("Joystick Deadzone"));
				joystick_deadzone_lb->setJustify(JUSTIFY_RIGHT);
				child_widget.push_back(joystick_deadzone_lb);
				optiontab[child_widget.size()-1] = 3;
			}
			//listboxes
			else if (infile.key == "resolution") {
				resolution_lstb->pos.x = frame.x + x2;
				resolution_lstb->pos.y = frame.y + y2;
				child_widget.push_back(resolution_lstb);
				optiontab[child_widget.size()-1] = 0;

				resolution_lb->setX(frame.x + x1);
				resolution_lb->setY(frame.y + y1);
				resolution_lb->set(msg->get("Resolution"));
				child_widget.push_back(resolution_lb);
				optiontab[child_widget.size()-1] = 0;

			}
			else if (infile.key == "activemods") {
				activemods_lstb->pos.x = frame.x + x2;
				activemods_lstb->pos.y = frame.y + y2;

				activemods_lb->setX(frame.x + x1);
				activemods_lb->setY(frame.y + y1);
				activemods_lb->set(msg->get("Active Mods"));
				child_widget.push_back(activemods_lb);
				optiontab[child_widget.size()-1] = 5;
			}
			else if (infile.key == "inactivemods") {
				inactivemods_lstb->pos.x = frame.x + x2;
				inactivemods_lstb->pos.y = frame.y + y2;

				inactivemods_lb->setX(frame.x + x1);
				inactivemods_lb->setY(frame.y + y1);
				inactivemods_lb->set(msg->get("Available Mods"));
				child_widget.push_back(inactivemods_lb);
				optiontab[child_widget.size()-1] = 5;
			}
			else if (infile.key == "joystick_device") {
				joystick_device_lstb->pos.x = frame.x + x2;
				joystick_device_lstb->pos.y = frame.y + y2;
				for(int i = 0; i < SDL_NumJoysticks(); i++) {
					if (SDL_JoystickName(i) != NULL)
						joystick_device_lstb->append(SDL_JoystickName(i),SDL_JoystickName(i));
				}
				child_widget.push_back(joystick_device_lstb);
				optiontab[child_widget.size()-1] = 3;

				joystick_device_lb->setX(frame.x + x1);
				joystick_device_lb->setY(frame.y + y1);
				joystick_device_lb->set(msg->get("Joystick"));
				child_widget.push_back(joystick_device_lb);
				optiontab[child_widget.size()-1] = 3;
			}
			else if (infile.key == "language") {
				language_lstb->pos.x = frame.x + x2;
				language_lstb->pos.y = frame.y + y2;
				child_widget.push_back(language_lstb);
				optiontab[child_widget.size()-1] = 2;

				language_lb->setX(frame.x + x1);
				language_lb->setY(frame.y + y1);
				language_lb->set(msg->get("Language"));
				child_widget.push_back(language_lb);
				optiontab[child_widget.size()-1] = 2;
			}
			// buttons begin
			else if (infile.key == "cancel") setting_num = CANCEL;
			else if (infile.key == "accept") setting_num = ACCEPT;
			else if (infile.key == "up") setting_num = UP;
			else if (infile.key == "down") setting_num = DOWN;
			else if (infile.key == "left") setting_num = LEFT;
			else if (infile.key == "right") setting_num = RIGHT;
			else if (infile.key == "bar1") setting_num = BAR_1;
			else if (infile.key == "bar2") setting_num = BAR_2;
			else if (infile.key == "bar3") setting_num = BAR_3;
			else if (infile.key == "bar4") setting_num = BAR_4;
			else if (infile.key == "bar5") setting_num = BAR_5;
			else if (infile.key == "bar6") setting_num = BAR_6;
			else if (infile.key == "bar7") setting_num = BAR_7;
			else if (infile.key == "bar8") setting_num = BAR_8;
			else if (infile.key == "bar9") setting_num = BAR_9;
			else if (infile.key == "bar0") setting_num = BAR_0;
			else if (infile.key == "main1") setting_num = MAIN1;
			else if (infile.key == "main2") setting_num = MAIN2;
			else if (infile.key == "character") setting_num = CHARACTER;
			else if (infile.key == "inventory") setting_num = INVENTORY;
			else if (infile.key == "powers") setting_num = POWERS;
			else if (infile.key == "log") setting_num = LOG;
			else if (infile.key == "ctrl") setting_num = CTRL;
			else if (infile.key == "shift") setting_num = SHIFT;
			else if (infile.key == "delete") setting_num = DEL;
			else if (infile.key == "actionbar") setting_num = ACTIONBAR;
			else if (infile.key == "actionbar_back") setting_num = ACTIONBAR_BACK;
			else if (infile.key == "actionbar_forward") setting_num = ACTIONBAR_FORWARD;
			else if (infile.key == "actionbar_use") setting_num = ACTIONBAR_USE;
			// buttons end

			else if (infile.key == "hws_note") {
				hws_note_lb->setX(frame.x + x1);
				hws_note_lb->setY(frame.y + y1);
				hws_note_lb->set(msg->get("Disable for performance"));
				child_widget.push_back(hws_note_lb);
				optiontab[child_widget.size()-1] = 0;
			}
			else if (infile.key == "dbuf_note") {
				dbuf_note_lb->setX(frame.x + x1);
				dbuf_note_lb->setY(frame.y + y1);
				dbuf_note_lb->set(msg->get("Disable for performance"));
				child_widget.push_back(dbuf_note_lb);
				optiontab[child_widget.size()-1] = 0;
			}
			else if (infile.key == "anim_tiles_note") {
				anim_tiles_note_lb->setX(frame.x + x1);
				anim_tiles_note_lb->setY(frame.y + y1);
				anim_tiles_note_lb->set(msg->get("Disable for performance"));
				child_widget.push_back(anim_tiles_note_lb);
				optiontab[child_widget.size()-1] = 0;
			}
			else if (infile.key == "test_note") {
				test_note_lb->setX(frame.x + x1);
				test_note_lb->setY(frame.y + y1);
				test_note_lb->set(msg->get("Experimental"));
				child_widget.push_back(test_note_lb);
				optiontab[child_widget.size()-1] = 0;
			}
			else if (infile.key == "handheld_note") {
				handheld_note_lb->setX(frame.x + x1);
				handheld_note_lb->setY(frame.y + y1);
				handheld_note_lb->set(msg->get("For handheld devices"));
				child_widget.push_back(handheld_note_lb);
				optiontab[child_widget.size()-1] = 3;
			}
			//buttons
			else if (infile.key == "activemods_shiftup") {
				activemods_shiftup_btn->pos.x = frame.x + x1;
				activemods_shiftup_btn->pos.y = frame.y + y1;
				activemods_shiftup_btn->refresh();
				child_widget.push_back(activemods_shiftup_btn);
				optiontab[child_widget.size()-1] = 5;
			}
			else if (infile.key == "activemods_shiftdown") {
				activemods_shiftdown_btn->pos.x = frame.x + x1;
				activemods_shiftdown_btn->pos.y = frame.y + y1;
				activemods_shiftdown_btn->refresh();
				child_widget.push_back(activemods_shiftdown_btn);
				optiontab[child_widget.size()-1] = 5;
			}
			else if (infile.key == "activemods_deactivate") {
				activemods_deactivate_btn->label = msg->get("<< Disable");
				activemods_deactivate_btn->pos.x = frame.x + x1;
				activemods_deactivate_btn->pos.y = frame.y + y1;
				activemods_deactivate_btn->refresh();
				child_widget.push_back(activemods_deactivate_btn);
				optiontab[child_widget.size()-1] = 5;
			}
			else if (infile.key == "inactivemods_activate") {
				inactivemods_activate_btn->label = msg->get("Enable >>");
				inactivemods_activate_btn->pos.x = frame.x + x1;
				inactivemods_activate_btn->pos.y = frame.y + y1;
				inactivemods_activate_btn->refresh();
				child_widget.push_back(inactivemods_activate_btn);
				optiontab[child_widget.size()-1] = 5;
			}
			else if (infile.key == "secondary_offset") {
				offset_x = x1;
				offset_y = y1;
			}
			else if (infile.key == "keybinds_bg_color") {
				// background color for keybinds scrollbox
				scrollpane_color.r = x1;
				scrollpane_color.g = y1;
				scrollpane_color.b = x2;
			}
			else if (infile.key == "scrollpane") {
				scrollpane.x = x1;
				scrollpane.y = y1;
				scrollpane.w = x2;
				scrollpane.h = y2;
			}
			else if (infile.key == "scrollpane_contents") {
				scrollpane_contents = x1;
			}

			if (setting_num > -1 && setting_num < 29) {
				//keybindings
				settings_lb[setting_num]->setX(x1);
				settings_lb[setting_num]->setY(y1);
				settings_key[setting_num]->pos.x = x2;
				settings_key[setting_num]->pos.y = y2;
			}

		}
		infile.close();
	}

	// Load the MenuConfirm positions and alignments from menus/menus.txt
	if (infile.open("menus/menus.txt")) {
		int menu_index = -1;
		while (infile.next()) {
			if (infile.key == "id") {
				if (infile.val == "confirm") menu_index = 0;
				else menu_index = -1;
			}

			if (menu_index == -1)
				continue;

			if (infile.key == "layout") {
				infile.val = infile.val + ',';
				menuConfirm_area.x = eatFirstInt(infile.val, ',');
				menuConfirm_area.y = eatFirstInt(infile.val, ',');
				menuConfirm_area.w = eatFirstInt(infile.val, ',');
				menuConfirm_area.h = eatFirstInt(infile.val, ',');
			}

			if (infile.key == "align") {
				menuConfirm_align = infile.val;
			}
		}
		infile.close();
	}

	defaults_confirm->window_area = menuConfirm_area;
	defaults_confirm->alignment = menuConfirm_align;
	defaults_confirm->align();
	defaults_confirm->update();

	resolution_confirm->window_area = menuConfirm_area;
	resolution_confirm->alignment = menuConfirm_align;
	resolution_confirm->align();
	resolution_confirm->update();

	// Allocate KeyBindings ScrollBox
	input_scrollbox = new WidgetScrollBox(scrollpane.w, scrollpane.h);
	input_scrollbox->pos.x = scrollpane.x + frame.x;
	input_scrollbox->pos.y = scrollpane.y + frame.y;
	input_scrollbox->bg.r = scrollpane_color.r;
	input_scrollbox->bg.g = scrollpane_color.g;
	input_scrollbox->bg.b = scrollpane_color.b;
	input_scrollbox->transparent = false;
	input_scrollbox->resize(scrollpane_contents);

	// Set positions of secondary key bindings
	for (unsigned int i = 29; i < 58; i++) {
		settings_key[i]->pos.x = settings_key[i-29]->pos.x + offset_x;
		settings_key[i]->pos.y = settings_key[i-29]->pos.y + offset_y;
	}
}
Пример #19
0
void loadMiscSettings() {
	FileParser infile;
	// load miscellaneous settings from engine config
	// misc.txt
	if (infile.open(mods->locate("engine/misc.txt").c_str())) {
		while (infile.next()) {
			if (infile.key == "save_hpmp") {
				SAVE_HPMP = atoi(infile.val.c_str());
			} else if (infile.key == "default_name") {
				DEFAULT_NAME = infile.val.c_str();
			}
		}
		infile.close();
	}
	else {
		fprintf(stderr, "No misc engine settings config found!\n");
	}
	// resolutions.txt
	if (infile.open(mods->locate("engine/resolutions.txt").c_str())) {
		while (infile.next()) {
			if (infile.key == "menu_frame_width") {
				FRAME_W = atoi(infile.val.c_str());
			} else if (infile.key == "menu_frame_height") {
				FRAME_H = atoi(infile.val.c_str());
			} else if (infile.key == "small_icon_size") {
				ICON_SIZE_SMALL = atoi(infile.val.c_str());
			} else if (infile.key == "large_icon_size") {
				ICON_SIZE_LARGE = atoi(infile.val.c_str());
			} else if (infile.key == "required_width") {
				MIN_VIEW_W = atoi(infile.val.c_str());
				if (VIEW_W < MIN_VIEW_W) VIEW_W = MIN_VIEW_W;
				VIEW_W_HALF = VIEW_W/2;
			} else if (infile.key == "required_height") {
				MIN_VIEW_H = atoi(infile.val.c_str());
				if (VIEW_H < MIN_VIEW_H) VIEW_H = MIN_VIEW_H;
				VIEW_H_HALF = VIEW_H/2;
			}
		}
		infile.close();
	}
	else {
		fprintf(stderr, "No resolutions engine settings config found!\n");
	}
	// gameplay.txt
	if (infile.open(mods->locate("engine/gameplay.txt").c_str())) {
		while (infile.next()) {
			if (infile.key == "enable_playgame") {
				ENABLE_PLAYGAME = atoi(infile.val.c_str());
			}
		}
		infile.close();
	}
	else {
		fprintf(stderr, "No gameplay engine settings config found!\n");
	}
	// combat.txt
	if (infile.open(mods->locate("engine/combat.txt").c_str())) {
		while (infile.next()) {
			if (infile.key == "max_absorb_percent") {
				MAX_ABSORB = atoi(infile.val.c_str());
			} else if (infile.key == "max_resist_percent") {
				MAX_RESIST = atoi(infile.val.c_str());
			} else if (infile.key == "max_block_percent") {
				MAX_BLOCK = atoi(infile.val.c_str());
			} else if (infile.key == "max_avoidance_percent") {
				MAX_AVOIDANCE = atoi(infile.val.c_str());
			}
		}
		infile.close();
	}
	else {
		fprintf(stderr, "No combat engine settings config found!\n");
	}
}
Пример #20
0
MenuInventory::MenuInventory(StatBlock *_stats) {
	stats = _stats;
	MAX_EQUIPPED = 4;
	MAX_CARRIED = 64;
	visible = false;
	background = loadGraphicSurface("images/menus/inventory.png");

	currency = 0;

	drag_prev_src = -1;
	changed_equipment = true;
	changed_artifact = true;
	log_msg = "";

	drop_stack.item = 0;
	drop_stack.quantity = 0;

	closeButton = new WidgetButton("images/menus/buttons/button_x.png");

	// Load config settings
	SDL_Rect equipment_slot;
	FileParser infile;
	if(infile.open("menus/inventory.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 == "equipment_slot") {
				equipment_slot.x = eatFirstInt(infile.val,',');
				equipment_slot.y = eatFirstInt(infile.val,',');
				equipment_slot.w = equipment_slot.h = eatFirstInt(infile.val,',');
				equipped_area.push_back(equipment_slot);
				slot_type.push_back(eatFirstString(infile.val,','));
			}
			else if(infile.key == "slot_name") {
				slot_desc.push_back(eatFirstString(infile.val,','));
			}
			else if(infile.key == "carried_area") {
				carried_area.x = eatFirstInt(infile.val,',');
				carried_area.y = eatFirstInt(infile.val,',');
			}
			else if (infile.key == "carried_cols") {
				carried_cols = eatFirstInt(infile.val,',');
			}
			else if (infile.key == "carried_rows") {
				carried_rows = eatFirstInt(infile.val,',');
			}
			else if (infile.key == "caption") {
				title =  eatLabelInfo(infile.val);
			}
			else if (infile.key == "currency") {
				currency_lbl =  eatLabelInfo(infile.val);
			}
			else if (infile.key == "help") {
				help_pos.x = eatFirstInt(infile.val,',');
				help_pos.y = eatFirstInt(infile.val,',');
				help_pos.w = eatFirstInt(infile.val,',');
				help_pos.h = eatFirstInt(infile.val,',');
			}
		}
		infile.close();
	}

	MAX_EQUIPPED = equipped_area.size();
	MAX_CARRIED = carried_cols * carried_rows;

	color_normal = font->getColor("menu_normal");
	color_high = font->getColor("menu_bonus");
}
Пример #21
0
SDLFontEngine::SDLFontEngine() : FontEngine(), active_font(NULL) {
	// Initiate SDL_ttf
	if(!TTF_WasInit() && TTF_Init()==-1) {
		logError("SDLFontEngine: TTF_Init: %s", TTF_GetError());
		exit(2);
	}

	// load the fonts
	// @CLASS SDLFontEngine: Font settings|Description of engine/font_settings.txt
	FileParser infile;
	if (infile.open("engine/font_settings.txt")) {
		while (infile.next()) {
			if (infile.new_section) {
				SDLFontStyle f;
				f.name = infile.section;
				font_styles.push_back(f);
			}

			if (font_styles.empty()) continue;

			SDLFontStyle *style = &(font_styles.back());
			if ((infile.key == "default" && style->path == "") || infile.key == LANGUAGE) {
				// @ATTR $STYLE.default, $STYLE.$LANGUAGE|filename (string), point size (integer), blending (boolean)|Filename, point size, and blend mode of the font to use for this language. $STYLE can be something like "font_normal" or "font_bold". $LANGUAGE can be a 2-letter region code.
				style->path = popFirstString(infile.val);
				style->ptsize = popFirstInt(infile.val);
				style->blend = toBool(popFirstString(infile.val));
				style->ttfont = TTF_OpenFont(mods->locate("fonts/" + style->path).c_str(), style->ptsize);
				if(style->ttfont == NULL) {
					logError("FontEngine: TTF_OpenFont: %s", TTF_GetError());
				}
				else {
					int lineskip = TTF_FontLineSkip(style->ttfont);
					style->line_height = lineskip;
					style->font_height = lineskip;
				}
			}
		}
		infile.close();
	}

	// set the font colors
	Color color;
	if (infile.open("engine/font_colors.txt")) {
		while (infile.next()) {
			// @ATTR menu_normal, menu_bonus, menu_penalty, widget_normal, widget_disabled|r (integer), g (integer), b (integer)|Colors for menus and widgets
			// @ATTR combat_givedmg, combat_takedmg, combat_crit, combat_buff, combat_miss|r (integer), g (integer), b (integer)|Colors for combat text
			// @ATTR requirements_not_met, item_bonus, item_penalty, item_flavor|r (integer), g (integer), b (integer)|Colors for tooltips
			// @ATTR item_$QUALITY|r (integer), g (integer), b (integer)|Colors for item quality. $QUALITY should match qualities used in items/items.txt
			color_map[infile.key] = toRGB(infile.val);
		}
		infile.close();
	}

	// Attempt to set the default active font
	setFont("font_regular");
	if (!active_font) {
		logError("FontEngine: Unable to determine default font!");
		SDL_Quit();
		exit(1);
	}
}
Пример #22
0
void loadTilesetSettings() {
	// reset defaults
	UNITS_PER_PIXEL_X = 2;
	UNITS_PER_PIXEL_Y = 4;
	TILE_W = 64;
	TILE_H = 32;
	TILE_W_HALF = TILE_W/2;
	TILE_H_HALF = TILE_H/2;
	TILESET_ISOMETRIC = 0;
	TILESET_ORTHOGONAL = 1;
	TILESET_ORIENTATION = TILESET_ISOMETRIC;

	FileParser infile;
	// load tileset settings from engine config
	// @CLASS Settings: Tileset config|Description of engine/tileset_config.txt
	if (infile.open("engine/tileset_config.txt", true, "Unable to open engine/tileset_config.txt! Defaulting to 64x32 isometric tiles.")) {
		while (infile.next()) {
			if (infile.key == "tile_size") {
				// @ATTR tile_size|w (integet), h (integer)|The width and height of a tile.
				TILE_W = toInt(infile.nextValue());
				TILE_H = toInt(infile.nextValue());
				TILE_W_HALF = TILE_W /2;
				TILE_H_HALF = TILE_H /2;
			}
			else if (infile.key == "orientation") {
				// @ATTR orientation|[isometric, orthogonal]|The perspective of tiles; isometric or orthogonal.
				if (infile.val == "isometric")
					TILESET_ORIENTATION = TILESET_ISOMETRIC;
				else if (infile.val == "orthogonal")
					TILESET_ORIENTATION = TILESET_ORTHOGONAL;
			}
			else {
				infile.error("Settings: '%s' is not a valid key.", infile.key.c_str());
			}
		}
		infile.close();
	}

	// Init automatically calculated parameters
	if (TILESET_ORIENTATION == TILESET_ISOMETRIC) {
		if (TILE_W > 0 && TILE_H > 0) {
			UNITS_PER_PIXEL_X = 2.0f / TILE_W;
			UNITS_PER_PIXEL_Y = 2.0f / TILE_H;
		}
		else {
			logError("Settings: Tile dimensions must be greater than 0. Resetting to the default size of 64x32.");
			TILE_W = 64;
			TILE_H = 32;
		}
	}
	else { // TILESET_ORTHOGONAL
		if (TILE_W > 0 && TILE_H > 0) {
			UNITS_PER_PIXEL_X = 1.0f / TILE_W;
			UNITS_PER_PIXEL_Y = 1.0f / TILE_H;
		}
		else {
			logError("Settings: Tile dimensions must be greater than 0. Resetting to the default size of 64x32.");
			TILE_W = 64;
			TILE_H = 32;
		}
	}
	if (UNITS_PER_PIXEL_X == 0 || UNITS_PER_PIXEL_Y == 0) {
		logError("Settings: One of UNITS_PER_PIXEL values is zero! %dx%d", (int)UNITS_PER_PIXEL_X, (int)UNITS_PER_PIXEL_Y);
		SDL_Quit();
		exit(1);
	}
}
Пример #23
0
/**
 * Load a specific item sets file
 *
 * @param filename The (full) path and name of the file to load
 */
void ItemManager::loadSets(const std::string& filename) {
	FileParser infile;

	// @CLASS ItemManager: Sets|Definition of a item sets, items/sets.txt...
	if (!infile.open(filename, FileParser::MOD_FILE, FileParser::ERROR_NORMAL))
		return;

	bool clear_bonus = true;

	int id = 0;
	bool id_line;
	while (infile.next()) {
		if (infile.key == "id") {
			// @ATTR id|int|A uniq id for the item set.
			id_line = true;
			id = Parse::toInt(infile.val);

			if (id > 0) {
				size_t new_size = id+1;
				if (item_sets.size() <= new_size)
					item_sets.resize(new_size);
			}

			clear_bonus = true;
		}
		else id_line = false;

		if (id < 1) {
			if (id_line) infile.error("ItemManager: Item set index out of bounds 1-%d, skipping set.", INT_MAX);
			continue;
		}
		if (id_line) continue;

		assert(item_sets.size() > std::size_t(id));

		if (infile.key == "name") {
			// @ATTR name|string|Name of the item set.
			item_sets[id].name = msg->get(infile.val);
		}
		else if (infile.key == "items") {
			// @ATTR items|list(item_id)|List of item id's that is part of the set.
			item_sets[id].items.clear();
			std::string item_id = Parse::popFirstString(infile.val);
			while (item_id != "") {
				int temp_id = Parse::toInt(item_id);
				if (temp_id > 0 && temp_id < static_cast<int>(items.size())) {
					items[temp_id].set = id;
					item_sets[id].items.push_back(temp_id);
				}
				else {
					const int maxsize = static_cast<int>(items.size()-1);
					infile.error("ItemManager: Item index out of bounds 1-%d, skipping item.", maxsize);
				}
				item_id = Parse::popFirstString(infile.val);
			}
		}
		else if (infile.key == "color") {
			// @ATTR color|color|A specific of color for the set.
			item_sets[id].color = Parse::toRGB(infile.val);
		}
		else if (infile.key == "bonus") {
			// @ATTR bonus|repeatable(int, string, int) : Required set item count, Stat name, Value|Bonus to append to items in the set.
			if (clear_bonus) {
				item_sets[id].bonus.clear();
				clear_bonus = false;
			}
			SetBonusData bonus;
			bonus.requirement = Parse::popFirstInt(infile.val);
			parseBonus(bonus, infile);
			item_sets[id].bonus.push_back(bonus);
		}
		else if (infile.key == "bonus_power_level") {
			// @ATTR bonus_power_level|repeatable(int, power_id, int) : Required set item count, Base power, Bonus levels|Grants bonus levels to a given base power.
			SetBonusData bonus;
			bonus.requirement = Parse::popFirstInt(infile.val);
			bonus.power_id = Parse::popFirstInt(infile.val);
			bonus.value = Parse::popFirstInt(infile.val);
			item_sets[id].bonus.push_back(bonus);
		}
		else {
			infile.error("ItemManager: '%s' is not a valid key.", infile.key.c_str());
		}
	}
	infile.close();
}
Пример #24
0
void loadMiscSettings() {
	// reset to defaults
	ELEMENTS.clear();
	EQUIP_FLAGS.clear();
	HERO_CLASSES.clear();
	FRAME_W = 0;
	FRAME_H = 0;
	IGNORE_TEXTURE_FILTER = false;
	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;
	SAVE_PREFIX = "";
	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;
	SAVE_ONLOAD = true;
	SAVE_ONEXIT = true;
	TOOLTIP_OFFSET = 0;
	TOOLTIP_WIDTH = 1;
	TOOLTIP_MARGIN = 0;
	TOOLTIP_MARGIN_NPC = 0;

	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 in 'ms' or 's'.
			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;
					logError("Settings: Currency ID below the minimum allowed value. Resetting it to %d", 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);
			// @ATTR save_onload|boolean|Save the game upon changing maps.
			else if (infile.key == "save_onload")
				SAVE_ONLOAD = toBool(infile.val);
			// @ATTR save_onexit|boolean|Save the game upon quitting to the title screen or desktop.
			else if (infile.key == "save_onexit")
				SAVE_ONEXIT = toBool(infile.val);

			else infile.error("Settings: '%s' is not a valid key.", infile.key.c_str());
		}
		infile.close();
	}

	if (SAVE_PREFIX == "") {
		logError("Settings: save_prefix not found in engine/misc.txt, setting to 'default'. This may cause save file conflicts between games that have no save_prefix.");
		SAVE_PREFIX = "default";
	}

	// @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_height|integer|Height of frame for New Game, Configuration, etc. menus.
			else if (infile.key == "menu_frame_height")
				FRAME_H = toInt(infile.val);
			// @ATTR icon_size|integer|Size of icons.
			else if (infile.key == "icon_size")
				ICON_SIZE = toInt(infile.val);
			// @ATTR required_width|integer|Minimum window/screen resolution width.
			else if (infile.key == "required_width") {
				MIN_SCREEN_W = toInt(infile.val);
			}
			// @ATTR required_height|integer|Minimum window/screen resolution height.
			else if (infile.key == "required_height") {
				MIN_SCREEN_H = toInt(infile.val);
			}
			// @ATTR virtual_height|integer|The height (in pixels) of the game's actual rendering area. The width will be resized to match the window's aspect ration, and everything will be scaled up to fill the window.
			else if (infile.key == "virtual_height") {
				VIEW_H = toInt(infile.val);
				VIEW_H_HALF = VIEW_H / 2;
			}
			// @ATTR ignore_texture_filter|boolean|If true, this ignores the "Texture Filtering" video setting and uses only nearest-neighbor scaling. This is good for games that use pixel art assets.
			else if (infile.key == "ignore_texture_filter") {
				IGNORE_TEXTURE_FILTER = toBool(infile.val);
			}
			else infile.error("Settings: '%s' is not a valid key.", infile.key.c_str());
		}
		infile.close();
	}

	// prevent the window from being too small
	if (SCREEN_W < MIN_SCREEN_W) SCREEN_W = MIN_SCREEN_W;
	if (SCREEN_H < MIN_SCREEN_H) SCREEN_H = MIN_SCREEN_H;

	// set the default virtual height if it's not defined
	if (VIEW_H == 0) {
		logError("Settings: virtual_height is undefined. Setting it to %d.", MIN_SCREEN_H);
		VIEW_H = MIN_SCREEN_H;
		VIEW_H_HALF = VIEW_H / 2;
	}

	// @CLASS Settings: Gameplay|Description of engine/gameplay.txt
	if (infile.open("engine/gameplay.txt")) {
		while (infile.next()) {
			if (infile.key == "enable_playgame") {
				// @ATTR enable_playgame|boolean|Enables the "Play Game" button on the main menu.
				ENABLE_PLAYGAME = toBool(infile.val);
			}
			else infile.error("Settings: '%s' is not a valid key.", infile.key.c_str());
		}
		infile.close();
	}

	// @CLASS Settings: Combat|Description of engine/combat.txt
	if (infile.open("engine/combat.txt")) {
		while (infile.next()) {
			// @ATTR max_absorb_percent|integer|Maximum percentage of damage that can be absorbed.
			if (infile.key == "max_absorb_percent") MAX_ABSORB = toInt(infile.val);
			// @ATTR max_resist_percent|integer|Maximum percentage of elemental damage that can be resisted.
			else if (infile.key == "max_resist_percent") MAX_RESIST = toInt(infile.val);
			// @ATTR max_block_percent|integer|Maximum percentage of damage that can be blocked.
			else if (infile.key == "max_block_percent") MAX_BLOCK = toInt(infile.val);
			// @ATTR max_avoidance_percent|integer|Maximum percentage chance that hazards can be avoided.
			else if (infile.key == "max_avoidance_percent") MAX_AVOIDANCE = toInt(infile.val);
			// @ATTR min_absorb_percent|integer|Minimum percentage of damage that can be absorbed.
			else if (infile.key == "min_absorb_percent") MIN_ABSORB = toInt(infile.val);
			// @ATTR min_resist_percent|integer|Minimum percentage of elemental damage that can be resisted.
			else if (infile.key == "min_resist_percent") MIN_RESIST = toInt(infile.val);
			// @ATTR min_block_percent|integer|Minimum percentage of damage that can be blocked.
			else if (infile.key == "min_block_percent") MIN_BLOCK = toInt(infile.val);
			// @ATTR min_avoidance_percent|integer|Minimum percentage chance that hazards can be avoided.
			else if (infile.key == "min_avoidance_percent") MIN_AVOIDANCE = toInt(infile.val);

			else infile.error("Settings: '%s' is not a valid key.", infile.key.c_str());
		}
		infile.close();
	}

	// @CLASS Settings: Elements|Description of engine/elements.txt
	if (infile.open("engine/elements.txt")) {
		Element e;
		while (infile.next()) {
			// @ATTR name|string|An identifier for this element.
			if (infile.key == "name") e.name = infile.val;
			// @ATTR description|string|The displayed name of this element.
			else if (infile.key == "description") e.description = infile.val;

			else infile.error("Settings: '%s' is not a valid key.", infile.key.c_str());

			if (e.name != "" && e.description != "") {
				ELEMENTS.push_back(e);
				e.name = e.description = "";
			}
		}
		infile.close();
	}

	// @CLASS Settings: Equip flags|Description of engine/equip_flags.txt
	if (infile.open("engine/equip_flags.txt")) {
		std::string type,description;
		type = description = "";

		while (infile.next()) {
			// @ATTR name|string|An identifier for this equip flag.
			if (infile.key == "name") type = infile.val;
			// @ATTR description|string|The displayed name of this equip flag.
			else if (infile.key == "description") description = infile.val;

			else infile.error("Settings: '%s' is not a valid key.", infile.key.c_str());

			if (type != "" && description != "") {
				EQUIP_FLAGS[type] = description;
				type = description = "";
			}
		}
		infile.close();
	}

	// @CLASS Settings: Classes|Description of engine/classes.txt
	if (infile.open("engine/classes.txt")) {
		while (infile.next()) {
			if (infile.new_section) {
				if (infile.section == "class") {
					HERO_CLASSES.push_back(HeroClass());
				}
			}

			if (infile.section != "class")
				continue;

			if (!HERO_CLASSES.empty()) {
				// @ATTR name|string|The displayed name of this class.
				if (infile.key == "name") HERO_CLASSES.back().name = infile.val;
				// @ATTR description|string|A description of this class.
				else if (infile.key == "description") HERO_CLASSES.back().description = infile.val;
				// @ATTR currency|integer|The amount of currency this class will start with.
				else if (infile.key == "currency") HERO_CLASSES.back().currency = toInt(infile.val);
				// @ATTR equipment|item (integer), ...|A list of items that are equipped when starting with this class.
				else if (infile.key == "equipment") HERO_CLASSES.back().equipment = infile.val;
				// @ATTR physical|integer|Class starts with this physical stat.
				else if (infile.key == "physical") HERO_CLASSES.back().physical = toInt(infile.val);
				// @ATTR mental|integer|Class starts with this mental stat.
				else if (infile.key == "mental") HERO_CLASSES.back().mental = toInt(infile.val);
				// @ATTR offense|integer|Class starts with this offense stat.
				else if (infile.key == "offense") HERO_CLASSES.back().offense = toInt(infile.val);
				// @ATTR defense|integer|Class starts with this defense stat.
				else if (infile.key == "defense") HERO_CLASSES.back().defense = toInt(infile.val);

				else if (infile.key == "actionbar") {
					// @ATTR actionbar|power (integer), ...|A list of powers to place in the action bar for the class.
					for (int i=0; i<12; i++) {
						HERO_CLASSES.back().hotkeys[i] = toInt(infile.nextValue());
					}
				}
				else if (infile.key == "powers") {
					// @ATTR powers|power (integer), ...|A list of powers that are unlocked when starting this class.
					std::string power;
					while ( (power = infile.nextValue()) != "") {
						HERO_CLASSES.back().powers.push_back(toInt(power));
					}
				}
				else if (infile.key == "campaign") {
					// @ATTR campaign|status (string), ...|A list of campaign statuses that are set when starting this class.
					std::string status;
					while ( (status = infile.nextValue()) != "") {
						HERO_CLASSES.back().statuses.push_back(status);
					}
				}
				// @ATTR power_tree|string|Power tree that will be loaded by MenuPowers
				else if (infile.key == "power_tree") HERO_CLASSES.back().power_tree = infile.val;

				else infile.error("Settings: '%s' is not a valid key.", infile.key.c_str());
			}
		}
		infile.close();
	}
	// Make a default hero class if none were found
	if (HERO_CLASSES.empty()) {
		HeroClass c;
		c.name = "Adventurer";
		HERO_CLASSES.push_back(c);
	}

	// @CLASS Settings: Death penalty|Description of engine/death_penalty.txt
	if (infile.open("engine/death_penalty.txt")) {
		while (infile.next()) {
			// @ATTR enable|boolean|Enable the death penalty.
			if (infile.key == "enable") DEATH_PENALTY = toBool(infile.val);
			// @ATTR permadeath|boolean|Force permadeath for all new saves.
			else if (infile.key == "permadeath") DEATH_PENALTY_PERMADEATH = toBool(infile.val);
			// @ATTR currency|integer|Remove this percentage of currency.
			else if (infile.key == "currency") DEATH_PENALTY_CURRENCY = toInt(infile.val);
			// @ATTR xp_total|integer|Remove this percentage of total XP.
			else if (infile.key == "xp_total") DEATH_PENALTY_XP = toInt(infile.val);
			// @ATTR xp_current_level|integer|Remove this percentage of the XP gained since the last level.
			else if (infile.key == "xp_current_level") DEATH_PENALTY_XP_CURRENT = toInt(infile.val);
			// @ATTR random_item|integer|Removes a random item from the player's inventory.
			else if (infile.key == "random_item") DEATH_PENALTY_ITEM = toBool(infile.val);

			else infile.error("Settings: '%s' is not a valid key.", infile.key.c_str());
		}
		infile.close();
	}

	// @CLASS Settings: Tooltips|Description of engine/tooltips.txt
	if (infile.open("engine/tooltips.txt")) {
		while (infile.next()) {
			// @ATTR tooltip_offset|integer|Offset in pixels from the origin point (usually mouse cursor).
			if (infile.key == "tooltip_offset")
				TOOLTIP_OFFSET = toInt(infile.val);
			// @ATTR tooltip_width|integer|Maximum width of tooltip in pixels.
			else if (infile.key == "tooltip_width")
				TOOLTIP_WIDTH = toInt(infile.val);
			// @ATTR tooltip_margin|integer|Padding between the text and the tooltip borders.
			else if (infile.key == "tooltip_margin")
				TOOLTIP_MARGIN = toInt(infile.val);
			// @ATTR npc_tooltip_margin|integer|Vertical offset for NPC labels.
			else if (infile.key == "npc_tooltip_margin")
				TOOLTIP_MARGIN_NPC = toInt(infile.val);
		}
		infile.close();
	}
}
Пример #25
0
StatBlock::StatBlock() {

	name = "";
	alive = true;
	corpse = false;
	hero = false;
	humanoid = false;
	hero_pos.x = hero_pos.y = -1;
	hero_alive = true;
	permadeath = false;
	transform_type = "";
	transformed = false;

	movement_type = MOVEMENT_NORMAL;
	flying = false;
	intangible = false;
	facing = true;

	// core stats
	offense_character = defense_character = physical_character = mental_character = 0;
	offense_additional = defense_additional = physical_additional = mental_additional = 0;
	physoff = physdef = mentoff = mentdef = 0;
	physment = offdef = 0;
	character_class="";
	level = 0;
	hp = maxhp = hp_per_minute = hp_ticker = 0;
	mp = maxmp = mp_per_minute = mp_ticker = 0;
	xp = 0;
	accuracy = 75;
	avoidance = 25;
	crit = 0;
	level_up = false;


	// equipment stats
	dmg_melee_min = 1;
	dmg_melee_max = 4;
	dmg_ment_min = 0;
	dmg_ment_max = 0;
	dmg_ranged_min = 0;
	dmg_ranged_max = 0;
	absorb_min = 0;
	absorb_max = 0;
	wielding_physical = false;
	wielding_mental = false;
	wielding_offense = false;

	// buff and debuff stats
	slow_duration = 0;
	slow_duration_total = 0;
	bleed_duration = 0;
	bleed_duration_total = 0;
	stun_duration = 0;
	stun_duration_total = 0;
	immobilize_duration = 0;
	immobilize_duration_total = 0;
	immunity_duration = 0;
	immunity_duration_total = 0;
	transform_duration = 0;
	transform_duration_total = 0;
	manual_untransform = false;
	haste_duration = 0;
	haste_duration_total = 0;
	hot_duration = 0;
	hot_duration_total = 0;
	hot_value = 0;
	forced_move_duration = 0;
	forced_move_duration_total = 0;
	shield_hp = 0;
	shield_hp_total = 0;
	shield_frame = 0;
	vengeance_stacks = 0;
	vengeance_frame = 0;
	cooldown_ticks = 0;
	blocking = false;

	// patrol waypoints
	waypoint_pause = 0;
	waypoint_pause_ticks = 0;

	// xp table
	// default to MAX_INT
	for (int i=0; i<MAX_CHARACTER_LEVEL; i++) {
		xp_table[i] = std::numeric_limits<int>::max();
	}
	// overwrite with data from config
	FileParser infile;
	infile.open(mods->locate("engine/xp_table.txt"));
	while(infile.next()) {
	    xp_table[atoi(infile.key.c_str()) - 1] = atoi(infile.val.c_str());
	}
	infile.close();

	loot_chance = 50;
	loot_types = vector<string>();
	loot_prob = vector<int>();
	loot_prob_sum = 0;
	teleportation = false;

	for (int i=0; i<POWERSLOT_COUNT; i++) {
		power_chance[i] = 0;
		power_index[i] = -1;
		power_cooldown[i] = 0;
		power_ticks[i] = 0;
	}
	melee_range = 64;

	melee_weapon_power = -1;
	ranged_weapon_power = -1;
	mental_weapon_power = -1;

	attunement_fire = 100;
	attunement_ice = 100;

	gold = 0;
	death_penalty = false;

	// campaign status interaction
	defeat_status = "";
	quest_loot_requires = "";
	quest_loot_not = "";
	quest_loot_id = 0;
	first_defeat_loot = 0;

	// default hero base/option
	base="male";
	head="head_short";
	portrait="male01";

	// default animations
	animations = "";

	// default animation speed
	animationSpeed = 100;

	statsLoaded = false;
	// formula numbers. Used only for hero
	hp_base = 10;
	hp_per_level = 2;
	hp_per_physical = 8;
	hp_regen_base = 10;
	hp_regen_per_level = 1;
	hp_regen_per_physical = 4;
	mp_base = 10;
	mp_per_level = 2;
	mp_per_mental = 8;
	mp_regen_base = 10;
	mp_regen_per_level = 1;
	mp_regen_per_mental = 4;
	accuracy_base = 75;
	accuracy_per_level = 1;
	accuracy_per_offense = 5;
	avoidance_base = 25;
	avoidance_per_level = 1;
	avoidance_per_defense = 5;
	crit_base = 5;
	crit_per_level = 1;
}
Пример #26
0
MenuCharacter::MenuCharacter(StatBlock *_stats) {
	stats = _stats;

	skill_points = 0;

	visible = false;
	newPowerNotification = false;

	for (int i=0; i<CSTAT_COUNT; i++) {
		cstat[i].label = new WidgetLabel();
		cstat[i].value = new WidgetLabel();
		cstat[i].hover.x = cstat[i].hover.y = 0;
		cstat[i].hover.w = cstat[i].hover.h = 0;
		cstat[i].visible = true;
	}
	for (int i=0; i<STATLIST_COUNT; i++) {
		show_stat[i] = true;
	}
	statlist_rows = 10;
	statlist_scrollbar_offset = 0;

	closeButton = new WidgetButton("images/menus/buttons/button_x.png");

	// Upgrade buttons
	for (int i=0; i<4; i++) {
		upgradeButton[i] = new WidgetButton("images/menus/buttons/upgrade.png");
		upgradeButton[i]->enabled = false;
		show_upgrade[i] = true;
	}
	physical_up = false;
	mental_up = false;
	offense_up = false;
	defense_up = false;

	// menu title
	labelCharacter = new WidgetLabel();

	// unspent points
	labelUnspent = new WidgetLabel();

	// Load config settings
	FileParser infile;
	if (infile.open("menus/character.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 == "caption") {
				title = eatLabelInfo(infile.val);
			}
			else if(infile.key == "upgrade_physical") {
				upgrade_pos[0].x = eatFirstInt(infile.val,',');
				upgrade_pos[0].y = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "upgrade_mental") {
				upgrade_pos[1].x = eatFirstInt(infile.val,',');
				upgrade_pos[1].y = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "upgrade_offense") {
				upgrade_pos[2].x = eatFirstInt(infile.val,',');
				upgrade_pos[2].y = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "upgrade_defense") {
				upgrade_pos[3].x = eatFirstInt(infile.val,',');
				upgrade_pos[3].y = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "statlist") {
				statlist_pos.x = eatFirstInt(infile.val,',');
				statlist_pos.y = eatFirstInt(infile.val,',');
			}
			else if (infile.key == "statlist_rows") {
				statlist_rows = eatFirstInt(infile.val,',');
			}
			else if (infile.key == "statlist_scrollbar_offset") {
				statlist_scrollbar_offset = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "label_name") {
				label_pos[0] = eatLabelInfo(infile.val);
				cstat[CSTAT_NAME].visible = !label_pos[0].hidden;
			}
			else if(infile.key == "label_level") {
				label_pos[1] = eatLabelInfo(infile.val);
				cstat[CSTAT_LEVEL].visible = !label_pos[1].hidden;
			}
			else if(infile.key == "label_physical") {
				label_pos[2] = eatLabelInfo(infile.val);
				cstat[CSTAT_PHYSICAL].visible = !label_pos[2].hidden;
			}
			else if(infile.key == "label_mental") {
				label_pos[3] = eatLabelInfo(infile.val);
				cstat[CSTAT_MENTAL].visible = !label_pos[3].hidden;
			}
			else if(infile.key == "label_offense") {
				label_pos[4] = eatLabelInfo(infile.val);
				cstat[CSTAT_OFFENSE].visible = !label_pos[4].hidden;
			}
			else if(infile.key == "label_defense") {
				label_pos[5] = eatLabelInfo(infile.val);
				cstat[CSTAT_DEFENSE].visible = !label_pos[5].hidden;
			}
			else if(infile.key == "name") {
				value_pos[0].x = eatFirstInt(infile.val,',');
				value_pos[0].y = eatFirstInt(infile.val,',');
				value_pos[0].w = eatFirstInt(infile.val,',');
				value_pos[0].h = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "level") {
				value_pos[1].x = eatFirstInt(infile.val,',');
				value_pos[1].y = eatFirstInt(infile.val,',');
				value_pos[1].w = eatFirstInt(infile.val,',');
				value_pos[1].h = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "physical") {
				value_pos[2].x = eatFirstInt(infile.val,',');
				value_pos[2].y = eatFirstInt(infile.val,',');
				value_pos[2].w = eatFirstInt(infile.val,',');
				value_pos[2].h = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "mental") {
				value_pos[3].x = eatFirstInt(infile.val,',');
				value_pos[3].y = eatFirstInt(infile.val,',');
				value_pos[3].w = eatFirstInt(infile.val,',');
				value_pos[3].h = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "offense") {
				value_pos[4].x = eatFirstInt(infile.val,',');
				value_pos[4].y = eatFirstInt(infile.val,',');
				value_pos[4].w = eatFirstInt(infile.val,',');
				value_pos[4].h = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "defense") {
				value_pos[5].x = eatFirstInt(infile.val,',');
				value_pos[5].y = eatFirstInt(infile.val,',');
				value_pos[5].w = eatFirstInt(infile.val,',');
				value_pos[5].h = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "unspent") {
				unspent_pos = eatLabelInfo(infile.val);
			}
			else if (infile.key == "show_upgrade_physical") {
				if (eatFirstInt(infile.val,',') == 0) show_upgrade[0] = false;
			}
			else if (infile.key == "show_upgrade_mental") {
				if (eatFirstInt(infile.val,',') == 0) show_upgrade[1] = false;
			}
			else if (infile.key == "show_upgrade_offense") {
				if (eatFirstInt(infile.val,',') == 0) show_upgrade[2] = false;
			}
			else if (infile.key == "show_upgrade_defense") {
				if (eatFirstInt(infile.val,',') == 0) show_upgrade[3] = false;
			}
			else if (infile.key == "show_maxhp") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[0] = false;
			}
			else if (infile.key == "show_hpregen") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[1] = false;
			}
			else if (infile.key == "show_maxmp") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[2] = false;
			}
			else if (infile.key == "show_mpregen") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[3] = false;
			}
			else if (infile.key == "show_accuracy") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[4] = false;
			}
			else if (infile.key == "show_avoidance") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[5] = false;
			}
			else if (infile.key == "show_melee") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[6] = false;
			}
			else if (infile.key == "show_ranged") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[7] = false;
			}
			else if (infile.key == "show_mental") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[8] = false;
			}
			else if (infile.key == "show_crit") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[9] = false;
			}
			else if (infile.key == "show_absorb") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[10] = false;
			}
			else if (infile.key == "show_poise") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[11] = false;
			}
			else if (infile.key == "show_bonus_xp") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[12] = false;
			}
			else if (infile.key == "show_bonus_currency") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[13] = false;
			}
			else if (infile.key == "show_bonus_itemfind") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[14] = false;
			}
			else if (infile.key == "show_bonus_stealth") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[15] = false;
			}
			else if (infile.key == "show_resists") {
				if (eatFirstInt(infile.val,',') == 0) show_stat[16] = false;
			}
		}
		infile.close();
	}

	// stat list
	statList = new WidgetListBox(STATLIST_COUNT-1+stats->vulnerable.size(), statlist_rows, "images/menus/buttons/listbox_char.png");
	tablist.add(statList);
	statList->can_select = false;
	statList->scrollbar_offset = statlist_scrollbar_offset;

	background = loadGraphicSurface("images/menus/character.png");
}
Пример #27
0
LootManager::LootManager(ItemManager *_items, MapRenderer *_map, StatBlock *_hero) {
	items = _items;
	map = _map; // we need to be able to read loot that drops from map containers
	hero = _hero; // we need the player's position for dropping loot in a valid spot

	tip = new WidgetTooltip();

	FileParser infile;
	// load loot animation settings from engine config file
	if (infile.open(mods->locate("engine/loot.txt").c_str())) {
		while (infile.next()) {
			infile.val = infile.val + ',';

			if (infile.key == "loot_animation") {
				animation_pos.x = eatFirstInt(infile.val, ',');
				animation_pos.y = eatFirstInt(infile.val, ',');
				animation_pos.w = eatFirstInt(infile.val, ',');
				animation_pos.h = eatFirstInt(infile.val, ',');
			} else if (infile.key == "loot_animation_offset") {
				animation_offset.x = eatFirstInt(infile.val, ',');
				animation_offset.y = eatFirstInt(infile.val, ',');
			} else if (infile.key == "tooltip_margin") {
				tooltip_margin = eatFirstInt(infile.val, ',');
			} else if (infile.key == "autopickup_range") {
				AUTOPICKUP_RANGE = eatFirstInt(infile.val, ',');
			} else if (infile.key == "autopickup_currency") {
				int currency = eatFirstInt(infile.val, ',');
				if (currency == 1)
					AUTOPICKUP_CURRENCY = true;
				else
					AUTOPICKUP_CURRENCY = false;
			} else if (infile.key == "currency_name") {
				CURRENCY = msg->get(eatFirstString(infile.val, ','));
			} else if (infile.key == "vendor_ratio") {
				VENDOR_RATIO = eatFirstInt(infile.val, ',') / 100.0f;
			} else if (infile.key == "currency_range") {
				CurrencyRange cr;
				cr.filename = eatFirstString(infile.val, ',');
				cr.low = eatFirstInt(infile.val, ',');
				cr.high = eatFirstInt(infile.val, ',');
				currency_range.push_back(cr);
			}
		}
		infile.close();
	} else fprintf(stderr, "Unable to open engine/loot.txt!\n");

	loot_flip = NULL;

	// reset current map loot
	loot.clear();

	loadGraphics();
	loot_flip = loadSfx("soundfx/flying_loot.ogg", "LootManager dropping loot");

	full_msg = false;

	if (!lootManager)
		lootManager = this;
	else
		exit(25);
	// TODO: make sure only one instance of the lootmanager is created.
}
Пример #28
0
FontEngine::FontEngine()
	: ttf(NULL)
	, active_font(NULL)
	, cursor_y(0) {
	// Initiate SDL_ttf
	if(!TTF_WasInit() && TTF_Init()==-1) {
		printf("TTF_Init: %s\n", TTF_GetError());
		exit(2);
	}

	// load the fonts
	FileParser infile;
	if (infile.open("engine/font_settings.txt")) {
		while (infile.next()) {
			infile.val = infile.val + ',';

			if (infile.new_section) {
				FontStyle f;
				f.name = infile.section;
				font_styles.push_back(f);
			}

			if (font_styles.empty()) continue;

			FontStyle *style = &(font_styles.back());
			if ((infile.key == "default" && style->path == "") || infile.key == LANGUAGE) {
				style->path = eatFirstString(infile.val,',');
				style->ptsize = eatFirstInt(infile.val,',');
				int blend = eatFirstInt(infile.val,',');
				if (blend == 1)
					style->blend = true;
				else
					style->blend = false;
				style->ttfont = TTF_OpenFont(mods->locate("fonts/" + style->path).c_str(), style->ptsize);
				if(style->ttfont == NULL) {
					printf("TTF_OpenFont: %s\n", TTF_GetError());
				}
				else {
					style->line_height = TTF_FontLineSkip(style->ttfont);
					style->font_height = TTF_FontLineSkip(style->ttfont);
				}
			}
		}
		infile.close();
	}

	// set the font colors
	// RGB values, the last value is 'unused'. For info,
	// see http://www.libsdl.org/cgi/docwiki.cgi/SDL_Color
	SDL_Color color;
	if (infile.open("engine/font_colors.txt")) {
		while (infile.next()) {
			infile.val = infile.val + ',';
			color.r = eatFirstInt(infile.val,',');
			color.g = eatFirstInt(infile.val,',');
			color.b = eatFirstInt(infile.val,',');
			color_map[infile.key] = color;
		}
		infile.close();
	}

	// Attempt to set the default active font
	setFont("font_regular");
	if (!active_font) {
		fprintf(stderr, "Unable to determine default font!\n");
		SDL_Quit();
		exit(1);
	}
}
Пример #29
0
/**
 * 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;
	int input_id = 0;
	
	if (infile.open(filename.c_str())) {
		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 = atoi(infile.val.c_str());
			}
			else if (infile.key == "type") {
				if (infile.val == "single") powers[input_id].type = POWTYPE_SINGLE;
				else if (infile.val == "effect") powers[input_id].type = POWTYPE_EFFECT;
				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.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 == "icon") {
				powers[input_id].icon = atoi(infile.val.c_str());
			}
			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.key == "face") {
				if (infile.val == "true") powers[input_id].face = true;
			}
			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 if (infile.key == "beacon") {
				if (infile.val == "true") powers[input_id].beacon = true;
			}
			// power requirements
			else if (infile.key == "requires_physical_weapon") {
				if (infile.val == "true") powers[input_id].requires_physical_weapon = true;
			}
			else if (infile.key == "requires_mental_weapon") {
				if (infile.val == "true") powers[input_id].requires_mental_weapon = true;
			}
			else if (infile.key == "requires_offense_weapon") {
				if (infile.val == "true") powers[input_id].requires_offense_weapon = true;
			}
			else if (infile.key == "requires_mp") {
				powers[input_id].requires_mp = atoi(infile.val.c_str());
			}
			else if (infile.key == "requires_los") {
				if (infile.val == "true") powers[input_id].requires_los = true;
			}
			else if (infile.key == "requires_empty_target") {
				if (infile.val == "true") powers[input_id].requires_empty_target = true;
			}
			else if (infile.key == "requires_item") {
				powers[input_id].requires_item = atoi(infile.val.c_str());
			}
			else if (infile.key == "requires_targeting") {
				if (infile.val == "true") powers[input_id].requires_targeting = true;
			}
			else if (infile.key == "cooldown") {
				powers[input_id].cooldown = atoi(infile.val.c_str());
			}
			
			// animation info
			else if (infile.key == "gfx") {
				powers[input_id].gfx_index = loadGFX(infile.val);
			}
			else if (infile.key == "sfx") {
				powers[input_id].sfx_index = loadSFX(infile.val);
			}
			else if (infile.key == "rendered") {
				if (infile.val == "true") powers[input_id].rendered = true;
			}
			else if (infile.key == "directional") {
				if (infile.val == "true") powers[input_id].directional = true;
			}
			else if (infile.key == "visual_random") {
				powers[input_id].visual_random = atoi(infile.val.c_str());
			}
			else if (infile.key == "visual_option") {
				powers[input_id].visual_option = atoi(infile.val.c_str());
			}
			else if (infile.key == "aim_assist") {
				powers[input_id].aim_assist = atoi(infile.val.c_str());
			}
			else if (infile.key == "speed") {
				powers[input_id].speed = atoi(infile.val.c_str());
			}
			else if (infile.key == "lifespan") {
				powers[input_id].lifespan = atoi(infile.val.c_str());
			}
			else if (infile.key == "frame_loop") {
				powers[input_id].frame_loop = atoi(infile.val.c_str());
			}
			else if (infile.key == "frame_duration") {
				powers[input_id].frame_duration = atoi(infile.val.c_str());
			}
			else if (infile.key == "frame_size") {
				powers[input_id].frame_size.x = atoi(infile.nextValue().c_str());
				powers[input_id].frame_size.y = atoi(infile.nextValue().c_str());
			}
			else if (infile.key == "frame_offset") {
				powers[input_id].frame_offset.x = atoi(infile.nextValue().c_str());
				powers[input_id].frame_offset.y = atoi(infile.nextValue().c_str());
			}
			else if (infile.key == "floor") {
				if (infile.val == "true") powers[input_id].floor = true;
			}
			else if (infile.key == "active_frame") {
				powers[input_id].active_frame = atoi(infile.val.c_str());
			}
			else if (infile.key == "complete_animation") {
				if (infile.val == "true") powers[input_id].complete_animation = true;
			}
			
			// hazard traits
			else if (infile.key == "use_hazard") {
				if (infile.val == "true") powers[input_id].use_hazard = true;
			}
			else if (infile.key == "no_attack") {
				if (infile.val == "true") powers[input_id].no_attack = true;
			}
			else if (infile.key == "radius") {
				powers[input_id].radius = atoi(infile.val.c_str());
			}
			else if (infile.key == "base_damage") {
				if (infile.val == "none")
					powers[input_id].base_damage = BASE_DAMAGE_NONE;
				else if (infile.val == "melee")
					powers[input_id].base_damage = BASE_DAMAGE_MELEE;
				else if (infile.val == "ranged")
					powers[input_id].base_damage = BASE_DAMAGE_RANGED;
				else if (infile.val == "ment")
					powers[input_id].base_damage = BASE_DAMAGE_MENT;
			}
			else if (infile.key == "damage_multiplier") {
				powers[input_id].damage_multiplier = atoi(infile.val.c_str());
			}
			else if (infile.key == "starting_pos") {
				if (infile.val == "source")
					powers[input_id].starting_pos = STARTING_POS_SOURCE;
				else if (infile.val == "target")
					powers[input_id].starting_pos = STARTING_POS_TARGET;
				else if (infile.val == "melee")
					powers[input_id].starting_pos = STARTING_POS_MELEE;
			}
			else if (infile.key == "multitarget") {
				if (infile.val == "true") powers[input_id].multitarget = true;
			}
			else if (infile.key == "trait_armor_penetration") {
				if (infile.val == "true") powers[input_id].trait_armor_penetration = true;
			}
			else if (infile.key == "trait_crits_impaired") {
				powers[input_id].trait_crits_impaired = atoi(infile.val.c_str());
			}
			else if (infile.key == "trait_elemental") {
				if (infile.val == "wood") powers[input_id].trait_elemental = ELEMENT_WOOD;
				else if (infile.val == "metal") powers[input_id].trait_elemental = ELEMENT_METAL;
				else if (infile.val == "wind") powers[input_id].trait_elemental = ELEMENT_WIND;
				else if (infile.val == "water") powers[input_id].trait_elemental = ELEMENT_WATER;
				else if (infile.val == "earth") powers[input_id].trait_elemental = ELEMENT_EARTH;
				else if (infile.val == "fire") powers[input_id].trait_elemental = ELEMENT_FIRE;
				else if (infile.val == "shadow") powers[input_id].trait_elemental = ELEMENT_SHADOW;
				else if (infile.val == "light") powers[input_id].trait_elemental = ELEMENT_LIGHT;
			}
			else if (infile.key == "forced_move") {
				powers[input_id].forced_move_speed = atoi(infile.nextValue().c_str());
				powers[input_id].forced_move_duration = atoi(infile.nextValue().c_str());
			}
			//steal effects
			else if (infile.key == "hp_steal") {
				powers[input_id].hp_steal = atoi(infile.val.c_str());
			}
			else if (infile.key == "mp_steal") {
				powers[input_id].mp_steal = atoi(infile.val.c_str());
			}
			//missile modifiers
			else if (infile.key == "missile_num") {
				powers[input_id].missile_num = atoi(infile.val.c_str());
			}
			else if (infile.key == "missile_angle") {
				powers[input_id].missile_angle = atoi(infile.val.c_str());
			}
			else if (infile.key == "angle_variance") {
				powers[input_id].angle_variance = atoi(infile.val.c_str());
			}
			else if (infile.key == "speed_variance") {
				powers[input_id].speed_variance = atoi(infile.val.c_str());
			}
			//repeater modifiers
			else if (infile.key == "delay") {
				powers[input_id].delay = atoi(infile.val.c_str());
			}
			else if (infile.key == "start_frame") {
				powers[input_id].start_frame = atoi(infile.val.c_str());
			}
			else if (infile.key == "repeater_num") {
				powers[input_id].repeater_num = atoi(infile.val.c_str());
			}
			// buff/debuff durations
			else if (infile.key == "bleed_duration") {
				powers[input_id].bleed_duration = atoi(infile.val.c_str());
			}
			else if (infile.key == "stun_duration") {
				powers[input_id].stun_duration = atoi(infile.val.c_str());
			}
			else if (infile.key == "slow_duration") {
				powers[input_id].slow_duration = atoi(infile.val.c_str());
			}
			else if (infile.key == "immobilize_duration") {
				powers[input_id].immobilize_duration = atoi(infile.val.c_str());
			}
			else if (infile.key == "immunity_duration") {
				powers[input_id].immunity_duration = atoi(infile.val.c_str());
			}
			else if (infile.key == "haste_duration") {
				powers[input_id].haste_duration = atoi(infile.val.c_str());
			}
			else if (infile.key == "hot_duration") {
				powers[input_id].hot_duration = atoi(infile.val.c_str());
			}
			else if (infile.key == "hot_value") {
				powers[input_id].hot_value = atoi(infile.val.c_str());
			}
			
			// buffs
			else if (infile.key == "buff_heal") {
				if (infile.val == "true") powers[input_id].buff_heal = true;
			}
			else if (infile.key == "buff_shield") {
				if (infile.val == "true") powers[input_id].buff_shield = true;
			}
			else if (infile.key == "buff_teleport") {
				if (infile.val == "true") powers[input_id].buff_teleport = true;
			}
			else if (infile.key == "buff_immunity") {
				if (infile.val == "true") powers[input_id].buff_immunity = true;
			}
			else if (infile.key == "buff_restore_hp") {
				powers[input_id].buff_restore_hp = atoi(infile.val.c_str());
			}
			else if (infile.key == "buff_restore_mp") {
				powers[input_id].buff_restore_mp = atoi(infile.val.c_str());
			}
			
			// pre and post power effects
			else if (infile.key == "post_power") {
				powers[input_id].post_power = atoi(infile.val.c_str());
			}
			else if (infile.key == "wall_power") {
				powers[input_id].wall_power = atoi(infile.val.c_str());
			}
			else if (infile.key == "allow_power_mod") {
				if (infile.val == "true") powers[input_id].allow_power_mod = true;
			}
			
			// spawn info
			else if (infile.key == "spawn_type") {
				powers[input_id].spawn_type = infile.val;
			}
		}
		infile.close();
	}
}
Пример #30
0
MenuCharacter::MenuCharacter(StatBlock *_stats) {
	stats = _stats;

	skill_points = 0;

	visible = false;
	newPowerNotification = false;

	for (int i=0; i<CSTAT_COUNT; i++) {
		cstat[i].label = new WidgetLabel();
		cstat[i].value = new WidgetLabel();
		cstat[i].hover.x = cstat[i].hover.y = 0;
		cstat[i].hover.w = cstat[i].hover.h = 0;
		cstat[i].visible = true;
	}
	for (int i=0; i<14; i++) {
		show_stat[i] = true;
	}

	closeButton = new WidgetButton(mods->locate("images/menus/buttons/button_x.png"));

	// Upgrade buttons
	for (int i=0; i<4; i++) {
		upgradeButton[i] = new WidgetButton(mods->locate("images/menus/buttons/upgrade.png"));
		upgradeButton[i]->enabled = false;
		show_upgrade[i] = true;
	}
	physical_up = false;
	mental_up = false;
	offense_up = false;
	defense_up = false;

	// menu title
	labelCharacter = new WidgetLabel();

	// stat list
	statList = new WidgetListBox(13+stats->vulnerable.size(), 10, mods->locate("images/menus/buttons/listbox_char.png"));

	// Load config settings
	FileParser infile;
	if(infile.open(mods->locate("menus/character.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 == "caption") {
				title = eatLabelInfo(infile.val);
			} else if(infile.key == "upgrade_physical") {
				upgrade_pos[0].x = eatFirstInt(infile.val,',');
				upgrade_pos[0].y = eatFirstInt(infile.val,',');
			} else if(infile.key == "upgrade_mental") {
				upgrade_pos[1].x = eatFirstInt(infile.val,',');
				upgrade_pos[1].y = eatFirstInt(infile.val,',');
			} else if(infile.key == "upgrade_offense") {
				upgrade_pos[2].x = eatFirstInt(infile.val,',');
				upgrade_pos[2].y = eatFirstInt(infile.val,',');
			} else if(infile.key == "upgrade_defense") {
				upgrade_pos[3].x = eatFirstInt(infile.val,',');
				upgrade_pos[3].y = eatFirstInt(infile.val,',');
			} else if(infile.key == "statlist") {
				statlist_pos.x = eatFirstInt(infile.val,',');
				statlist_pos.y = eatFirstInt(infile.val,',');
			} else if(infile.key == "label_name") {
				label_pos[0] = eatLabelInfo(infile.val);
				cstat[CSTAT_NAME].visible = !label_pos[0].hidden;
			} else if(infile.key == "label_level") {
				label_pos[1] = eatLabelInfo(infile.val);
				cstat[CSTAT_LEVEL].visible = !label_pos[1].hidden;
			} else if(infile.key == "label_physical") {
				label_pos[2] = eatLabelInfo(infile.val);
				cstat[CSTAT_PHYSICAL].visible = !label_pos[2].hidden;
			} else if(infile.key == "label_mental") {
				label_pos[3] = eatLabelInfo(infile.val);
				cstat[CSTAT_MENTAL].visible = !label_pos[3].hidden;
			} else if(infile.key == "label_offense") {
				label_pos[4] = eatLabelInfo(infile.val);
				cstat[CSTAT_OFFENSE].visible = !label_pos[4].hidden;
			} else if(infile.key == "label_defense") {
				label_pos[5] = eatLabelInfo(infile.val);
				cstat[CSTAT_DEFENSE].visible = !label_pos[5].hidden;
			} else if(infile.key == "name") {
				value_pos[0].x = eatFirstInt(infile.val,',');
				value_pos[0].y = eatFirstInt(infile.val,',');
				value_pos[0].w = eatFirstInt(infile.val,',');
				value_pos[0].h = eatFirstInt(infile.val,',');
			} else if(infile.key == "level") {
				value_pos[1].x = eatFirstInt(infile.val,',');
				value_pos[1].y = eatFirstInt(infile.val,',');
				value_pos[1].w = eatFirstInt(infile.val,',');
				value_pos[1].h = eatFirstInt(infile.val,',');
			} else if(infile.key == "physical") {
				value_pos[2].x = eatFirstInt(infile.val,',');
				value_pos[2].y = eatFirstInt(infile.val,',');
				value_pos[2].w = eatFirstInt(infile.val,',');
				value_pos[2].h = eatFirstInt(infile.val,',');
			} else if(infile.key == "mental") {
				value_pos[3].x = eatFirstInt(infile.val,',');
				value_pos[3].y = eatFirstInt(infile.val,',');
				value_pos[3].w = eatFirstInt(infile.val,',');
				value_pos[3].h = eatFirstInt(infile.val,',');
			} else if(infile.key == "offense") {
				value_pos[4].x = eatFirstInt(infile.val,',');
				value_pos[4].y = eatFirstInt(infile.val,',');
				value_pos[4].w = eatFirstInt(infile.val,',');
				value_pos[4].h = eatFirstInt(infile.val,',');
			} else if(infile.key == "defense") {
				value_pos[5].x = eatFirstInt(infile.val,',');
				value_pos[5].y = eatFirstInt(infile.val,',');
				value_pos[5].w = eatFirstInt(infile.val,',');
				value_pos[5].h = eatFirstInt(infile.val,',');
			} else if(infile.key == "unspent") {
				value_pos[6].x = eatFirstInt(infile.val,',');
				value_pos[6].y = eatFirstInt(infile.val,',');
				value_pos[6].w = eatFirstInt(infile.val,',');
				value_pos[6].h = eatFirstInt(infile.val,',');
			} else if (infile.key == "show_unspent"){
				if (eatFirstInt(infile.val,',') == 0) cstat[CSTAT_UNSPENT].visible = false;
			} else if (infile.key == "show_upgrade_physical"){
				if (eatFirstInt(infile.val,',') == 0) show_upgrade[0] = false;
			} else if (infile.key == "show_upgrade_mental"){
				if (eatFirstInt(infile.val,',') == 0) show_upgrade[1] = false;
			} else if (infile.key == "show_upgrade_offense"){
				if (eatFirstInt(infile.val,',') == 0) show_upgrade[2] = false;
			} else if (infile.key == "show_upgrade_defense"){
				if (eatFirstInt(infile.val,',') == 0) show_upgrade[3] = false;
			} else if (infile.key == "show_maxhp"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[0] = false;
			} else if (infile.key == "show_hpregen"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[1] = false;
			} else if (infile.key == "show_maxmp"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[2] = false;
			} else if (infile.key == "show_mpregen"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[3] = false;
			} else if (infile.key == "show_accuracy_v1"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[4] = false;
			} else if (infile.key == "show_accuracy_v5"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[5] = false;
			} else if (infile.key == "show_avoidance_v1"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[6] = false;
			} else if (infile.key == "show_avoidance_v5"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[7] = false;
			} else if (infile.key == "show_melee"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[8] = false;
			} else if (infile.key == "show_ranged"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[9] = false;
			} else if (infile.key == "show_mental"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[10] = false;
			} else if (infile.key == "show_crit"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[11] = false;
			} else if (infile.key == "show_absorb"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[12] = false;
			} else if (infile.key == "show_resists"){
				if (eatFirstInt(infile.val,',') == 0) show_stat[13] = false;
			}
		}
		infile.close();
	} else fprintf(stderr, "Unable to open menus/character.txt!\n");

	loadGraphics();
}