void GameStateLoad::readGameSlot(int slot) {

	stringstream filename;
	FileParser infile;

	// abort if not a valid slot number
	if (slot < 0 || slot >= GAME_SLOT_MAX) return;

	// save slots are named save#.txt
	filename << PATH_USER;
	if (GAME_PREFIX.length() > 0)
		filename << GAME_PREFIX << "_";
	filename << "save" << (slot+1) << ".txt";

	if (!infile.open(filename.str(),false, true, "")) return;

	while (infile.next()) {

		// load (key=value) pairs
		if (infile.key == "name")
			stats[slot].name = infile.val;
		else if (infile.key == "class")
			stats[slot].character_class = infile.val;
		else if (infile.key == "xp")
			stats[slot].xp = atoi(infile.val.c_str());
		else if (infile.key == "build") {
			stats[slot].physical_character = atoi(infile.nextValue().c_str());
			stats[slot].mental_character = atoi(infile.nextValue().c_str());
			stats[slot].offense_character = atoi(infile.nextValue().c_str());
			stats[slot].defense_character = atoi(infile.nextValue().c_str());
		}
		else if (infile.key == "equipped") {
			string repeat_val = infile.nextValue();
			while (repeat_val != "") {
				equipped[slot].push_back(toInt(repeat_val));
				repeat_val = infile.nextValue();
			}
		}
		else if (infile.key == "option") {
			stats[slot].base = infile.nextValue();
			stats[slot].head = infile.nextValue();
			stats[slot].portrait = infile.nextValue();
		}
		else if (infile.key == "spawn") {
			current_map[slot] = getMapName(infile.nextValue());
		}
		else if (infile.key == "permadeath") {
			stats[slot].permadeath = (toInt(infile.val) == 1);
		}
	}
	infile.close();

	stats[slot].recalc();
	loadPreview(slot);

}
Пример #2
0
void MenuActionBar::update() {

	// Read data from config file
	FileParser infile;

	if (infile.open(mods->locate("menus/actionbar.txt"))) {
	  while (infile.next()) {
		infile.val = infile.val + ',';

		if (infile.key == "slot1") {
			slots[0].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[0].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[0].w = eatFirstInt(infile.val, ',');
			slots[0].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "slot2") {
			slots[1].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[1].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[1].w = eatFirstInt(infile.val, ',');
			slots[1].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "slot3") {
			slots[2].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[2].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[2].w = eatFirstInt(infile.val, ',');
			slots[2].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "slot4") {
			slots[3].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[3].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[3].w = eatFirstInt(infile.val, ',');
			slots[3].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "slot5") {
			slots[4].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[4].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[4].w = eatFirstInt(infile.val, ',');
			slots[4].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "slot6") {
			slots[5].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[5].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[5].w = eatFirstInt(infile.val, ',');
			slots[5].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "slot7") {
			slots[6].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[6].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[6].w = eatFirstInt(infile.val, ',');
			slots[6].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "slot8") {
			slots[7].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[7].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[7].w = eatFirstInt(infile.val, ',');
			slots[7].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "slot9") {
			slots[8].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[8].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[8].w = eatFirstInt(infile.val, ',');
			slots[8].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "slot10") {
			slots[9].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[9].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[9].w = eatFirstInt(infile.val, ',');
			slots[9].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "slot_M1") {
			slots[10].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[10].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[10].w = eatFirstInt(infile.val, ',');
			slots[10].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "slot_M2") {
			slots[11].x = window_area.x+eatFirstInt(infile.val, ',');
			slots[11].y = window_area.y+eatFirstInt(infile.val, ',');
			slots[11].w = eatFirstInt(infile.val, ',');
			slots[11].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "char_menu") {
			menus[0].x = window_area.x+eatFirstInt(infile.val, ',');
			menus[0].y = window_area.y+eatFirstInt(infile.val, ',');
			menus[0].w = eatFirstInt(infile.val, ',');
			menus[0].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "inv_menu") {
			menus[1].x = window_area.x+eatFirstInt(infile.val, ',');
			menus[1].y = window_area.y+eatFirstInt(infile.val, ',');
			menus[1].w = eatFirstInt(infile.val, ',');
			menus[1].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "powers_menu") {
			menus[2].x = window_area.x+eatFirstInt(infile.val, ',');
			menus[2].y = window_area.y+eatFirstInt(infile.val, ',');
			menus[2].w = eatFirstInt(infile.val, ',');
			menus[2].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "log_menu") {
			menus[3].x = window_area.x+eatFirstInt(infile.val, ',');
			menus[3].y = window_area.y+eatFirstInt(infile.val, ',');
			menus[3].w = eatFirstInt(infile.val, ',');
			menus[3].h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "numberArea") {
			numberArea.x = window_area.x+eatFirstInt(infile.val, ',');
			numberArea.w = eatFirstInt(infile.val, ',');
			numberArea.h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "mouseArea") {
			mouseArea.x = window_area.x+eatFirstInt(infile.val, ',');
			mouseArea.w = eatFirstInt(infile.val, ',');
			mouseArea.h = eatFirstInt(infile.val, ',');
		} else if (infile.key == "menuArea") {
			menuArea.x = window_area.x+eatFirstInt(infile.val, ',');
			menuArea.w = eatFirstInt(infile.val, ',');
			menuArea.h = eatFirstInt(infile.val, ',');
		}

	  }
	  infile.close();
	} else fprintf(stderr, "Unable to open menus/actionbar.txt!\n");

	// screen areas occupied by the three main sections
	numberArea.y = mouseArea.y = menuArea.y = window_area.y;

	// set keybinding labels
	for (unsigned int i=0; i<10; i++) {
		if (inpt->binding[i+6] < 8)
			labels[i]->set(slots[i].x+slots[i].w, slots[i].y+slots[i].h-12, JUSTIFY_RIGHT, VALIGN_TOP, inpt->mouse_button[inpt->binding[i+6]-1], font->getColor("menu_normal"));
		else
			labels[i]->set(slots[i].x+slots[i].w, slots[i].y+slots[i].h-12, JUSTIFY_RIGHT, VALIGN_TOP, SDL_GetKeyName((SDLKey)inpt->binding[i+6]), font->getColor("menu_normal"));
	}
	for (unsigned int i=0; i<2; i++) {
		if (inpt->binding[i+20] < 8)
			labels[i+10]->set(slots[i+10].x+slots[i+10].w, slots[i+10].y+slots[i+10].h-12, JUSTIFY_RIGHT, VALIGN_TOP, inpt->mouse_button[inpt->binding[i+20]-1], font->getColor("menu_normal"));
		else
			labels[i+10]->set(slots[i+10].x+slots[i+10].w, slots[i+10].y+slots[i+10].h-12, JUSTIFY_RIGHT, VALIGN_TOP, SDL_GetKeyName((SDLKey)inpt->binding[i+20]), font->getColor("menu_normal"));
	}
	for (unsigned int i=0; i<4; i++) {
		if (inpt->binding[i+16] < 8)
			labels[i+12]->set(menus[i].x+menus[i].w, menus[i].y+menus[i].h-12, JUSTIFY_RIGHT, VALIGN_TOP, inpt->mouse_button[inpt->binding[i+16]-1], font->getColor("menu_normal"));
		else
			labels[i+12]->set(menus[i].x+menus[i].w, menus[i].y+menus[i].h-12, JUSTIFY_RIGHT, VALIGN_TOP, SDL_GetKeyName((SDLKey)inpt->binding[i+16]), font->getColor("menu_normal"));
	}
}
Пример #3
0
GameStateNew::GameStateNew() : GameState() {
	game_slot = 0;
	current_option = 0;
	option_count = 0;
	tip_buf.clear();
	modified_name = false;

	// set up buttons
	button_exit = new WidgetButton("images/menus/buttons/button_default.png");
	button_exit->label = msg->get("Cancel");
	button_exit->pos.x = VIEW_W_HALF - button_exit->pos.w;
	button_exit->pos.y = VIEW_H - button_exit->pos.h;
	button_exit->refresh();

	button_create = new WidgetButton("images/menus/buttons/button_default.png");
	button_create->label = msg->get("Create");
	button_create->pos.x = VIEW_W_HALF;
	button_create->pos.y = VIEW_H - button_create->pos.h;
	button_create->enabled = false;
	button_create->refresh();

	button_prev = new WidgetButton("images/menus/buttons/left.png");
	button_next = new WidgetButton("images/menus/buttons/right.png");
	input_name = new WidgetInput();
	button_permadeath = new WidgetCheckBox("images/menus/buttons/checkbox_default.png");
	if (DEATH_PENALTY_PERMADEATH) {
		button_permadeath->enabled = false;
		button_permadeath->Check();
	}

	class_list = new WidgetListBox (HERO_CLASSES.size(), 12, "images/menus/buttons/listbox_default.png");
	class_list->can_deselect = false;
	class_list->selected[0] = true;

	show_classlist = true;

	tip = new WidgetTooltip();

	// Read positions from config file
	FileParser infile;

	if (infile.open("menus/gamenew.txt")) {
		while (infile.next()) {
			infile.val = infile.val + ',';

			if (infile.key == "button_prev") {
				button_prev->pos.x = eatFirstInt(infile.val, ',');
				button_prev->pos.y = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "button_next") {
				button_next->pos.x = eatFirstInt(infile.val, ',');
				button_next->pos.y = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "button_permadeath") {
				button_permadeath->pos.x = eatFirstInt(infile.val, ',');
				button_permadeath->pos.y = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "name_input") {
				name_pos.x = eatFirstInt(infile.val, ',');
				name_pos.y = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "portrait_label") {
				portrait_label = eatLabelInfo(infile.val);
			}
			else if (infile.key == "name_label") {
				name_label = eatLabelInfo(infile.val);
			}
			else if (infile.key == "permadeath_label") {
				permadeath_label = eatLabelInfo(infile.val);
			}
			else if (infile.key == "classlist_label") {
				classlist_label = eatLabelInfo(infile.val);
			}
			else if (infile.key == "portrait") {
				portrait_pos.x = eatFirstInt(infile.val, ',');
				portrait_pos.y = eatFirstInt(infile.val, ',');
				portrait_pos.w = eatFirstInt(infile.val, ',');
				portrait_pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "class_list") {
				class_list->pos.x = eatFirstInt(infile.val, ',');
				class_list->pos.y = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "show_classlist") {
				int show_cl = eatFirstInt(infile.val, ',');
				if (show_cl == 1)
					show_classlist = true;
				else
					show_classlist = false;
			}
		}
		infile.close();
	}

	button_prev->pos.x += (VIEW_W - FRAME_W)/2;
	button_prev->pos.y += (VIEW_H - FRAME_H)/2;

	button_next->pos.x += (VIEW_W - FRAME_W)/2;
	button_next->pos.y += (VIEW_H - FRAME_H)/2;

	class_list->pos.x += (VIEW_W - FRAME_W)/2;
	class_list->pos.y += (VIEW_H - FRAME_H)/2;

	name_pos.x += (VIEW_W - FRAME_W)/2;
	name_pos.y += (VIEW_H - FRAME_H)/2;

	input_name->setPosition(name_pos.x, name_pos.y);

	button_permadeath->pos.x += (VIEW_W - FRAME_W)/2;
	button_permadeath->pos.y += (VIEW_H - FRAME_H)/2;

	portrait_label.x += (VIEW_W - FRAME_W)/2;
	portrait_label.y += (VIEW_H - FRAME_H)/2;

	name_label.x += (VIEW_W - FRAME_W)/2;
	name_label.y += (VIEW_H - FRAME_H)/2;

	permadeath_label.x += (VIEW_W - FRAME_W)/2;
	permadeath_label.y += (VIEW_H - FRAME_H)/2;

	classlist_label.x += (VIEW_W - FRAME_W)/2;
	classlist_label.y += (VIEW_H - FRAME_H)/2;

	// set up labels
	color_normal = font->getColor("menu_normal");
	label_portrait = new WidgetLabel();
	label_portrait->set(portrait_label.x, portrait_label.y, portrait_label.justify, portrait_label.valign, msg->get("Choose a Portrait"), color_normal, portrait_label.font_style);
	label_name = new WidgetLabel();
	label_name->set(name_label.x, name_label.y, name_label.justify, name_label.valign, msg->get("Choose a Name"), color_normal, name_label.font_style);
	label_permadeath = new WidgetLabel();
	label_permadeath->set(permadeath_label.x, permadeath_label.y, permadeath_label.justify, permadeath_label.valign, msg->get("Permadeath?"), color_normal, permadeath_label.font_style);
	label_classlist = new WidgetLabel();
	label_classlist->set(classlist_label.x, classlist_label.y, classlist_label.justify, classlist_label.valign, msg->get("Choose a Class"), color_normal, classlist_label.font_style);

	// set up class list
	for (unsigned i=0; i<HERO_CLASSES.size(); i++) {
		class_list->append(msg->get(HERO_CLASSES[i].name),getClassTooltip(i));
	}

	loadGraphics();
	loadOptions("hero_options.txt");
	loadPortrait(portrait[0]);
	setName(name[0]);

	// Set up tab list
	tablist.add(button_exit);
	tablist.add(button_create);
	tablist.add(button_permadeath);
	tablist.add(button_prev);
	tablist.add(button_next);
	tablist.add(class_list);
}
Пример #4
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] = powers->verifyID(num, &infile);
		// @ATTR power_melee_ment|integer|Power index for the mental melee power.
		else if (infile.key == "power_melee_ment") power_index[MELEE_MENT] = powers->verifyID(num, &infile);
		// @ATTR power_ranged_phys|integer|Power index for the physical ranged power.
		else if (infile.key == "power_ranged_phys") power_index[RANGED_PHYS] = powers->verifyID(num, &infile);
		// @ATTR power_ranged_ment|integer|Power index for the mental ranged power.
		else if (infile.key == "power_ranged_ment") power_index[RANGED_MENT] = powers->verifyID(num, &infile);
		// @ATTR power_beacon|integer|Power index of a "beacon" power used to aggro nearby creatures.
		else if (infile.key == "power_beacon") power_index[BEACON] = powers->verifyID(num, &infile);
		// @ATTR power_on_hit|integer|Power index that is triggered when hit.
		else if (infile.key == "power_on_hit") power_index[ON_HIT] = powers->verifyID(num, &infile);
		// @ATTR power_on_death|integer|Power index that is triggered when dead.
		else if (infile.key == "power_on_death") power_index[ON_DEATH] = powers->verifyID(num, &infile);
		// @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] = powers->verifyID(num, &infile);
		// @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] = powers->verifyID(num, &infile);
		// @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] = powers->verifyID(num, &infile);
		// @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();
}
Пример #5
0
GameStateConfig::GameStateConfig ()
		: GameState(),
		  child_widget(),
		  ok_button(NULL),
		  defaults_button(NULL),
		  cancel_button(NULL),
		  imgFileName(mods->locate("images/menus/config.png"))

{
	// Load background image
	SDL_Surface * tmp = IMG_Load(imgFileName.c_str());
	if (NULL == tmp) {
		fprintf(stderr, "Could not load image \"%s\" error \"%s\"\n",
				imgFileName.c_str(), IMG_GetError());
		SDL_Quit();
		exit(1);
	}
	background = SDL_DisplayFormatAlpha(tmp);
	SDL_FreeSurface(tmp);

	// Initialize Widgets
	tabControl = new WidgetTabControl(5);
	ok_button = new WidgetButton(mods->locate("images/menus/buttons/button_default.png"));
	defaults_button = new WidgetButton(mods->locate("images/menus/buttons/button_default.png"));
	cancel_button = new WidgetButton(mods->locate("images/menus/buttons/button_default.png"));

	for (unsigned int i = 0; i < 41; i++) {
		 settings_lb[i] = new WidgetLabel();
	}

	for (unsigned int i = 0; i < 3; i++) {
		 settings_sl[i] = new WidgetSlider(mods->locate("images/menus/buttons/slider_default.png"));
	}

	for (unsigned int i = 0; i < 6; i++) {
		 settings_cb[i] = new WidgetCheckBox(mods->locate("images/menus/buttons/checkbox_default.png"));
	}

	for (unsigned int i = 0; i < 50; i++) {
		 settings_key[i] = new WidgetButton(mods->locate("images/menus/buttons/button_default.png"));
	}
	keyboard_layout = new WidgetComboBox(2, mods->locate("images/menus/buttons/combobox_default.png"));
	keyboard_layout->set(0, "QWERTY");
	keyboard_layout->set(1, "AZERTY");

	input_scrollbox = new WidgetScrollBox(600, 230, 780);
	input_scrollbox->pos.x = (VIEW_W - 640)/2 + 10;
	input_scrollbox->pos.y = (VIEW_H - 480)/2 + 150;
	input_scrollbox->refresh();

	settings_btn[0] = new WidgetButton(mods->locate("images/menus/buttons/up.png"));
	settings_btn[1] = new WidgetButton(mods->locate("images/menus/buttons/down.png"));
	settings_btn[2] = new WidgetButton(mods->locate("images/menus/buttons/button_default.png"));
	settings_btn[3] = new WidgetButton(mods->locate("images/menus/buttons/button_default.png"));

	// Allocate Joycticks ComboBox
	settings_cmb[0] = new WidgetComboBox(SDL_NumJoysticks(), mods->locate("images/menus/buttons/combobox_default.png"));

	// Allocate Resolution ComboBox
	int resolutions = getVideoModes();
	if (resolutions < 1) fprintf(stderr, "Unable to get resolutions list!\n");

	settings_cmb[1] = new WidgetComboBox(resolutions, mods->locate("images/menus/buttons/combobox_default.png"));

	// Allocate Languages ComboBox
	int langCount = getLanguagesNumber();
	language_ISO = new std::string[langCount];
	language_full = new std::string[langCount];
	settings_cmb[2] = new WidgetComboBox(langCount, mods->locate("images/menus/buttons/combobox_default.png"));

	// Allocate Mods ListBoxes
	vector<string> mod_dirs;
	getDirList(PATH_DATA + "mods", mod_dirs);

	settings_lstb[0] = new WidgetListBox(mod_dirs.size(), 5, mods->locate("images/menus/buttons/listbox_default.png"));
	settings_lstb[1] = new WidgetListBox(mod_dirs.size(), 5, mods->locate("images/menus/buttons/listbox_default.png"));

	//Load the menu configuration from file
	int x1;
	int y1;
	int x2;
	int y2;
	int setting_num;
	int offset_x;
	int offset_y;

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

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

			setting_num = -1;

			if (infile.key == "fullscreen") setting_num = 1;
			else if (infile.key == "mouse_move") setting_num = 2;
			else if (infile.key == "combat_text") setting_num = 3;
			else if (infile.key == "hwsurface") setting_num = 4;
			else if (infile.key == "doublebuf") setting_num = 5;
			else if (infile.key == "enable_joystick") setting_num = 6;
			else if (infile.key == "music_volume") setting_num = 7;
			else if (infile.key == "sound_volume") setting_num = 8;
			else if (infile.key == "gamma") setting_num = 9;
			else if (infile.key == "joystick_device") setting_num = 10;
			else if (infile.key == "resolution") setting_num = 11;
			else if (infile.key == "language")setting_num = 12;

			else if (infile.key == "cancel") setting_num = 13 + CANCEL;
			else if (infile.key == "accept") setting_num = 13 + ACCEPT;
			else if (infile.key == "up") setting_num = 13 + UP;
			else if (infile.key == "down") setting_num = 13 + DOWN;
			else if (infile.key == "left") setting_num = 13 + LEFT;
			else if (infile.key == "right") setting_num = 13 + RIGHT;
			else if (infile.key == "bar1") setting_num = 13 + BAR_1;
			else if (infile.key == "bar2") setting_num = 13 + BAR_2;
			else if (infile.key == "bar3") setting_num = 13 + BAR_3;
			else if (infile.key == "bar4") setting_num = 13 + BAR_4;
			else if (infile.key == "bar5") setting_num = 13 + BAR_5;
			else if (infile.key == "bar6") setting_num = 13 + BAR_6;
			else if (infile.key == "bar7") setting_num = 13 + BAR_7;
			else if (infile.key == "bar8") setting_num = 13 + BAR_8;
			else if (infile.key == "bar9") setting_num = 13 + BAR_9;
			else if (infile.key == "bar0") setting_num = 13 + BAR_0;
			else if (infile.key == "main1") setting_num = 13 + MAIN1;
			else if (infile.key == "main2") setting_num = 13 + MAIN2;
			else if (infile.key == "character") setting_num = 13 + CHARACTER;
			else if (infile.key == "inventory") setting_num = 13 + INVENTORY;
			else if (infile.key == "powers") setting_num = 13 + POWERS;
			else if (infile.key == "log") setting_num = 13 + LOG;
			else if (infile.key == "ctrl") setting_num = 13 + CTRL;
			else if (infile.key == "shift") setting_num = 13 + SHIFT;
			else if (infile.key == "delete") setting_num = 13 + DEL;
			else if (infile.key == "hws_note") setting_num = 38;
			else if (infile.key == "dbuf_note") setting_num = 39;
			else if (infile.key == "activemods") setting_num = 40;
			else if (infile.key == "inactivemods") setting_num = 41;
			else if (infile.key == "activemods_shiftup") setting_num = 42;
			else if (infile.key == "activemods_shiftdown") setting_num = 43;
			else if (infile.key == "activemods_deactivate") setting_num = 44;
			else if (infile.key == "inactivemods_activate") setting_num = 45;
			else if (infile.key == "secondary_offset") {offset_x = x1; offset_y = y1;}
			else if (infile.key == "keyboard_layout") setting_num = 46;

			if (setting_num != -1) {
				if (setting_num > 12 && setting_num < 38) {
					settings_lb[setting_num-1]->setX(x1);
					settings_lb[setting_num-1]->setY(y1);
				} else if (setting_num < 42) {
					settings_lb[setting_num-1]->setX((VIEW_W - 640)/2 + x1);
					settings_lb[setting_num-1]->setY((VIEW_H - 480)/2 + y1);
				}

				if (setting_num < 7) {
					settings_cb[setting_num-1]->pos.x = (VIEW_W - 640)/2 + x2;
					settings_cb[setting_num-1]->pos.y = (VIEW_H - 480)/2 + y2;
				} else if ((setting_num > 6) && (setting_num < 10)) {
					settings_sl[setting_num-7]->pos.x = (VIEW_W - 640)/2 + x2;
					settings_sl[setting_num-7]->pos.y = (VIEW_H - 480)/2 + y2;
				} else if ((setting_num > 9) && (setting_num < 13)) {
					settings_cmb[setting_num-10]->pos.x = (VIEW_W - 640)/2 + x2;
					settings_cmb[setting_num-10]->pos.y = (VIEW_H - 480)/2 + y2;
				} else if (setting_num > 12 && setting_num < 39) {
					settings_key[setting_num-13]->pos.x = x2;
					settings_key[setting_num-13]->pos.y = y2;
				} else if (setting_num > 39 && setting_num < 42) {
					settings_lstb[setting_num-40]->pos.x = (VIEW_W - 640)/2 + x2;
					settings_lstb[setting_num-40]->pos.y = (VIEW_H - 480)/2 + y2;
				} else if (setting_num > 41 && setting_num < 46) {
					settings_btn[setting_num-42]->pos.x = (VIEW_W - 640)/2 + x1;
					settings_btn[setting_num-42]->pos.y = (VIEW_H - 480)/2 + y1;
				} else if (setting_num == 46) {
					keyboard_layout->pos.x = (VIEW_W - 640)/2 + x1;
					keyboard_layout->pos.y = (VIEW_H - 480)/2 + y1;
				}
			}

		  }
		} else fprintf(stderr, "Unable to open config.txt!\n");
		infile.close();

	// Initialize the tab control.
	tabControl->setMainArea((VIEW_W - 640)/2, (VIEW_H - 480)/2, 640, 480);

	// Set positions of secondary key bindings
	for (unsigned int i = 25; i < 50; i++) {
		settings_key[i]->pos.x = settings_key[i-25]->pos.x + offset_x;
		settings_key[i]->pos.y = settings_key[i-25]->pos.y + offset_y;
	}

	// Define the header.
	tabControl->setTabTitle(0, msg->get("Video"));
	tabControl->setTabTitle(1, msg->get("Audio"));
	tabControl->setTabTitle(2, msg->get("Interface"));
	tabControl->setTabTitle(3, msg->get("Input"));
	tabControl->setTabTitle(4, msg->get("Mods"));
	tabControl->updateHeader();

	// Define widgets
	ok_button->label = msg->get("Ok");
	ok_button->pos.x = VIEW_W_HALF - ok_button->pos.w/2;
	ok_button->pos.y = VIEW_H - (cancel_button->pos.h*3);
	ok_button->refresh();
	child_widget.push_back(ok_button);

    defaults_button->label = msg->get("Defaults");
	defaults_button->pos.x = VIEW_W_HALF - defaults_button->pos.w/2;
	defaults_button->pos.y = VIEW_H - (cancel_button->pos.h*2);
	defaults_button->refresh();
	child_widget.push_back(defaults_button);

	cancel_button->label = msg->get("Cancel");
	cancel_button->pos.x = VIEW_W_HALF - cancel_button->pos.w/2;
	cancel_button->pos.y = VIEW_H - (cancel_button->pos.h);
	cancel_button->refresh();
	child_widget.push_back(cancel_button);

	settings_lb[0]->set(msg->get("Full Screen Mode"));
	child_widget.push_back(settings_lb[0]);
	optiontab[child_widget.size()-1] = 0;

	child_widget.push_back(settings_cb[0]);
	optiontab[child_widget.size()-1] = 0;

	settings_lb[6]->set(msg->get("Music Volume"));
	child_widget.push_back(settings_lb[6]);
	optiontab[child_widget.size()-1] = 1;

	child_widget.push_back(settings_sl[0]);
	optiontab[child_widget.size()-1] = 1;

	settings_lb[7]->set(msg->get("Sound Volume"));
	child_widget.push_back(settings_lb[7]);
	optiontab[child_widget.size()-1] = 1;

	child_widget.push_back(settings_sl[1]);
	optiontab[child_widget.size()-1] = 1;

	settings_lb[8]->set(msg->get("Gamma"));
	child_widget.push_back(settings_lb[8]);
	optiontab[child_widget.size()-1] = 0;

	child_widget.push_back(settings_sl[2]);
	optiontab[child_widget.size()-1] = 0;

	settings_lb[1]->set(msg->get("Move hero using mouse"));
	child_widget.push_back(settings_lb[1]);
	optiontab[child_widget.size()-1] = 3;

	child_widget.push_back(settings_cb[1]);
	optiontab[child_widget.size()-1] = 3;

	settings_lb[2]->set(msg->get("Show combat text"));
	child_widget.push_back(settings_lb[2]);
	optiontab[child_widget.size()-1] = 2;

	child_widget.push_back(settings_cb[2]);
	optiontab[child_widget.size()-1] = 2;

	settings_lb[3]->set(msg->get("Hardware surfaces"));
	child_widget.push_back(settings_lb[3]);
	optiontab[child_widget.size()-1] = 0;

	child_widget.push_back(settings_cb[3]);
	optiontab[child_widget.size()-1] = 0;

	settings_lb[4]->set(msg->get("Double buffering"));
	child_widget.push_back(settings_lb[4]);
	optiontab[child_widget.size()-1] = 0;

	child_widget.push_back(settings_cb[4]);
	optiontab[child_widget.size()-1] = 0;

	settings_lb[5]->set(msg->get("Use joystick"));
	child_widget.push_back(settings_lb[5]);
	optiontab[child_widget.size()-1] = 3;

	child_widget.push_back(settings_cb[5]);
	optiontab[child_widget.size()-1] = 3;

	settings_lb[37]->set(msg->get("Try disabling for performance"));
	child_widget.push_back(settings_lb[37]);
	optiontab[child_widget.size()-1] = 0;

	settings_lb[38]->set(msg->get("Try disabling for performance"));
	child_widget.push_back(settings_lb[38]);
	optiontab[child_widget.size()-1] = 0;

	//Define ComboBoxes and their Labels

	settings_lb[10]->set(msg->get("Resolution"));
	child_widget.push_back(settings_lb[10]);
	optiontab[child_widget.size()-1] = 0;

	child_widget.push_back(settings_cmb[1]);
	optiontab[child_widget.size()-1] = 0;

	settings_lb[11]->set(msg->get("Language"));
	child_widget.push_back(settings_lb[11]);
	optiontab[child_widget.size()-1] = 2;

	child_widget.push_back(settings_cmb[2]);
	optiontab[child_widget.size()-1] = 2;

	settings_lb[9]->set(msg->get("Joystick"));
	child_widget.push_back(settings_lb[9]);
	optiontab[child_widget.size()-1] = 3;

	for(int i = 0; i < SDL_NumJoysticks(); i++)
	{
		settings_cmb[0]->set(i, SDL_JoystickName(i));
	}
	child_widget.push_back(settings_cmb[0]);
	optiontab[child_widget.size()-1] = 3;

	// Add Key Binding objects
	for (unsigned int i = 12; i < 37; i++) {
		 settings_lb[i]->set(binding_name[i-12]);
		 child_widget.push_back(settings_lb[i]);
		 optiontab[child_widget.size()-1] = 3;
	}
	for (unsigned int i = 0; i < 50; i++) {
		 child_widget.push_back(settings_key[i]);
		 optiontab[child_widget.size()-1] = 3;
	}
	keyboard_layout->refresh();
	child_widget.push_back(keyboard_layout);
	optiontab[child_widget.size()-1] = 3;

	// Add ListBoxes
	settings_lb[39]->set(msg->get("Active Mods"));
	child_widget.push_back(settings_lb[39]);
	optiontab[child_widget.size()-1] = 4;

	settings_lstb[0]->multi_select = true;
	for (unsigned int i = 0; i < mods->mod_list.size() ; i++) {
		settings_lstb[0]->append(mods->mod_list[i],"");
	}
	child_widget.push_back(settings_lstb[0]);
	optiontab[child_widget.size()-1] = 4;

	settings_lb[40]->set(msg->get("Avaliable Mods"));
	child_widget.push_back(settings_lb[40]);
	optiontab[child_widget.size()-1] = 4;

	settings_lstb[1]->multi_select = true;
	for (unsigned int i = 0; i < mod_dirs.size(); i++) {
		settings_lstb[1]->append(mod_dirs[i],"");
	}
	child_widget.push_back(settings_lstb[1]);
	optiontab[child_widget.size()-1] = 4;

	// Add Button labels
	settings_btn[2]->label = msg->get("<< Deactivate");
	settings_btn[3]->label = msg->get("Activate >>");

	for (unsigned int i=0; i<4; i++) {
		settings_btn[i]->refresh();
		child_widget.push_back(settings_btn[i]);
		optiontab[child_widget.size()-1] = 4;
	}


	update();
}
Пример #6
0
MenuStatBar::MenuStatBar(short _type)
	: bar(NULL)
	, label(new WidgetLabel())
	, stat_min(0)
	, stat_cur(0)
	, stat_cur_prev(0)
	, stat_max(0)
	, orientation(HORIZONTAL)
	, custom_text_pos(false) // label will be placed in the middle of the bar
	, custom_string("")
	, bar_gfx("")
	, bar_gfx_background("")
	, type(_type)
{
	std::string type_filename;
	if (type == TYPE_HP)
		type_filename = "hp";
	else if (type == TYPE_MP)
		type_filename = "mp";
	else if (type == TYPE_XP)
		type_filename = "xp";

	// Load config settings
	FileParser infile;
	// @CLASS MenuStatBar|Description of menus/hp.txt, menus/mp.txt, menus/xp.txt
	if(!type_filename.empty() && infile.open("menus/" + type_filename + ".txt", FileParser::MOD_FILE, FileParser::ERROR_NORMAL)) {
		while(infile.next()) {
			if (parseMenuKey(infile.key, infile.val))
				continue;

			// @ATTR bar_pos|rectangle|Position and dimensions of the bar graphics.
			if(infile.key == "bar_pos") {
				bar_pos = Parse::toRect(infile.val);
			}
			// @ATTR text_pos|label|Position of the text displaying the current value of the relevant stat.
			else if(infile.key == "text_pos") {
				custom_text_pos = true;
				text_pos = Parse::popLabelInfo(infile.val);
			}
			// @ATTR orientation|bool|True is vertical orientation; false is horizontal.
			else if(infile.key == "orientation") {
				orientation = Parse::toBool(infile.val);
			}
			// @ATTR bar_gfx|filename|Filename of the image to use for the "fill" of the bar.
			else if (infile.key == "bar_gfx") {
				bar_gfx = infile.val;
			}
			// @ATTR bar_gfx_background|filename|Filename of the image to use for the base of the bar.
			else if (infile.key == "bar_gfx_background") {
				bar_gfx_background = infile.val;
			}
			// @ATTR hide_timeout|duration|Hide HP and MP bar if full mana or health, after given amount of seconds; Hide XP bar if no changes in XP points for given amount of seconds. 0 disable hiding.
			else if (infile.key == "hide_timeout") {
				timeout.setDuration(Parse::toDuration(infile.val));
			}
			else {
				infile.error("MenuStatBar: '%s' is not a valid key.", infile.key.c_str());
			}
		}
		infile.close();
	}

	loadGraphics();

	align();
}
Пример #7
0
void ItemManager::loadSets(const string& filename) {
	FileParser infile;
	if (!infile.open(filename)) {
		fprintf(stderr, "Unable to open %s!\n", filename.c_str());
		return;
	}

	int id = 0;
	bool id_line;
	while (infile.next()) {
		if (infile.key == "id") {
			id_line = true;
			id = toInt(infile.val);
			if (id > 0 && id >= (int)item_sets.size()) {
				// *2 to amortize the resizing to O(log(n)).
				item_sets.resize((2*id) + 1);
			}
		} else id_line = false;

		if (id < 1) {
			if (id_line) fprintf(stderr, "Item set index out of bounds 1-%d, skipping\n", INT_MAX);
			continue;
		}
		if (id_line) continue;

		if (infile.key == "name") {
			item_sets[id].name = msg->get(infile.val);
		}
		else if (infile.key == "items") {
			string item_id = infile.nextValue();
			while (item_id != "") {
				if (toInt(item_id) > 0) {
					items[toInt(item_id)].set = id;
					item_sets[id].items.push_back(toInt(item_id));
					item_id = infile.nextValue();
				} else fprintf(stderr, "Item index inside item set %s definition out of bounds 1-%d, skipping item\n", item_sets[id].name.c_str(), INT_MAX);
			}
		}
		else if (infile.key == "color") {
			item_sets[id].color.r = toInt(infile.nextValue());
			item_sets[id].color.g = toInt(infile.nextValue());
			item_sets[id].color.b = toInt(infile.nextValue());
		}
		else if (infile.key == "bonus") {
			Set_bonus bonus;
			bonus.requirement = toInt(infile.nextValue());
			bonus.bonus_stat = infile.nextValue();
			bonus.bonus_val = toInt(infile.nextValue());
			item_sets[id].bonus.push_back(bonus);
		}
	}
	infile.close();
}
Пример #8
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, bool locateFileName) {
	FileParser infile;

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

	bool clear_bonus = true;

	int id = 0;
	bool id_line;
	while (infile.next()) {
		if (infile.key == "id") {
			// @ATTR id|integer|A uniq id for the item set.
			id_line = true;
			id = 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|[item_id,...]|List of item id's that is part of the set.
			item_sets[id].items.clear();
			std::string item_id = infile.nextValue();
			while (item_id != "") {
				int temp_id = 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 = infile.nextValue();
			}
		}
		else if (infile.key == "color") {
			// @ATTR color|color|A specific of color for the set.
			item_sets[id].color = toRGB(infile.val);
		}
		else if (infile.key == "bonus") {
			// @ATTR bonus|[requirements (integer), bonus stat (string), bonus (integer)]|Bonus to append to items in the set.
			if (clear_bonus) {
				item_sets[id].bonus.clear();
				clear_bonus = false;
			}
			Set_bonus bonus;
			bonus.requirement = toInt(infile.nextValue());
			parseBonus(bonus, infile);
			item_sets[id].bonus.push_back(bonus);
		}
		else {
			infile.error("ItemManager: '%s' is not a valid key.", infile.key.c_str());
		}
	}
	infile.close();
}
Пример #9
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, bool locateFileName) {
	FileParser infile;

	// @CLASS ItemManager: Items|Description about the class and it usage, items/items.txt...
	if (!infile.open(filename, locateFileName))
		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|integer|An uniq id of the item used as reference from other classes.
			id_line = true;
			id = toInt(infile.val);
			addUnknownItem(id);

			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|integer|The item's level. Has no gameplay impact. (Deprecated?)
			items[id].level = toInt(infile.val);
		else if (infile.key == "icon") {
			// @ATTR icon|integer|An id for the icon to display for this item.
			items[id].icon = toInt(infile.nextValue());
		}
		else if (infile.key == "book") {
			// @ATTR book|string|A book file to open when this item is activated.
			items[id].book = infile.val;
		}
		else if (infile.key == "quality") {
			// @ATTR quality|string|Item quality matching an id in items/qualities.txt
			items[id].quality = infile.val;
		}
		else if (infile.key == "item_type") {
			// @ATTR item_type|string|Equipment slot [artifact, head, chest, hands, legs, feets, main, off, ring] or base item type [gem, consumable]
			items[id].type = infile.val;
		}
		else if (infile.key == "equip_flags") {
			// @ATTR equip_flags|flag (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 = popFirstString(infile.val);

			while (flag != "") {
				items[id].equip_flags.push_back(flag);
				flag = popFirstString(infile.val);
			}
		}
		else if (infile.key == "dmg_melee") {
			// @ATTR dmg_melee|[min (integer), max (integer)]|Defines the item melee damage, if only min is specified the melee damage is fixed.
			items[id].dmg_melee_min = toInt(infile.nextValue());
			if (infile.val.length() > 0)
				items[id].dmg_melee_max = toInt(infile.nextValue());
			else
				items[id].dmg_melee_max = items[id].dmg_melee_min;
		}
		else if (infile.key == "dmg_ranged") {
			// @ATTR dmg_ranged|[min (integer), max (integer)]|Defines the item ranged damage, if only min is specified the ranged damage is fixed.
			items[id].dmg_ranged_min = toInt(infile.nextValue());
			if (infile.val.length() > 0)
				items[id].dmg_ranged_max = toInt(infile.nextValue());
			else
				items[id].dmg_ranged_max = items[id].dmg_ranged_min;
		}
		else if (infile.key == "dmg_ment") {
			// @ATTR dmg_ment|[min (integer), max (integer)]|Defines the item mental damage, if only min is specified the ranged damage is fixed.
			items[id].dmg_ment_min = toInt(infile.nextValue());
			if (infile.val.length() > 0)
				items[id].dmg_ment_max = toInt(infile.nextValue());
			else
				items[id].dmg_ment_max = items[id].dmg_ment_min;
		}
		else if (infile.key == "abs") {
			// @ATTR abs|[min (integer), max (integer)]|Defines the item absorb value, if only min is specified the absorb value is fixed.
			items[id].abs_min = toInt(infile.nextValue());
			if (infile.val.length() > 0)
				items[id].abs_max = toInt(infile.nextValue());
			else
				items[id].abs_max = items[id].abs_min;
		}
		else if (infile.key == "requires_level") {
			// @ATTR requires_level|integer|The hero's level must match or exceed this value in order to equip this item.
			items[id].requires_level = toInt(infile.val);
		}
		else if (infile.key == "requires_stat") {
			// @ATTR requires_stat|[ [physical:mental:offense:defense], amount (integer) ]|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 = infile.nextValue();
			if (s == "physical")
				items[id].req_stat.push_back(REQUIRES_PHYS);
			else if (s == "mental")
				items[id].req_stat.push_back(REQUIRES_MENT);
			else if (s == "offense")
				items[id].req_stat.push_back(REQUIRES_OFF);
			else if (s == "defense")
				items[id].req_stat.push_back(REQUIRES_DEF);
			else
				infile.error("%s unrecognized at; requires_stat must be one of [physical:mental:offense:defense]", s.c_str());
			items[id].req_val.push_back(toInt(infile.nextValue()));
		}
		else if (infile.key == "requires_class") {
			// @ATTR requires_class|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|[stat_name (string), amount (integer)]|Adds a bonus to the item power_tag being a uniq tag of a power definition, e.: bonus=HP regen, 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 == "soundfx") {
			// @ATTR soundfx|string|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|string|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|filename (string), min quantity (int), max quantity (int)|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 = popFirstString(infile.val);
			la.low = popFirstInt(infile.val);
			la.high = 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 (toInt(infile.val) > 0)
				items[id].power = 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|old (integer), new (integer)|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 = 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|integer|The amount of currency the item costs, if set to 0 the item cannot be sold.
			items[id].price = toInt(infile.val);
		else if (infile.key == "price_per_level")
			// @ATTR price_per_level|integer|Additional price for each player level above 1
			items[id].price_per_level = toInt(infile.val);
		else if (infile.key == "price_sell")
			// @ATTR price_sell|integer|The amount of currency the item is sold for, if set to 0 the sell prices is prices*vendor_ratio.
			items[id].price_sell = toInt(infile.val);
		else if (infile.key == "max_quantity")
			// @ATTR max_quantity|integer|Max item count per stack.
			items[id].max_quantity = 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|string|Sound effect when walking, this applies only to armors.
			items[id].stepfx = infile.val;
		else if (infile.key == "disable_slots") {
			// @ATTR disable_slots|type (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 = popFirstString(infile.val);

			while (slot_type != "") {
				items[id].disable_slots.push_back(slot_type);
				slot_type = 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 = toBool(infile.val);
		}
		else {
			infile.error("ItemManager: '%s' is not a valid key.", infile.key.c_str());
		}

	}
	infile.close();
}
Пример #10
0
void LootManager::loadLootTables() {
	std::vector<std::string> filenames = mods->list("loot", false);

	for (unsigned i=0; i<filenames.size(); i++) {
		FileParser infile;
		if (!infile.open(filenames[i]))
			continue;

		std::vector<Event_Component> *ec_list = &loot_tables[filenames[i]];
		Event_Component *ec = NULL;
		bool skip_to_next = false;

		while (infile.next()) {
			if (infile.section == "") {
				if (infile.key == "loot") {
					ec_list->push_back(Event_Component());
					ec = &ec_list->back();
					parseLoot(infile, ec, ec_list);
				}
			}
			else if (infile.section == "loot") {
				if (infile.new_section) {
					ec_list->push_back(Event_Component());
					ec = &ec_list->back();
					ec->type = "loot";
					skip_to_next = false;
				}

				if (skip_to_next || ec == NULL)
					continue;

				if (infile.key == "id") {
					ec->s = infile.val;

					if (ec->s == "currency")
						ec->c = CURRENCY_ID;
					else if (toInt(ec->s, -1) != -1)
						ec->c = toInt(ec->s);
					else {
						skip_to_next = true;
						infile.error("LootManager: Invalid item id for loot.");
					}
				}
				else if (infile.key == "chance") {
					if (infile.val == "fixed")
						ec->z = 0;
					else
						ec->z = toInt(infile.val);
				}
				else if (infile.key == "quantity") {
					ec->a = toInt(infile.nextValue());
					clampFloor(ec->a, 1);
					ec->b = toInt(infile.nextValue());
					clampFloor(ec->b, ec->a);
				}
			}
		}

		infile.close();
	}
}
Пример #11
0
MenuCharacter::MenuCharacter(StatBlock *_stats) {
	stats = _stats;

	// Labels for major stats
	cstat_labels[CSTAT_NAME] = "Name";
	cstat_labels[CSTAT_LEVEL] = "Level";
	cstat_labels[CSTAT_PHYSICAL] = "Physical";
	cstat_labels[CSTAT_MENTAL] = "Mental";
	cstat_labels[CSTAT_OFFENSE] = "Offense";
	cstat_labels[CSTAT_DEFENSE] = "Defense";

	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;
	// @CLASS MenuCharacter|Description of menus/character.txt
	if (infile.open("menus/character.txt")) {
		while(infile.next()) {
			if (parseMenuKey(infile.key, infile.val))
				continue;

			// @ATTR close|x (integer), y (integer)|Position of the close button.
			if(infile.key == "close") close_pos = toPoint(infile.val);
			// @ATTR label_title|label|Position of the "Character" text.
			else if(infile.key == "label_title") title = eatLabelInfo(infile.val);
			// @ATTR upgrade_physical|x (integer), y (integer)|Position of the button used to add a stat point to Physical.
			else if(infile.key == "upgrade_physical") upgrade_pos[0] = toPoint(infile.val);
			// @ATTR upgrade_mental|x (integer), y (integer)|Position of the button used to add a stat point to Mental.
			else if(infile.key == "upgrade_mental")	upgrade_pos[1] = toPoint(infile.val);
			// @ATTR upgrade_offense|x (integer), y (integer)|Position of the button used to add a stat point to Offense.
			else if(infile.key == "upgrade_offense") upgrade_pos[2] = toPoint(infile.val);
			// @ATTR upgrade_defense|x (integer), y (integer)|Position of the button used to add a stat point to Defense.
			else if(infile.key == "upgrade_defense") upgrade_pos[3] = toPoint(infile.val);
			// @ATTR statlist|x (integer), y (integer)|Position of the scrollbox containing non-primary stats.
			else if(infile.key == "statlist") statlist_pos = toPoint(infile.val);
			// @ATTR statlist_rows|integer|The height of the statlist in rows.
			else if (infile.key == "statlist_rows") statlist_rows = toInt(infile.val);
			// @ATTR statlist_scrollbar_offset|integer|Right margin in pixels for the statlist's scrollbar.
			else if (infile.key == "statlist_scrollbar_offset") statlist_scrollbar_offset = toInt(infile.val);

			// @ATTR label_name|label|Position of the "Name" text.
			else if(infile.key == "label_name") {
				label_pos[0] = eatLabelInfo(infile.val);
				cstat[CSTAT_NAME].visible = !label_pos[0].hidden;
			}
			// @ATTR label_level|label|Position of the "Level" text.
			else if(infile.key == "label_level") {
				label_pos[1] = eatLabelInfo(infile.val);
				cstat[CSTAT_LEVEL].visible = !label_pos[1].hidden;
			}
			// @ATTR label_physical|label|Position of the "Physical" text.
			else if(infile.key == "label_physical") {
				label_pos[2] = eatLabelInfo(infile.val);
				cstat[CSTAT_PHYSICAL].visible = !label_pos[2].hidden;
			}
			// @ATTR label_mental|label|Position of the "Mental" text.
			else if(infile.key == "label_mental") {
				label_pos[3] = eatLabelInfo(infile.val);
				cstat[CSTAT_MENTAL].visible = !label_pos[3].hidden;
			}
			// @ATTR label_offense|label|Position of the "Offense" text.
			else if(infile.key == "label_offense") {
				label_pos[4] = eatLabelInfo(infile.val);
				cstat[CSTAT_OFFENSE].visible = !label_pos[4].hidden;
			}
			// @ATTR label_defense|label|Position of the "Defense" text.
			else if(infile.key == "label_defense") {
				label_pos[5] = eatLabelInfo(infile.val);
				cstat[CSTAT_DEFENSE].visible = !label_pos[5].hidden;
			}

			// @ATTR name|x (integer), y (integer), w (integer), h (integer)|Position of the player's name and dimensions of the tooltip hotspot.
			else if(infile.key == "name") value_pos[0] = toRect(infile.val);
			// @ATTR level|x (integer), y (integer), w (integer), h (integer)|Position of the player's level and dimensions of the tooltip hotspot.
			else if(infile.key == "level") value_pos[1] = toRect(infile.val);
			// @ATTR physical|x (integer), y (integer), w (integer), h (integer)|Position of the player's physical stat and dimensions of the tooltip hotspot.
			else if(infile.key == "physical") value_pos[2] = toRect(infile.val);
			// @ATTR mental|x (integer), y (integer), w (integer), h (integer)|Position of the player's mental stat and dimensions of the tooltip hotspot.
			else if(infile.key == "mental") value_pos[3] = toRect(infile.val);
			// @ATTR offense|x (integer), y (integer), w (integer), h (integer)|Position of the player's offense stat and dimensions of the tooltip hotspot.
			else if(infile.key == "offense") value_pos[4] = toRect(infile.val);
			// @ATTR defense|x (integer), y (integer), w (integer), h (integer)|Position of the player's defense stat and dimensions of the tooltip hotspot.
			else if(infile.key == "defense") value_pos[5] = toRect(infile.val);

			// @ATTR upspent|label|Position of the label showing the number of unspent stat points.
			else if(infile.key == "unspent") unspent_pos = eatLabelInfo(infile.val);

			// @ATTR show_upgrade_physical|boolean|Hide the Physical upgrade button if set to false.
			else if (infile.key == "show_upgrade_physical") show_upgrade[0] = toBool(infile.val);
			// @ATTR show_upgrade_mental|boolean|Hide the Mental upgrade button if set to false.
			else if (infile.key == "show_upgrade_mental") show_upgrade[1] = toBool(infile.val);
			// @ATTR show_upgrade_offense|boolean|Hide the Offense upgrade button if set to false.
			else if (infile.key == "show_upgrade_offense") show_upgrade[2] = toBool(infile.val);
			// @ATTR show_upgrade_defense|boolean|Hide the Defense upgrade button if set to false.
			else if (infile.key == "show_upgrade_defense") show_upgrade[3] = toBool(infile.val);

			// @ATTR show_maxhp|boolean|Hide the "Max HP" stat in the statlist if set to false.
			else if (infile.key == "show_maxhp") show_stat[0] = toBool(infile.val);
			// @ATTR show_hpregen|boolean|Hide the "HP Regen" stat in the statlist if set to false.
			else if (infile.key == "show_hpregen") show_stat[1] = toBool(infile.val);
			// @ATTR show_maxmp|boolean|Hide the "Max MP" stat in the statlist if set to false.
			else if (infile.key == "show_maxmp") show_stat[2] = toBool(infile.val);
			// @ATTR show_mpregen|boolean|Hide the "MP Regen" stat in the statlist if set to false.
			else if (infile.key == "show_mpregen") show_stat[3] = toBool(infile.val);
			// @ATTR show_accuracy|boolean|Hide the "Accuracy" stat in the statlist if set to false.
			else if (infile.key == "show_accuracy") show_stat[4] = toBool(infile.val);
			// @ATTR show_avoidance|boolean|Hide the "Avoidance" stat in the statlist if set to false.
			else if (infile.key == "show_avoidance") show_stat[5] = toBool(infile.val);
			// @ATTR show_melee|boolean|Hide the "Melee Damage" stat in the statlist if set to false.
			else if (infile.key == "show_melee") show_stat[6] = toBool(infile.val);
			// @ATTR show_ranged|boolean|Hide the "Ranged Damage" stat in the statlist if set to false.
			else if (infile.key == "show_ranged") show_stat[7] = toBool(infile.val);
			// @ATTR show_mental|boolean|Hide the "Mental Damage" stat in the statlist if set to false.
			else if (infile.key == "show_mental") show_stat[8] = toBool(infile.val);
			// @ATTR show_crit|boolean|Hide the "Crit" stat in the statlist if set to false.
			else if (infile.key == "show_crit") show_stat[9] = toBool(infile.val);
			// @ATTR show_absorb|boolean|Hide the "Absorb" stat in the statlist if set to false.
			else if (infile.key == "show_absorb") show_stat[10] = toBool(infile.val);
			// @ATTR show_poise|boolean|Hide the "Poise" stat in the statlist if set to false.
			else if (infile.key == "show_poise") show_stat[11] = toBool(infile.val);
			// @ATTR show_bonus_xp|boolean|Hide the "Bonus XP" stat in the statlist if set to false.
			else if (infile.key == "show_bonus_xp") show_stat[12] = toBool(infile.val);
			// @ATTR show_bonus_currency|boolean|Hide the "Bonus Gold" stat in the statlist if set to false.
			else if (infile.key == "show_bonus_currency") show_stat[13] = toBool(infile.val);
			// @ATTR show_bonus_itemfind|boolean|Hide the "Bonus Item Find" stat in the statlist if set to false.
			else if (infile.key == "show_bonus_itemfind") show_stat[14] = toBool(infile.val);
			// @ATTR show_bonus_stealth|boolean|Hide the "Stealth" stat in the statlist if set to false.
			else if (infile.key == "show_bonus_stealth") show_stat[15] = toBool(infile.val);
			// @ATTR show_resists|boolean|Hide the elemental "Resistance" stats in the statlist if set to false.
			else if (infile.key == "show_resists") show_stat[16] = toBool(infile.val);
		}
		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;

	setBackground("images/menus/character.png");

	align();
	alignElements();
}
Пример #12
0
void LootManager::parseLoot(FileParser &infile, Event_Component *e, std::vector<Event_Component> *ec_list) {
	if (e == NULL) return;

	std::string chance;
	bool first_is_filename = false;
	e->s = infile.nextValue();

	if (e->s == "currency")
		e->c = CURRENCY_ID;
	else if (toInt(e->s, -1) != -1)
		e->c = toInt(e->s);
	else if (ec_list) {
		// load entire loot table
		std::string filename = e->s;

		// remove the last event component, since getLootTable() will create a new one
		if (e == &ec_list->back())
			ec_list->pop_back();

		getLootTable(filename, ec_list);
		first_is_filename = true;
	}

	if (!first_is_filename) {
		// make sure the type is "loot"
		e->type = "loot";

		// drop chance
		chance = infile.nextValue();
		if (chance == "fixed") e->z = 0;
		else e->z = toInt(chance);

		// quantity min/max
		e->a = toInt(infile.nextValue());
		clampFloor(e->a, 1);
		e->b = toInt(infile.nextValue());
		clampFloor(e->b, e->a);
	}

	// add repeating loot
	if (ec_list) {
		std::string repeat_val = infile.nextValue();
		while (repeat_val != "") {
			ec_list->push_back(Event_Component());
			Event_Component *ec = &ec_list->back();
			ec->type = infile.key;

			ec->s = repeat_val;
			if (ec->s == "currency")
				ec->c = CURRENCY_ID;
			else if (toInt(ec->s, -1) != -1)
				ec->c = toInt(ec->s);
			else {
				// remove the last event component, since getLootTable() will create a new one
				ec_list->pop_back();

				getLootTable(repeat_val, ec_list);

				repeat_val = infile.nextValue();
				continue;
			}

			chance = infile.nextValue();
			if (chance == "fixed") ec->z = 0;
			else ec->z = toInt(chance);

			ec->a = toInt(infile.nextValue());
			clampFloor(ec->a, 1);
			ec->b = toInt(infile.nextValue());
			clampFloor(ec->b, ec->a);

			repeat_val = infile.nextValue();
		}
	}
}
Пример #13
0
/**
 * Load the entity's animation from animation definition file
 */
void Entity::loadAnimations(const string& filename) {

	FileParser parser;

	if (!parser.open(mods->locate(filename).c_str())) {
		cout << "Error loading animation definition file: " << filename << endl;
		SDL_Quit();
		exit(1);
	}

	string name = "";
	int position = 0;
	int frames = 0;
	int duration = 0;
	Point render_size;
	Point render_offset;
	string type = "";
	string firstAnimation = "";
	int active_frame = 0;

	// Parse the file and on each new section create an animation object from the data parsed previously

	parser.next();
	parser.new_section = false; // do not create the first animation object until parser has parsed first section

	do {
		// create the animation if finished parsing a section
		if (parser.new_section) {
			animations.push_back(new Animation(name, render_size, render_offset, position, frames, duration, type, active_frame));
		}

		if (parser.key == "position") {
			if (isInt(parser.val)) {
				position = atoi(parser.val.c_str());
			}
		}
		else if (parser.key == "frames") {
			if (isInt(parser.val)) {
				frames = atoi(parser.val.c_str());
			}
		}
		else if (parser.key == "duration") {
			if (isInt(parser.val)) {
				int ms_per_frame = atoi(parser.val.c_str());

				duration = (int)round((float)ms_per_frame / (1000.0 / (float)FRAMES_PER_SEC));

				// adjust duration according to the entity's animation speed
				duration = (duration * 100) / stats.animationSpeed;

				// TEMP: if an animation is too fast, display one frame per fps anyway
				if (duration < 1) duration=1;
			}
		}
		else if (parser.key == "type") {
			type = parser.val;
		}
		else if (parser.key == "render_size_x") {
			if (isInt(parser.val)) {
				render_size.x = atoi(parser.val.c_str());
			}
		}
		else if (parser.key == "render_size_y") {
			if (isInt(parser.val)) {
				render_size.y = atoi(parser.val.c_str());
			}
		}
		else if (parser.key == "render_offset_x") {
			if (isInt(parser.val)) {
				render_offset.x = atoi(parser.val.c_str());
			}
		}
		else if (parser.key == "render_offset_y") {
			if (isInt(parser.val)) {
				render_offset.y = atoi(parser.val.c_str());
			}
		}
		else if (parser.key == "active_frame") {
			active_frame = atoi(parser.val.c_str());
		}

		if (name == "") {
			// This is the first animation
			firstAnimation = parser.section;
		}
		name = parser.section;
	}
	while (parser.next());

	// add final animation
	animations.push_back(new Animation(name, render_size, render_offset, position, frames, duration, type, active_frame));


	// set the default animation
	if (firstAnimation != "") {
		setAnimation(firstAnimation);
	}
}
GameStateLoad::GameStateLoad() : GameState() {
	items = new ItemManager();
	portrait = NULL;
	loading_requested = false;
	loading = false;
	loaded = false;

	label_loading = new WidgetLabel();

	for (int i = 0; i < GAME_SLOT_MAX; i++) {
		label_name[i] = new WidgetLabel();
		label_level[i] = new WidgetLabel();
		label_map[i] = new WidgetLabel();
	}

	// Confirmation box to confirm deleting
	confirm = new MenuConfirm(msg->get("Delete Save"), msg->get("Delete this save?"));
	button_exit = new WidgetButton("images/menus/buttons/button_default.png");
	button_exit->label = msg->get("Exit to Title");
	button_exit->pos.x = VIEW_W_HALF - button_exit->pos.w/2;
	button_exit->pos.y = VIEW_H - button_exit->pos.h;
	button_exit->refresh();

	button_action = new WidgetButton("images/menus/buttons/button_default.png");
	button_action->label = msg->get("Choose a Slot");
	button_action->enabled = false;

	button_alternate = new WidgetButton("images/menus/buttons/button_default.png");
	button_alternate->label = msg->get("Delete Save");
	button_alternate->enabled = false;

	// Set up tab list
	tablist = TabList(HORIZONTAL);
	tablist.add(button_exit);

	// Read positions from config file
	FileParser infile;

	if (infile.open("menus/gameload.txt")) {
		while (infile.next()) {
			infile.val = infile.val + ',';

			if (infile.key == "action_button") {
				button_action->pos.x = eatFirstInt(infile.val, ',');
				button_action->pos.y = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "atlernate_button") {
				button_alternate->pos.x = eatFirstInt(infile.val, ',');
				button_alternate->pos.y = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "portrait") {
				portrait_pos.x = eatFirstInt(infile.val, ',');
				portrait_pos.y = eatFirstInt(infile.val, ',');
				portrait_pos.w = eatFirstInt(infile.val, ',');
				portrait_pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "gameslot") {
				gameslot_pos.x = eatFirstInt(infile.val, ',');
				gameslot_pos.y = eatFirstInt(infile.val, ',');
				gameslot_pos.w = eatFirstInt(infile.val, ',');
				gameslot_pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "preview") {
				preview_pos.x = eatFirstInt(infile.val, ',');
				preview_pos.y = eatFirstInt(infile.val, ',');
				preview_pos.w = eatFirstInt(infile.val, ',');
				preview_pos.h = eatFirstInt(infile.val, ',');
				// label positions within each slot
			}
			else if (infile.key == "name") {
				name_pos = eatLabelInfo(infile.val);
			}
			else if (infile.key == "level") {
				level_pos = eatLabelInfo(infile.val);
			}
			else if (infile.key == "map") {
				map_pos = eatLabelInfo(infile.val);
			}
			else if (infile.key == "loading_label") {
				loading_pos = eatLabelInfo(infile.val);
				// Position for the avatar preview image in each slot
			}
			else if (infile.key == "sprite") {
				sprites_pos.x = eatFirstInt(infile.val, ',');
				sprites_pos.y = eatFirstInt(infile.val, ',');
			}
		}
		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 + ',';
				confirm->window_area.x = eatFirstInt(infile.val, ',');
				confirm->window_area.y = eatFirstInt(infile.val, ',');
				confirm->window_area.w = eatFirstInt(infile.val, ',');
				confirm->window_area.h = eatFirstInt(infile.val, ',');
			}

			if (infile.key == "align") {
				confirm->alignment = infile.val;
			}
		}
		infile.close();
	}

	confirm->align();
	confirm->update();

	// get displayable types list
	bool found_layer = false;
	if (infile.open("engine/hero_options.txt")) {
		while(infile.next()) {
			infile.val = infile.val + ',';

			if (infile.key == "layer") {
				unsigned dir = eatFirstInt(infile.val,',');
				if (dir != 6) continue;
				else found_layer = true;

				string layer = eatFirstString(infile.val,',');
				while (layer != "") {
					preview_layer.push_back(layer);
					layer = eatFirstString(infile.val,',');
				}
			}
		}
		infile.close();
	}
	if (!found_layer) fprintf(stderr, "Warning: Could not find layers for direction 6\n");

	button_action->pos.x += (VIEW_W - FRAME_W)/2;
	button_action->pos.y += (VIEW_H - FRAME_H)/2;
	button_action->refresh();

	button_alternate->pos.x += (VIEW_W - FRAME_W)/2;
	button_alternate->pos.y += (VIEW_H - FRAME_H)/2;
	button_alternate->refresh();

	load_game = false;

	for (int i=0; i<GAME_SLOT_MAX; i++) {
		current_map[i] = "";
	}

	loadGraphics();
	readGameSlots();

	for (int i=0; i<GAME_SLOT_MAX; i++) {
		slot_pos[i].x = gameslot_pos.x + (VIEW_W - FRAME_W)/2;
		slot_pos[i].h = gameslot_pos.h;
		slot_pos[i].y = gameslot_pos.y + (VIEW_H - FRAME_H)/2 + (i * gameslot_pos.h);
		slot_pos[i].w = gameslot_pos.w;
	}

	selected_slot = -1;

	// temp
	current_frame = 0;
	frame_ticker = 0;

	color_normal = font->getColor("menu_normal");
}
Пример #15
0
void GameStateLoad::readGameSlot(int slot) {

	stringstream filename;
	FileParser infile;
	
	// abort if not a valid slot number
	if (slot < 0 || slot >= GAME_SLOT_MAX) return;

	// save slots are named save#.txt
	filename << "save" << (slot+1) << ".txt";

	if (!infile.open(PATH_USER + filename.str())) return;
	
	while (infile.next()) {
	
		// load (key=value) pairs
		if (infile.key == "name")
			stats[slot].name = infile.val;
		else if (infile.key == "xp")
			stats[slot].xp = atoi(infile.val.c_str());
		else if (infile.key == "build") {
			stats[slot].physical_character = atoi(infile.nextValue().c_str());
			stats[slot].mental_character = atoi(infile.nextValue().c_str());
			stats[slot].offense_character = atoi(infile.nextValue().c_str());
			stats[slot].defense_character = atoi(infile.nextValue().c_str());
		}
		else if (infile.key == "equipped") {
			equipped[slot][0] = atoi(infile.nextValue().c_str());
			equipped[slot][1] = atoi(infile.nextValue().c_str());
			equipped[slot][2] = atoi(infile.nextValue().c_str());
		}
		else if (infile.key == "option") {
			stats[slot].base = infile.nextValue();
			stats[slot].head = infile.nextValue();
			stats[slot].portrait = infile.nextValue();
		}
		else if (infile.key == "spawn") {
			current_map[slot] = getMapName(infile.nextValue());
		}
	}
	infile.close();
	
	stats[slot].recalc();
	loadPreview(slot);

}
Пример #16
0
/**
 * All powers are defined in powers/powers.txt
 */
void PowerManager::loadPowers() {

	FileParser infile;
	int input_id = 0;
	
	if (infile.open((PATH_DATA + "powers/powers.txt").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.key == "name") {
				powers[input_id].name = infile.val;
			}
			else if (infile.key == "description") {
				powers[input_id].description = 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;
			}
			//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;
			}
		}
		infile.close();
	}
}
Пример #17
0
void AnimationSet::load() {
	assert(!loaded);
	loaded = true;

	FileParser parser;
	// @CLASS Animation|Description of animations in animations/
	if (!parser.open(name, true, "Error loading animation definition: " + name))
		return;

	string _name = "";
	int position = 0;
	int frames = 0;
	int duration = 0;
	Point render_size;
	Point render_offset;
	string type = "";
	string starting_animation = "";
	bool first_section=true;
	bool compressed_loading=false; // is reset every section to false, set by frame keyword
	Animation *newanim = NULL;
	vector<short> active_frames;

	// 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 (parser.key == "image") {
			// @ATTR image|string|Filename of sprite-sheet image.
			if (sprite != NULL) {
				printf("multiple images specified in %s, dragons be here!\n", name.c_str());
				SDL_Quit();
				exit(128);
			}

			sprite = render_device->loadImage(parser.val);
		}
		else if (parser.key == "position") {
			// @ATTR position|integer|Number of frames to the right to use as the first frame. Unpacked animations only.
			position = toInt(parser.val);
		}
		else if (parser.key == "frames") {
			// @ATTR frames|integer|The total number of frames
			frames = toInt(parser.val);
		}
		else if (parser.key == "duration") {
			// @ATTR duration|integer|The duration of each frame.
			duration = 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|w (integer), h (integer)|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|x (integer), y (integer)|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|[all:frame (integer), ...]|A list of frames marked as "active". Also, "all" can be used to mark all frames as active.
			active_frames.clear();
			string nv = parser.nextValue();
			if (nv == "all") {
				active_frames.push_back(-1);
			}
			else {
				while (nv != "") {
					active_frames.push_back(toInt(nv));
					nv = parser.nextValue();
				}
				sort(active_frames.begin(), active_frames.end());
				active_frames.erase(unique(active_frames.begin(), active_frames.end()), active_frames.end());
			}
		}
		else if (parser.key == "frame") {
			// @ATTR frame|index (integer), direction (integer), x (integer), y (integer), w (integer), h (integer), x offset (integer), y offset (integer)|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 int index = toInt(parser.nextValue());
			const int direction = 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 {
			fprintf(stderr, "animations definitions (%s): Key %s not supported!\n", parser.getFileName().c_str(), parser.key.c_str());
		}

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

	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;
	}
}
Пример #18
0
MenuInventory::MenuInventory(StatBlock *_stats) {
	stats = _stats;
	MAX_EQUIPPED = 4;
	MAX_CARRIED = 64;
	visible = false;

	setBackground("images/menus/inventory.png");

	currency = 0;

	carried_cols = 4; // default to 4 if menus/inventory.txt::carried_cols not set
	carried_rows = 4; // default to 4 if menus/inventory.txt::carried_rows not set

	drag_prev_src = -1;
	changed_equipment = true;
	inv_ctrl = INV_CTRL_NONE;
	log_msg = "";
	show_book = "";

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

	// Load config settings
	FileParser infile;
	// @CLASS MenuInventory|Description of menus/inventory.txt
	if (infile.open("menus/inventory.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);
				closeButton->setBasePos(pos.x, pos.y);
			}
			// @ATTR equipment_slot|x (integer), y (integer), size (integer), slot_type (string)|Position and item type of an equipment slot.
			else if(infile.key == "equipment_slot") {
				Rect area;
				Point pos;

				pos.x = area.x = popFirstInt(infile.val);
				pos.y = area.y = popFirstInt(infile.val);
				area.w = area.h = popFirstInt(infile.val);
				equipped_area.push_back(area);
				equipped_pos.push_back(pos);
				slot_type.push_back(popFirstString(infile.val));
			}
			// @ATTR slot_name|string|The displayed name of the last defined equipment slot.
			else if(infile.key == "slot_name") slot_desc.push_back(infile.val);
			// @ATTR carried_area|x (integer), y (integer)|Position of the first normal inventory slot.
			else if(infile.key == "carried_area") {
				Point pos;
				carried_pos.x = carried_area.x = popFirstInt(infile.val);
				carried_pos.y = carried_area.y = popFirstInt(infile.val);
			}
			// @ATTR carried_cols|integer|The number of columns for the normal inventory.
			else if (infile.key == "carried_cols") carried_cols = std::max(1, toInt(infile.val));
			// @ATTR carried_rows|integer|The number of rows for the normal inventory.
			else if (infile.key == "carried_rows") carried_rows = std::max(1, toInt(infile.val));
			// @ATTR label_title|label|Position of the "Inventory" label.
			else if (infile.key == "label_title") title =  eatLabelInfo(infile.val);
			// @ATTR currency|label|Position of the label that displays the total currency being carried.
			else if (infile.key == "currency") currency_lbl =  eatLabelInfo(infile.val);
			// @ATTR help|x (integer), y (integer), w (integer), h (integer)|A mouse-over area that displays some help text for inventory shortcuts.
			else if (infile.key == "help") help_pos = toRect(infile.val);

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

	MAX_EQUIPPED = static_cast<int>(equipped_area.size());
	MAX_CARRIED = carried_cols * carried_rows;

	carried_area.w = carried_cols*ICON_SIZE;
	carried_area.h = carried_rows*ICON_SIZE;

	color_normal = font->getColor("menu_normal");
	color_high = font->getColor("menu_bonus");

	inventory[EQUIPMENT].init(MAX_EQUIPPED, equipped_area, slot_type);
	inventory[CARRIED].init(MAX_CARRIED, carried_area, ICON_SIZE, carried_cols);

	for (int i = 0; i < MAX_EQUIPPED; i++) {
		tablist.add(inventory[EQUIPMENT].slots[i]);
	}
	for (int i = 0; i < MAX_CARRIED; i++) {
		tablist.add(inventory[CARRIED].slots[i]);
	}

	align();
}
Пример #19
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") {
                AUTOPICKUP_CURRENCY = eatFirstInt(infile.val, ',');
			} else if (infile.key == "currency_name") {
                CURRENCY = msg->get(eatFirstString(infile.val, ','));
			} else if (infile.key == "vendor_ratio") {
                VENDOR_RATIO = (float)eatFirstInt(infile.val, ',') / 100.0;
			} 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");

	animation_count = 0;

	for (int i=0; i<64; i++) {
		flying_loot[i] = NULL;
		animation_id[i] = "";
	}

	loot_flip = NULL;

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

	// reset loot table
	for (int lvl=0; lvl<15; lvl++) {
		loot_table_count[lvl] = 0;
		for (int num=0; num<256; num++) {
			loot_table[lvl][num] = 0;
		}
	}

	loadGraphics();
	calcTables();
	if (audio && SOUND_VOLUME)
		loot_flip = Mix_LoadWAV(mods->locate("soundfx/flying_loot.ogg").c_str());
	full_msg = false;

	anim_loot_frames = 6;
	anim_loot_duration = 3;

	if (!lootManager)
		lootManager = this;
	else
		exit(25);
		// TODO: make sure only one instance of the lootmanager is created.
}
Пример #20
0
void EventManager::loadEventComponent(FileParser &infile, Event* evnt, Event_Component* ec) {
    Event_Component *e = NULL;
    if (evnt) {
        evnt->components.push_back(Event_Component());
        e = &evnt->components.back();
    }
    else if (ec) {
        e = ec;
    }

    if (!e) return;

    e->type = infile.key;

    if (infile.key == "tooltip") {
        // @ATTR event.tooltip|string|Tooltip for event
        e->s = msg->get(infile.val);
    }
    else if (infile.key == "power_path") {
        // @ATTR event.power_path|[hero:[x,y]]|Event power path
        // x,y are src, if s=="hero" we target the hero,
        // else we'll use values in a,b as coordinates
        e->x = toInt(infile.nextValue());
        e->y = toInt(infile.nextValue());

        std::string dest = infile.nextValue();
        if (dest == "hero") {
            e->s = "hero";
        }
        else {
            e->a = toInt(dest);
            e->b = toInt(infile.nextValue());
        }
    }
    else if (infile.key == "power_damage") {
        // @ATTR event.power_damage|min(integer), max(integer)|Range of power damage
        e->a = toInt(infile.nextValue());
        e->b = toInt(infile.nextValue());
    }
    else if (infile.key == "intermap") {
        // @ATTR event.intermap|[map(string),x(integer),y(integer)]|Jump to specific map at location specified.
        e->s = infile.nextValue();
        e->x = toInt(infile.nextValue());
        e->y = toInt(infile.nextValue());
    }
    else if (infile.key == "intramap") {
        // @ATTR event.intramap|[x(integer),y(integer)]|Jump to specific position within current map.
        e->x = toInt(infile.nextValue());
        e->y = toInt(infile.nextValue());
    }
    else if (infile.key == "mapmod") {
        // @ATTR event.mapmod|[string,int,int,int],..|Modify map tiles
        e->s = infile.nextValue();
        e->x = toInt(infile.nextValue());
        e->y = toInt(infile.nextValue());
        e->z = toInt(infile.nextValue());

        // add repeating mapmods
        if (evnt) {
            std::string repeat_val = infile.nextValue();
            while (repeat_val != "") {
                evnt->components.push_back(Event_Component());
                e = &evnt->components.back();
                e->type = infile.key;
                e->s = repeat_val;
                e->x = toInt(infile.nextValue());
                e->y = toInt(infile.nextValue());
                e->z = toInt(infile.nextValue());

                repeat_val = infile.nextValue();
            }
        }
    }
    else if (infile.key == "soundfx") {
        // @ATTR event.soundfx|[soundfile(string),x(integer),y(integer)]|Filename of a sound to play at an optional location
        e->s = infile.nextValue();
        e->x = e->y = -1;

        std::string s = infile.nextValue();
        if (s != "") e->x = toInt(s);

        s = infile.nextValue();
        if (s != "") e->y = toInt(s);

    }
    else if (infile.key == "loot") {
        // @ATTR event.loot|[string,drop_chance([fixed:chance(integer)]),quantity_min(integer),quantity_max(integer)],...|Add loot to the event; either a filename or an inline definition.
        loot->parseLoot(infile, e, &evnt->components);
    }
    else if (infile.key == "msg") {
        // @ATTR event.msg|string|Adds a message to be displayed for the event.
        e->s = msg->get(infile.val);
    }
    else if (infile.key == "shakycam") {
        // @ATTR event.shakycam|duration|Makes the camera shake for this duration in 'ms' or 's'.
        e->x = parse_duration(infile.val);
    }
    else if (infile.key == "requires_status") {
        // @ATTR event.requires_status|string,...|Event requires list of statuses
        e->s = infile.nextValue();

        // add repeating requires_status
        if (evnt) {
            std::string repeat_val = infile.nextValue();
            while (repeat_val != "") {
                evnt->components.push_back(Event_Component());
                e = &evnt->components.back();
                e->type = infile.key;
                e->s = repeat_val;

                repeat_val = infile.nextValue();
            }
        }
    }
    else if (infile.key == "requires_not_status") {
        // @ATTR event.requires_not_status|string,...|Event requires not list of statuses
        e->s = infile.nextValue();

        // add repeating requires_not
        if (evnt) {
            std::string repeat_val = infile.nextValue();
            while (repeat_val != "") {
                evnt->components.push_back(Event_Component());
                e = &evnt->components.back();
                e->type = infile.key;
                e->s = repeat_val;

                repeat_val = infile.nextValue();
            }
        }
    }
    else if (infile.key == "requires_level") {
        // @ATTR event.requires_level|integer|Event requires hero level
        e->x = toInt(infile.nextValue());
    }
    else if (infile.key == "requires_not_level") {
        // @ATTR event.requires_not_level|integer|Event requires not hero level
        e->x = toInt(infile.nextValue());
    }
    else if (infile.key == "requires_currency") {
        // @ATTR event.requires_currency|integer|Event requires atleast this much currency
        e->x = toInt(infile.nextValue());
    }
    else if (infile.key == "requires_item") {
        // @ATTR event.requires_item|integer,...|Event requires specific item
        e->x = toInt(infile.nextValue());

        // add repeating requires_item
        if (evnt) {
            std::string repeat_val = infile.nextValue();
            while (repeat_val != "") {
                evnt->components.push_back(Event_Component());
                e = &evnt->components.back();
                e->type = infile.key;
                e->x = toInt(repeat_val);

                repeat_val = infile.nextValue();
            }
        }
    }
    else if (infile.key == "requires_class") {
        // @ATTR event.requires_class|string|Event requires this base class
        e->s = infile.nextValue();
    }
    else if (infile.key == "set_status") {
        // @ATTR event.set_status|string,...|Sets specified statuses
        e->s = infile.nextValue();

        // add repeating set_status
        if (evnt) {
            std::string repeat_val = infile.nextValue();
            while (repeat_val != "") {
                evnt->components.push_back(Event_Component());
                e = &evnt->components.back();
                e->type = infile.key;
                e->s = repeat_val;

                repeat_val = infile.nextValue();
            }
        }
    }
    else if (infile.key == "unset_status") {
        // @ATTR event.unset_status|string,...|Unsets specified statuses
        e->s = infile.nextValue();

        // add repeating unset_status
        if (evnt) {
            std::string repeat_val = infile.nextValue();
            while (repeat_val != "") {
                evnt->components.push_back(Event_Component());
                e = &evnt->components.back();
                e->type = infile.key;
                e->s = repeat_val;

                repeat_val = infile.nextValue();
            }
        }
    }
    else if (infile.key == "remove_currency") {
        // @ATTR event.remove_currency|integer|Removes specified amount of currency from hero inventory
        e->x = toInt(infile.val);
        clampFloor(e->x, 0);
    }
    else if (infile.key == "remove_item") {
        // @ATTR event.remove_item|integer,...|Removes specified item from hero inventory
        e->x = toInt(infile.nextValue());

        // add repeating remove_item
        if (evnt) {
            std::string repeat_val = infile.nextValue();
            while (repeat_val != "") {
                evnt->components.push_back(Event_Component());
                e = &evnt->components.back();
                e->type = infile.key;
                e->x = toInt(repeat_val);

                repeat_val = infile.nextValue();
            }
        }
    }
    else if (infile.key == "reward_xp") {
        // @ATTR event.reward_xp|integer|Reward hero with specified amount of experience points.
        e->x = toInt(infile.val);
        clampFloor(e->x, 0);
    }
    else if (infile.key == "reward_currency") {
        // @ATTR event.reward_currency|integer|Reward hero with specified amount of currency.
        e->x = toInt(infile.val);
        clampFloor(e->x, 0);
    }
    else if (infile.key == "reward_item") {
        // @ATTR event.reward_item|x(integer),y(integer)|Reward hero with y number of item x.
        e->x = toInt(infile.nextValue());
        e->y = toInt(infile.val);
        clampFloor(e->y, 0);
    }
    else if (infile.key == "restore") {
        // @ATTR event.restore|string|Restore the hero's HP, MP, and/or status.
        e->s = infile.val;
    }
    else if (infile.key == "power") {
        // @ATTR event.power|power_id|Specify power coupled with event.
        e->x = toInt(infile.val);
    }
    else if (infile.key == "spawn") {
        // @ATTR event.spawn|[string,x(integer),y(integer)], ...|Spawn an enemy from this category at location
        e->s = infile.nextValue();
        e->x = toInt(infile.nextValue());
        e->y = toInt(infile.nextValue());

        // add repeating spawn
        if (evnt) {
            std::string repeat_val = infile.nextValue();
            while (repeat_val != "") {
                evnt->components.push_back(Event_Component());
                e = &evnt->components.back();
                e->type = infile.key;

                e->s = repeat_val;
                e->x = toInt(infile.nextValue());
                e->y = toInt(infile.nextValue());

                repeat_val = infile.nextValue();
            }
        }
    }
    else if (infile.key == "stash") {
        // @ATTR event.stash|boolean|Opens the Stash menu.
        e->s = infile.val;
    }
    else if (infile.key == "npc") {
        // @ATTR event.npc|string|Filename of an NPC to start dialog with.
        e->s = infile.val;
    }
    else if (infile.key == "music") {
        // @ATTR event.music|string|Change background music to specified file.
        e->s = infile.val;
    }
    else if (infile.key == "cutscene") {
        // @ATTR event.cutscene|string|Show specified cutscene by filename.
        e->s = infile.val;
    }
    else if (infile.key == "repeat") {
        // @ATTR event.repeat|boolean|Allows the event to be triggered again.
        e->s = infile.val;
    }
    else if (infile.key == "save_game") {
        // @ATTR event.save_game|boolean|Saves the game when the event is triggered. The respawn position is set to where the player is standing.
        e->s = infile.val;
    }
    else {
        infile.error("EventManager: '%s' is not a valid key.", infile.key.c_str());
    }
}
Пример #21
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;
	if (!infile.open(filename)) {
		fprintf(stderr, "Unable to open %s!\n", filename.c_str());
		return;
	}

	int id = 0;
	bool id_line = false;
	while (infile.next()) {
		if (infile.key == "id") {
			id_line = true;
			id = toInt(infile.val);
			if (id > 0 && id >= (int)items.size()) {
				// *2 to amortize the resizing to O(log(n)).
				items.resize((2*id) + 1);
			}
		} else id_line = false;

		if (id < 1) {
			if (id_line) fprintf(stderr, "Item index out of bounds 1-%d, skipping\n", INT_MAX);
			continue;
		}
		if (id_line) continue;

		if (infile.key == "name")
			items[id].name = msg->get(infile.val);
		else if (infile.key == "level")
			items[id].level = toInt(infile.val);
		else if (infile.key == "icon") {
			items[id].icon = toInt(infile.nextValue());
		}
		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 == "item_type") {
				items[id].type = infile.val;
		}
		else if (infile.key == "dmg_melee") {
			items[id].dmg_melee_min = toInt(infile.nextValue());
			if (infile.val.length() > 0)
				items[id].dmg_melee_max = toInt(infile.nextValue());
			else
				items[id].dmg_melee_max = items[id].dmg_melee_min;
		}
		else if (infile.key == "dmg_ranged") {
			items[id].dmg_ranged_min = toInt(infile.nextValue());
			if (infile.val.length() > 0)
				items[id].dmg_ranged_max = toInt(infile.nextValue());
			else
				items[id].dmg_ranged_max = items[id].dmg_ranged_min;
		}
		else if (infile.key == "dmg_ment") {
			items[id].dmg_ment_min = toInt(infile.nextValue());
			if (infile.val.length() > 0)
				items[id].dmg_ment_max = toInt(infile.nextValue());
			else
				items[id].dmg_ment_max = items[id].dmg_ment_min;
		}
		else if (infile.key == "abs") {
			items[id].abs_min = toInt(infile.nextValue());
			if (infile.val.length() > 0)
				items[id].abs_max = toInt(infile.nextValue());
			else
				items[id].abs_max = items[id].abs_min;
		}
		else if (infile.key == "req") {
			string 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 = toInt(infile.nextValue());
		}
		else if (infile.key == "bonus") {
			items[id].bonus_stat.push_back(infile.nextValue());
			items[id].bonus_val.push_back(toInt(infile.nextValue()));
		}
		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_animation")
			items[id].loot_animation = infile.val;
		else if (infile.key == "power") {
			if (toInt(infile.val) > 0) {
				items[id].power = toInt(infile.val);
			}
			else fprintf(stderr, "Power index inside item %d definition out of bounds 1-%d, skipping item\n", id, INT_MAX);
		}
		else if (infile.key == "power_mod")
			items[id].power_mod = toInt(infile.val);
		else if (infile.key == "power_desc")
			items[id].power_desc = msg->get(infile.val);
		else if (infile.key == "price")
			items[id].price = toInt(infile.val);
		else if (infile.key == "price_sell")
			items[id].price_sell = toInt(infile.val);
		else if (infile.key == "max_quantity")
			items[id].max_quantity = toInt(infile.val);
		else if (infile.key == "rand_loot")
			items[id].rand_loot = toInt(infile.val);
		else if (infile.key == "rand_vendor")
			items[id].rand_vendor = toInt(infile.val);
		else if (infile.key == "pickup_status")
			items[id].pickup_status = infile.val;
		else if (infile.key == "stepfx")
			items[id].stepfx = infile.val;
		else if (infile.key == "class") {
			string classname = infile.nextValue();
			while (classname != "") {
				unsigned pos; // find the position where this classname is stored:
				for (pos = 0; pos < item_class_names.size(); pos++) {
					if (item_class_names[pos] == classname)
						break;
				}
				// if it was not found, add it to the end.
				// pos is already the correct index.
				if (pos == item_class_names.size()) {
					item_class_names.push_back(classname);
					item_class_items.push_back(vector<unsigned int>());
				}
				// add item id to the item list of that class:
				item_class_items[pos].push_back(id);
				classname = infile.nextValue();
			}
		}

	}
	infile.close();
}
Пример #22
0
void EventManager::loadEvent(FileParser &infile, Event* evnt) {
    if (!evnt) return;
    // @CLASS EventManager|Description of events in maps/ and npcs/

    if (infile.key == "type") {
        // @ATTR event.type|[on_trigger:on_mapexit:on_leave:on_load:on_clear]|Type of map event.
        std::string type = infile.val;
        evnt->type = type;

        if      (type == "on_trigger");
        else if (type == "on_mapexit"); // no need to set keep_after_trigger to false correctly, it's ignored anyway
        else if (type == "on_leave");
        else if (type == "on_load") {
            evnt->keep_after_trigger = false;
        }
        else if (type == "on_clear") {
            evnt->keep_after_trigger = false;
        }
        else {
            infile.error("EventManager: Event type '%s' unknown, change to \"on_trigger\" to suppress this warning.", type.c_str());
        }
    }
    else if (infile.key == "location") {
        // @ATTR event.location|[x,y,w,h]|Defines the location area for the event.
        evnt->location.x = toInt(infile.nextValue());
        evnt->location.y = toInt(infile.nextValue());
        evnt->location.w = toInt(infile.nextValue());
        evnt->location.h = toInt(infile.nextValue());

        if (evnt->center.x == -1 && evnt->center.y == -1) {
            evnt->center.x = static_cast<float>(evnt->location.x) + static_cast<float>(evnt->location.w)/2;
            evnt->center.y = static_cast<float>(evnt->location.y) + static_cast<float>(evnt->location.h)/2;
        }
    }
    else if (infile.key == "hotspot") {
        //  @ATTR event.hotspot|[ [x, y, w, h] : location ]|Event uses location as hotspot or defined by rect.
        if (infile.val == "location") {
            evnt->hotspot.x = evnt->location.x;
            evnt->hotspot.y = evnt->location.y;
            evnt->hotspot.w = evnt->location.w;
            evnt->hotspot.h = evnt->location.h;
        }
        else {
            evnt->hotspot.x = toInt(infile.nextValue());
            evnt->hotspot.y = toInt(infile.nextValue());
            evnt->hotspot.w = toInt(infile.nextValue());
            evnt->hotspot.h = toInt(infile.nextValue());
        }

        evnt->center.x = static_cast<float>(evnt->hotspot.x) + static_cast<float>(evnt->hotspot.w)/2;
        evnt->center.y = static_cast<float>(evnt->hotspot.y) + static_cast<float>(evnt->hotspot.h)/2;
    }
    else if (infile.key == "cooldown") {
        // @ATTR event.cooldown|duration|Duration for event cooldown in 'ms' or 's'.
        evnt->cooldown = parse_duration(infile.val);
    }
    else if (infile.key == "reachable_from") {
        // @ATTR event.reachable_from|[x,y,w,h]|If the hero is inside this rectangle, they can activate the event.
        evnt->reachable_from.x = toInt(infile.nextValue());
        evnt->reachable_from.y = toInt(infile.nextValue());
        evnt->reachable_from.w = toInt(infile.nextValue());
        evnt->reachable_from.h = toInt(infile.nextValue());
    }
    else {
        loadEventComponent(infile, evnt, NULL);
    }
}
Пример #23
0
int main(int argc, char* argv[])
#endif
{		
	IFXRESULT result = IFX_OK;
#ifdef __MINGW32__
	wchar_t **argw = NULL;
	int argc=0;
#endif
#ifndef WIN32
	wchar_t **argw = NULL;
	int i;
#endif

	result = IFXSetDefaultLocale();
	IFXTRACE_GENERIC(L"[Converter] IFXSetDefaultLocale %i\n", result);

	if( IFXSUCCESS(result) )
	{
#ifdef __MINGW32__
		argw = CommandLineToArgvW(GetCommandLineW(), &argc);
#endif
#ifndef WIN32
		argw = (wchar_t**)malloc(argc*sizeof(wchar_t*));
		if (argw == NULL)
			result = IFX_E_OUT_OF_MEMORY;

		if( IFXSUCCESS(result) )
		{
			memset(argw, 0, argc*sizeof(wchar_t*));

			for (i=0; i<argc; i++) 
			{
				argw[i] = mbs_to_wcs(argv[i]);

				if (argw[i] == NULL)
				{
					result = IFX_E_OUT_OF_MEMORY;
					break;
				}
			}
		}
#endif
	}


	if( IFXSUCCESS(result) && argc > 2 )
	{
		if( 0 == wcscmp(L"-libdir", argw[argc-2]) || 0 == wcscmp(L"-l", argw[argc-2]) )
		{
			size_t size = wcstombs(NULL, argw[argc-1], 0);
			if (size <= MAXIMUM_FILENAME_LENGTH)
			{
#ifdef WIN32
				SetEnvironmentVariable(L"U3D_LIBDIR", argw[argc-1]);
#else
				char libdir[size+1];
				wcstombs(libdir, argw[argc-1], size);
				libdir[size] = 0;
				setenv("U3D_LIBDIR",libdir,1);
#endif
				argc -=2;
			}
		}
	}

	if( IFXSUCCESS(result) )
	{
		IFXDEBUG_STARTUP();
		result = IFXCOMInitialize();
	}
	
	IFXTRACE_GENERIC(L"[Converter] IFXCOMInitialize %i\n", result);

	if( IFXSUCCESS(result) )
	{
		ConverterOptions converterOptions;
		FileOptions fileOptions;
		
		if( IFXSUCCESS(result) )
			SetDefaultOptionsX( &converterOptions, &fileOptions );
		
		if( IFXSUCCESS(result) )
		{
			result = ReadAndSetUserOptionsX( 
								argc, argw, 
								&converterOptions, &fileOptions );		
		}
		
#ifdef STDIO_HACK
		if( IFXSUCCESS(result) )
		{
			if ( fileOptions.outFile != L"stdout" && fileOptions.outFile != L"-" )
				stdmsg = stdout;
		}
#endif
		
		if( IFXSUCCESS(result) )
		{
			SceneUtilities sceneUtils;
			FileParser fileParser;
            
            IFXTRACE_GENERIC( L"[Converter] fileParser.Initialize\n" );
			result = fileParser.Initialize( fileOptions.inFile.Raw() );

			if( IFXSUCCESS(result) )
                IFXTRACE_GENERIC( L"[Converter] sceneUtils.InitializeScene\n" );
				result = sceneUtils.InitializeScene( 
											fileOptions.profile, 
											fileOptions.scalingFactor );

			if( IFXSUCCESS(result) )
			{
                IFXTRACE_GENERIC( L"[Converter] converter.Convert\n" );
				SceneConverter converter( 
									&fileParser, &sceneUtils, 
									&converterOptions );
				result = converter.Convert();
			}

			//----------------------------------------------
			// Scene now built and in the U3D engine.
			// It is now time to examine the scene and/or
			// dump it to a debug file or a U3D file.
			//----------------------------------------------

			// Write out the scene to a U3D file if this is enabled.
			if ( IFXSUCCESS( result ) && ( fileOptions.exportOptions > 0 ) )
			{
				result = sceneUtils.WriteSceneToFile( 
											fileOptions.outFile,
											fileOptions.exportOptions );
			}

			// If enabled, dump the scene to the debug file.
			if ( IFXSUCCESS( result ) && ( fileOptions.debugLevel > 0 ) )
			{
				U8 file[MAXIMUM_FILENAME_LENGTH];
				result = fileOptions.outFile.ConvertToRawU8( file, MAXIMUM_FILENAME_LENGTH );

				if ( IFXSUCCESS( result ) )
					result = sceneUtils.WriteDebugInfo( (const char*)file );
			}
		}
	}

	fprintf(stdmsg,"Exit code = %x\n", result);

	IFXRESULT comResult = IFXCOMUninitialize();
	IFXTRACE_GENERIC( L"[Converter] IFXCOMUninitialize %i\n", comResult );
	
	IFXDEBUG_SHUTDOWN();

#ifdef __MINGW32__
	LocalFree(argw);
#endif
#ifndef WIN32
	if (argw != NULL)
	{
		for (i=0; i<argc; i++) 
		{
			if(argw[i] != NULL) free(argw[i]);
		}
		free(argw);
	}
#endif

	return result;
}
Пример #24
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);
			}
		}
		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 == "small_icon_size")
				ICON_SIZE_SMALL = toInt(infile.val);
			else if (infile.key == "large_icon_size")
				ICON_SIZE_LARGE = 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 = msg->get(infile.val);
			else if (infile.key == "resist") e.resist = msg->get(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");
}
Пример #25
0
/**
 * load a statblock, typically for an enemy definition
 */
void StatBlock::load(const string& filename) {
	FileParser infile;
	if (!infile.open(filename))
		return;

	string loot_token;

	while (infile.next()) {
		int num = toInt(infile.val);
		float fnum = toFloat(infile.val);
		bool valid = loadCoreStat(&infile);

		if (infile.key == "name") name = msg->get(infile.val);
		else if (infile.key == "humanoid") humanoid = toBool(infile.val);
		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 == "convert_status") convert_status = infile.val;
		else if (infile.key == "first_defeat_loot") first_defeat_loot = num;
		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
		else if (infile.key == "cooldown") cooldown = parse_duration(infile.val);

		// behavior stats
		else if (infile.key == "flying") flying = toBool(infile.val);
		else if (infile.key == "intangible") intangible = toBool(infile.val);
		else if (infile.key == "facing") facing = toBool(infile.val);

		else if (infile.key == "waypoint_pause") waypoint_pause = 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 = fnum;
		else if (infile.key == "threat_range") threat_range = fnum;
		else if (infile.key == "passive_attacker") passive_attacker = toBool(infile.val);

		// 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") suppress_hp = toBool(infile.val);
		// 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) {
			fprintf(stderr, "%s=%s not a valid StatBlock parameter\n", infile.key.c_str(), infile.val.c_str());
		}
	}
	infile.close();

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

	// sort loot table
	std::sort(loot.begin(), loot.end(), sortLoot);

	applyEffects();
}
Пример #26
0
void Map::loadEventComponent(FileParser &infile) {
	// new event component
	events.back().components.push_back(Event_Component());
	Event_Component *e = &events.back().components.back();
	e->type = infile.key;

	if (infile.key == "tooltip") {
		e->s = msg->get(infile.val);
	}
	else if (infile.key == "power_path") {
		// x,y are src, if s=="hero" we target the hero,
		// else we'll use values in a,b as coordinates
		e->x = toInt(infile.nextValue());
		e->y = toInt(infile.nextValue());

		std::string dest = infile.nextValue();
		if (dest == "hero") {
			e->s = "hero";
		}
		else {
			e->a = toInt(dest);
			e->b = toInt(infile.nextValue());
		}
	}
	else if (infile.key == "power_damage") {
		e->a = toInt(infile.nextValue());
		e->b = toInt(infile.nextValue());
	}
	else if (infile.key == "intermap") {
		e->s = infile.nextValue();
		e->x = toInt(infile.nextValue());
		e->y = toInt(infile.nextValue());
	}
	else if (infile.key == "intramap") {
		e->x = toInt(infile.nextValue());
		e->y = toInt(infile.nextValue());
	}
	else if (infile.key == "mapmod") {
		e->s = infile.nextValue();
		e->x = toInt(infile.nextValue());
		e->y = toInt(infile.nextValue());
		e->z = toInt(infile.nextValue());

		// add repeating mapmods
		std::string repeat_val = infile.nextValue();
		while (repeat_val != "") {
			events.back().components.push_back(Event_Component());
			e = &events.back().components.back();
			e->type = infile.key;
			e->s = repeat_val;
			e->x = toInt(infile.nextValue());
			e->y = toInt(infile.nextValue());
			e->z = toInt(infile.nextValue());

			repeat_val = infile.nextValue();
		}
	}
	else if (infile.key == "soundfx") {
		e->s = infile.nextValue();
		e->x = e->y = -1;

		std::string s = infile.nextValue();
		if (s != "") e->x = toInt(s);

		s = infile.nextValue();
		if (s != "") e->y = toInt(s);

	}
	else if (infile.key == "loot") {
		e->s = infile.nextValue();
		e->x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
		e->y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;

		// drop chance
		std::string chance = infile.nextValue();
		if (chance == "fixed") e->z = 0;
		else e->z = toInt(chance);

		// quantity min/max
		e->a = toInt(infile.nextValue());
		if (e->a < 1) e->a = 1;
		e->b = toInt(infile.nextValue());
		if (e->b < e->a) e->b = e->a;

		// add repeating loot
		std::string repeat_val = infile.nextValue();
		while (repeat_val != "") {
			events.back().components.push_back(Event_Component());
			e = &events.back().components.back();
			e->type = infile.key;
			e->s = repeat_val;
			e->x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
			e->y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;

			chance = infile.nextValue();
			if (chance == "fixed") e->z = 0;
			else e->z = toInt(chance);

			e->a = toInt(infile.nextValue());
			if (e->a < 1) e->a = 1;
			e->b = toInt(infile.nextValue());
			if (e->b < e->a) e->b = e->a;

			repeat_val = infile.nextValue();
		}
	}
	else if (infile.key == "msg") {
		e->s = msg->get(infile.val);
	}
	else if (infile.key == "shakycam") {
		e->x = toInt(infile.val);
	}
	else if (infile.key == "requires_status") {
		e->s = infile.nextValue();

		// add repeating requires_status
		std::string repeat_val = infile.nextValue();
		while (repeat_val != "") {
			events.back().components.push_back(Event_Component());
			e = &events.back().components.back();
			e->type = infile.key;
			e->s = repeat_val;

			repeat_val = infile.nextValue();
		}
	}
	else if (infile.key == "requires_not") {
		e->s = infile.nextValue();

		// add repeating requires_not
		std::string repeat_val = infile.nextValue();
		while (repeat_val != "") {
			events.back().components.push_back(Event_Component());
			e = &events.back().components.back();
			e->type = infile.key;
			e->s = repeat_val;

			repeat_val = infile.nextValue();
		}
	}
	else if (infile.key == "requires_level") {
		e->x = toInt(infile.nextValue());
	}
	else if (infile.key == "requires_not_level") {
		e->x = toInt(infile.nextValue());
	}
	else if (infile.key == "requires_item") {
		e->x = toInt(infile.nextValue());

		// add repeating requires_item
		std::string repeat_val = infile.nextValue();
		while (repeat_val != "") {
			events.back().components.push_back(Event_Component());
			e = &events.back().components.back();
			e->type = infile.key;
			e->x = toInt(repeat_val);

			repeat_val = infile.nextValue();
		}
	}
	else if (infile.key == "set_status") {
		e->s = infile.nextValue();

		// add repeating set_status
		std::string repeat_val = infile.nextValue();
		while (repeat_val != "") {
			events.back().components.push_back(Event_Component());
			e = &events.back().components.back();
			e->type = infile.key;
			e->s = repeat_val;

			repeat_val = infile.nextValue();
		}
	}
	else if (infile.key == "unset_status") {
		e->s = infile.nextValue();

		// add repeating unset_status
		std::string repeat_val = infile.nextValue();
		while (repeat_val != "") {
			events.back().components.push_back(Event_Component());
			e = &events.back().components.back();
			e->type = infile.key;
			e->s = repeat_val;

			repeat_val = infile.nextValue();
		}
	}
	else if (infile.key == "remove_item") {
		e->x = toInt(infile.nextValue());

		// add repeating remove_item
		std::string repeat_val = infile.nextValue();
		while (repeat_val != "") {
			events.back().components.push_back(Event_Component());
			e = &events.back().components.back();
			e->type = infile.key;
			e->x = toInt(repeat_val);

			repeat_val = infile.nextValue();
		}
	}
	else if (infile.key == "reward_xp") {
		e->x = toInt(infile.val);
	}
	else if (infile.key == "power") {
		e->x = toInt(infile.val);
	}
	else if (infile.key == "spawn") {

		e->s = infile.nextValue();
		e->x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
		e->y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;

		// add repeating spawn
		std::string repeat_val = infile.nextValue();
		while (repeat_val != "") {
			events.back().components.push_back(Event_Component());
			e = &events.back().components.back();
			e->type = infile.key;

			e->s = repeat_val;
			e->x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
			e->y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;

			repeat_val = infile.nextValue();
		}
	}
	else if (infile.key == "stash") {
		e->s = infile.val;
	}
	else if (infile.key == "npc") {
		e->s = infile.val;
	}
	else if (infile.key == "music") {
		e->s = infile.val;
	}
	else if (infile.key == "cutscene") {
		e->s = infile.val;
	}
	else if (infile.key == "repeat") {
		e->s = infile.val;
	}
	else {
		fprintf(stderr, "Map: Unknown key value: %s in file %s in section %s\n", infile.key.c_str(), infile.getFileName().c_str(), infile.section.c_str());
	}
}
Пример #27
0
MenuManager::MenuManager(PowerManager *_powers, StatBlock *_stats, CampaignManager *_camp, ItemManager *_items) {
	powers = _powers;
	stats = _stats;
	camp = _camp;
	items = _items;

	loadIcons();

	hp = new MenuStatBar("hp");
	menus.push_back(hp); // menus[0]
	mp = new MenuStatBar("mp");
	menus.push_back(mp); // menus[1]
	xp = new MenuStatBar("xp");
	menus.push_back(xp); // menus[2]
	effects = new MenuActiveEffects(icons);
	menus.push_back(effects); // menus[3]
	hudlog = new MenuHUDLog();
	menus.push_back(hudlog); // menus[4]
	act = new MenuActionBar(powers, stats, icons);
	menus.push_back(act); // menus[5]
	enemy = new MenuEnemy();
	menus.push_back(enemy); // menus[6]
	vendor = new MenuVendor(items, stats);
	menus.push_back(vendor); // menus[7]
	talker = new MenuTalker(camp);
	menus.push_back(talker); // menus[8]
	exit = new MenuExit();
	menus.push_back(exit); // menus[9]
	mini = new MenuMiniMap();
	menus.push_back(mini); // menus[10]
	chr = new MenuCharacter(stats);
	menus.push_back(chr); // menus[11]
	inv = new MenuInventory(items, stats, powers);
	menus.push_back(inv); // menus[12]
	pow = new MenuPowers(stats, powers, icons);
	menus.push_back(pow); // menus[13]
	log = new MenuLog();
	menus.push_back(log); // menus[14]
	stash = new MenuStash(items, stats);
	menus.push_back(stash); // menus[15]
	tip = new WidgetTooltip();

	// Load the menu positions and alignments from menus/menus.txt
	std::string align;
	FileParser infile;
	if (infile.open(mods->locate("menus/menus.txt"))) {
		while (infile.next()) {
			infile.val = infile.val + ',';
			int x = eatFirstInt(infile.val, ',');
			int y = eatFirstInt(infile.val, ',');
			int w = eatFirstInt(infile.val, ',');
			int h = eatFirstInt(infile.val, ',');
			align = eatFirstString(infile.val, ',');

			int menu_index = -1;

			if (infile.key == "hp") menu_index = 0;
			else if (infile.key == "mp") menu_index = 1;
			else if (infile.key == "xp") menu_index = 2;
			else if (infile.key == "effects") menu_index = 3;
			else if (infile.key == "hudlog") menu_index = 4;
			else if (infile.key == "actionbar") menu_index = 5;
			else if (infile.key == "enemy") menu_index = 6;
			else if (infile.key == "vendor") menu_index = 7;
			else if (infile.key == "talker") menu_index = 8;
			else if (infile.key == "exit") menu_index = 9;
			else if (infile.key == "minimap") menu_index = 10;
			else if (infile.key == "character") menu_index = 11;
			else if (infile.key == "inventory") menu_index = 12;
			else if (infile.key == "powers") menu_index = 13;
			else if (infile.key == "log") menu_index = 14;
			else if (infile.key == "stash") menu_index = 15;

			if (menu_index != -1) {
				menus[menu_index]->window_area.x = x;
				menus[menu_index]->window_area.y = y;
				menus[menu_index]->window_area.w = w;
				menus[menu_index]->window_area.h = h;
				menus[menu_index]->alignment = align;
				menus[menu_index]->align();
			}

		}
		infile.close();
	} else fprintf(stderr, "Unable to open menus/menus.txt!\n");

	// Some menus need to be updated to apply their new dimensions
	act->update();
	vendor->update();
	vendor->buyback_stock.init(NPC_VENDOR_MAX_STOCK, items);
	talker->update();
	exit->update();
	chr->update();
	inv->update();
	pow->update();
	log->update();
	stash->update();

	pause = false;
	dragging = false;
	drag_stack.item = 0;
	drag_stack.quantity = 0;
	drag_power = 0;
	drag_src = 0;
	drop_stack.item = 0;
	drop_stack.quantity = 0;


	loadSounds();

	done = false;

	closeAll(false); // make sure all togglable menus start closed
}
Пример #28
0
void TileSet::load(const std::string& filename) {
	if (current_map == filename) return;

	reset();

	FileParser infile;
	string img;

	if (infile.open("tilesetdefs/" + filename)) {
		while (infile.next()) {
			if (infile.key == "tile") {

				infile.val = infile.val + ',';
				unsigned index = eatFirstInt(infile.val, ',');

				if (index >= tiles.size())
					tiles.resize(index + 1);

				tiles[index].tile.src.x = eatFirstInt(infile.val, ',');
				tiles[index].tile.src.y = eatFirstInt(infile.val, ',');
				tiles[index].tile.src.w = eatFirstInt(infile.val, ',');
				tiles[index].tile.src.h = eatFirstInt(infile.val, ',');
				tiles[index].offset.x = eatFirstInt(infile.val, ',');
				tiles[index].offset.y = eatFirstInt(infile.val, ',');
				max_size_x = std::max(max_size_x, (tiles[index].tile.src.w / TILE_W) + 1);
				max_size_y = std::max(max_size_y, (tiles[index].tile.src.h / TILE_H) + 1);
			}
			else if (infile.key == "img") {
				img = infile.val;
			}
			else if (infile.key == "transparency") {
				alpha_background = false;

				infile.val = infile.val + ',';
				trans_r = (Uint8)eatFirstInt(infile.val, ',');
				trans_g = (Uint8)eatFirstInt(infile.val, ',');
				trans_b = (Uint8)eatFirstInt(infile.val, ',');

			}
			else if (infile.key == "animation") {
				int frame = 0;
				unsigned TILE_ID = toInt(infile.nextValue());

				if (TILE_ID >= anim.size())
					anim.resize(TILE_ID + 1);

				string repeat_val = infile.nextValue();
				while (repeat_val != "") {
					anim[TILE_ID].frames++;
					anim[TILE_ID].pos.resize(frame + 1);
					anim[TILE_ID].frame_duration.resize(frame + 1);
					anim[TILE_ID].pos[frame].x = toInt(repeat_val);
					anim[TILE_ID].pos[frame].y = toInt(infile.nextValue());
					anim[TILE_ID].frame_duration[frame] = toInt(infile.nextValue());

					frame++;
					repeat_val = infile.nextValue();
				}
			}
		}
		infile.close();
		loadGraphics(img);
	}

	current_map = filename;
}
Пример #29
0
void EventManager::loadEventComponent(FileParser &infile, Event* evnt, Event_Component* ec) {
	if (!loadEventComponentString(infile.key, infile.val, evnt, ec)) {
		infile.error("EventManager: '%s' is not a valid key.", infile.key.c_str());
	}
}
Пример #30
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("maps/" + 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 maps/%s, loading spawn.txt\n", mapr->teleport_mapname.c_str());
					mapr->teleport_mapname = "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->inventory[EQUIPMENT].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();
}