Ejemplo n.º 1
0
void loadTilesetSettings() {
	// reset defaults
	UNITS_PER_PIXEL_X = 2;
	UNITS_PER_PIXEL_Y = 4;
	TILE_W = 64;
	TILE_H = 32;
	TILE_W_HALF = TILE_W/2;
	TILE_H_HALF = TILE_H/2;
	TILESET_ISOMETRIC = 0;
	TILESET_ORTHOGONAL = 1;
	TILESET_ORIENTATION = TILESET_ISOMETRIC;

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

	// Init automatically calculated parameters
	if (TILESET_ORIENTATION == TILESET_ISOMETRIC) {
		if (TILE_W > 0 && TILE_H > 0) {
			UNITS_PER_PIXEL_X = 2.0f / TILE_W;
			UNITS_PER_PIXEL_Y = 2.0f / TILE_H;
		}
		else {
			logError("Settings: Tile dimensions must be greater than 0. Resetting to the default size of 64x32.");
			TILE_W = 64;
			TILE_H = 32;
		}
	}
	else { // TILESET_ORTHOGONAL
		if (TILE_W > 0 && TILE_H > 0) {
			UNITS_PER_PIXEL_X = 1.0f / TILE_W;
			UNITS_PER_PIXEL_Y = 1.0f / TILE_H;
		}
		else {
			logError("Settings: Tile dimensions must be greater than 0. Resetting to the default size of 64x32.");
			TILE_W = 64;
			TILE_H = 32;
		}
	}
	if (UNITS_PER_PIXEL_X == 0 || UNITS_PER_PIXEL_Y == 0) {
		logError("Settings: One of UNITS_PER_PIXEL values is zero! %dx%d", static_cast<int>(UNITS_PER_PIXEL_X), static_cast<int>(UNITS_PER_PIXEL_Y));
		Exit(1);
	}
}
Ejemplo n.º 2
0
/**
 * When loading the game, load from file if possible
 */
void GameStatePlay::loadGame() {
	int saved_hp = 0;
	int saved_mp = 0;
	int currency = 0;

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

	FileParser infile;
	int hotkeys[12];

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

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

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

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

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

	// add legacy currency to inventory
	menu->inv->addCurrency(currency);

	// apply stats, inventory, and powers
	applyPlayerData();

	// trigger passive effects here? Saved HP/MP values might depend on passively boosted HP/MP
	// powers->activatePassives(pc->stats);
	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();
}
Ejemplo n.º 3
0
MenuTalker::MenuTalker(MenuManager *_menu)
	: Menu()
	, menu(_menu)
	, portrait(NULL)
	, dialog_node(0)
	, event_cursor(0)
	, font_who("font_regular")
	, font_dialog("font_regular")
	, color_normal(font->getColor("menu_normal"))
	, npc(NULL)
	, advanceButton(new WidgetButton("images/menus/buttons/right.png"))
	, closeButton(new WidgetButton("images/menus/buttons/button_x.png")) {

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

	// Load config settings
	FileParser infile;
	// @CLASS MenuTalker|Description of menus/talker.txt
	if(infile.open("menus/talker.txt")) {
		while(infile.next()) {
			if (parseMenuKey(infile.key, infile.val))
				continue;

			// @ATTR close|x (integer), y (integer)|Position of the close button.
			if(infile.key == "close") {
				Point pos = toPoint(infile.val);
				closeButton->setBasePos(pos.x, pos.y);
			}
			// @ATTR advance|x (integer), y (integer)|Position of the button to advance dialog.
			else if(infile.key == "advance") {
				Point pos = toPoint(infile.val);
				advanceButton->setBasePos(pos.x, pos.y);
			}
			// @ATTR dialogbox|x (integer), y (integer), w (integer), h (integer)|Position and dimensions of the text box graphics.
			else if (infile.key == "dialogbox") dialog_pos = toRect(infile.val);
			// @ATTR dialogtext|x (integer), y (integer), w (integer), h (integer)|Rectangle where the dialog text is placed.
			else if (infile.key == "dialogtext") text_pos = toRect(infile.val);
			// @ATTR text_offset|x (integer), y (integer)|Margins for the left/right and top/bottom of the dialog text.
			else if (infile.key == "text_offset") text_offset = toPoint(infile.val);
			// @ATTR portrait_he|x (integer), y (integer), w (integer), h (integer)|Position and dimensions of the NPC portrait graphics.
			else if (infile.key == "portrait_he") portrait_he = toRect(infile.val);
			// @ATTR portrait_you|x (integer), y (integer), w (integer), h (integer)|Position and dimensions of the player's portrait graphics.
			else if (infile.key == "portrait_you") portrait_you = toRect(infile.val);
			// @ATTR font_who|string|Font style to use for the name of the currently talking person.
			else if (infile.key == "font_who") font_who = infile.val;
			// @ATTR font_dialog|string|Font style to use for the dialog text.
			else if (infile.key == "font_dialog") font_dialog = infile.val;

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

	label_name = new WidgetLabel();
	label_name->setBasePos(text_pos.x + text_offset.x, text_pos.y + text_offset.y);

	textbox = new WidgetScrollBox(text_pos.w, text_pos.h-(text_offset.y*2));
	textbox->setBasePos(text_pos.x, text_pos.y + text_offset.y);

	tablist.add(advanceButton);
	tablist.add(closeButton);
	tablist.add(textbox);

	align();
}
Ejemplo n.º 4
0
/**
 * load
 */
int MapIso::load(string filename) {
	FileParser infile;
	string val;
	string cur_layer;
	string data_format;

	clearEvents();

	event_count = 0;
	bool collider_set = false;

	if (infile.open(mods->locate("maps/" + filename))) {
		while (infile.next()) {
			if (infile.new_section) {
				data_format = "dec"; // default

				if (enemy_awaiting_queue) {
					enemies.push(new_enemy);
					enemy_awaiting_queue = false;
				}
				if (npc_awaiting_queue) {
					npcs.push(new_npc);
					npc_awaiting_queue = false;
				}
				if (group_awaiting_queue) {
					push_enemy_group(new_group);
					group_awaiting_queue = false;
				}

				// for sections that are stored in collections, add a new object here
				if (infile.section == "enemy") {
					clearEnemy(new_enemy);
					enemy_awaiting_queue = true;
				}
				else if (infile.section == "enemygroup") {
					clearGroup(new_group);
					group_awaiting_queue = true;
				}
				else if (infile.section == "npc") {
					clearNPC(new_npc);
					npc_awaiting_queue = true;
				}
				else if (infile.section == "event") {
					event_count++;
				}

			}
			if (infile.section == "header") {
				if (infile.key == "title") {
					this->title = msg->get(infile.val);
				}
				else if (infile.key == "width") {
					this->w = atoi(infile.val.c_str());
				}
				else if (infile.key == "height") {
					this->h = atoi(infile.val.c_str());
				}
				else if (infile.key == "tileset") {
					this->tileset = infile.val;
				}
				else if (infile.key == "music") {
					if (this->music_filename == infile.val) {
						this->new_music = false;
					}
					else {
						this->music_filename = infile.val;
						this->new_music = true;
					}
				}
				else if (infile.key == "location") {
					spawn.x = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
					spawn.y = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
					spawn_dir = atoi(infile.nextValue().c_str());
				}
			}
			else if (infile.section == "layer") {
				if (infile.key == "type") {
					cur_layer = infile.val;
				}
				else if (infile.key == "format") {
					data_format = infile.val;
				}
				else if (infile.key == "data") {
					// layer map data handled as a special case

					// The next h lines must contain layer data.  TODO: err
					if (data_format == "hex") {
						for (int j=0; j<h; j++) {
							val = infile.getRawLine() + ',';
							for (int i=0; i<w; i++) {
								if (cur_layer == "background") background[i][j] = eatFirstHex(val, ',');
								else if (cur_layer == "object") object[i][j] = eatFirstHex(val, ',');
								else if (cur_layer == "collision") collision[i][j] = eatFirstHex(val, ',');
							}
						}
					}
					else if (data_format == "dec") {
						for (int j=0; j<h; j++) {
							val = infile.getRawLine() + ',';
							for (int i=0; i<w; i++) {
								if (cur_layer == "background") background[i][j] = eatFirstInt(val, ',');
								else if (cur_layer == "object") object[i][j] = eatFirstInt(val, ',');
								else if (cur_layer == "collision") collision[i][j] = eatFirstInt(val, ',');
							}
						}
					}
					if ((cur_layer == "collision") && !collider_set) {
						collider.setmap(collision);
						collider.map_size.x = w;
						collider.map_size.y = h;
					}
				}
			}
			else if (infile.section == "enemy") {
				if (infile.key == "type") {
					new_enemy.type = infile.val;
				}
				else if (infile.key == "location") {
					new_enemy.pos.x = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
					new_enemy.pos.y = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
				}
				else if (infile.key == "direction") {
					new_enemy.direction = atoi(infile.val.c_str());
				}
				else if (infile.key == "waypoints") {
					string none = "";
					string a = infile.nextValue();
					string b = infile.nextValue();

					while (a != none) {
						Point p;
						p.x = atoi(a.c_str()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
						p.y = atoi(b.c_str()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
						new_enemy.waypoints.push(p);
						a = infile.nextValue();
						b = infile.nextValue();
					}
				}
			}
			else if (infile.section == "enemygroup") {
				if (infile.key == "type") {
					new_group.category = infile.val;
				}
				else if (infile.key == "level") {
					new_group.levelmin = atoi(infile.nextValue().c_str());
					new_group.levelmax = atoi(infile.nextValue().c_str());
				}
				else if (infile.key == "location") {
					new_group.pos.x = atoi(infile.nextValue().c_str());
					new_group.pos.y = atoi(infile.nextValue().c_str());
					new_group.area.x = atoi(infile.nextValue().c_str());
					new_group.area.y = atoi(infile.nextValue().c_str());
				}
				else if (infile.key == "number") {
					new_group.numbermin = atoi(infile.nextValue().c_str());
					new_group.numbermax = atoi(infile.nextValue().c_str());
				}
				else if (infile.key == "chance") {
					new_group.chance = atoi(infile.nextValue().c_str()) / 100.0f;
					if (new_group.chance > 1.0f) {
						new_group.chance = 1.0f;
					}
					if (new_group.chance < 0.0f) {
						new_group.chance = 0.0f;
					}
				}
			}
			else if (infile.section == "npc") {
				if (infile.key == "type") {
					new_npc.id = infile.val;
				}
				else if (infile.key == "location") {
					new_npc.pos.x = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
					new_npc.pos.y = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
				}
			}
			else if (infile.section == "event") {
				if (infile.key == "type") {
					events[event_count-1].type = infile.val;
				}
				else if (infile.key == "location") {
					events[event_count-1].location.x = atoi(infile.nextValue().c_str());
					events[event_count-1].location.y = atoi(infile.nextValue().c_str());
					events[event_count-1].location.w = atoi(infile.nextValue().c_str());
					events[event_count-1].location.h = atoi(infile.nextValue().c_str());
				}
				else if (infile.key == "hotspot") {
					events[event_count-1].hotspot.x = atoi(infile.nextValue().c_str());
					events[event_count-1].hotspot.y = atoi(infile.nextValue().c_str());
					events[event_count-1].hotspot.w = atoi(infile.nextValue().c_str());
					events[event_count-1].hotspot.h = atoi(infile.nextValue().c_str());
				}
				else if (infile.key == "tooltip") {
					events[event_count-1].tooltip = msg->get(infile.val);
				}
				else if (infile.key == "power_path") {
					events[event_count-1].power_src.x = atoi(infile.nextValue().c_str());
					events[event_count-1].power_src.y = atoi(infile.nextValue().c_str());
					string dest = infile.nextValue();
					if (dest == "hero") {
						events[event_count-1].targetHero = true;
					}
					else {
						events[event_count-1].power_dest.x = atoi(dest.c_str());
						events[event_count-1].power_dest.y = atoi(infile.nextValue().c_str());
					}
				}
				else if (infile.key == "power_damage") {
					events[event_count-1].damagemin = atoi(infile.nextValue().c_str());
					events[event_count-1].damagemax = atoi(infile.nextValue().c_str());
				}
				else if (infile.key == "power_cooldown") {
					events[event_count-1].power_cooldown = atoi(infile.val.c_str());
				}
				else {
					// new event component
					Event_Component *e = &events[event_count-1].components[events[event_count-1].comp_num];
					e->type = infile.key;

					if (infile.key == "intermap") {
						e->s = infile.nextValue();
						e->x = atoi(infile.nextValue().c_str());
						e->y = atoi(infile.nextValue().c_str());
					}
					else if (infile.key == "mapmod") {
						e->s = infile.nextValue();
						e->x = atoi(infile.nextValue().c_str());
						e->y = atoi(infile.nextValue().c_str());
						e->z = atoi(infile.nextValue().c_str());

						// add repeating mapmods
						string repeat_val = infile.nextValue();
						while (repeat_val != "") {
							events[event_count-1].comp_num++;
							e = &events[event_count-1].components[events[event_count-1].comp_num];
							e->type = infile.key;
							e->s = repeat_val;
							e->x = atoi(infile.nextValue().c_str());
							e->y = atoi(infile.nextValue().c_str());
							e->z = atoi(infile.nextValue().c_str());

							repeat_val = infile.nextValue();
						}
					}
					else if (infile.key == "soundfx") {
						e->s = infile.val;
					}
					else if (infile.key == "loot") {
						e->s = infile.nextValue();
						e->x = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
						e->y = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
						e->z = atoi(infile.nextValue().c_str());

						// add repeating loot
						string repeat_val = infile.nextValue();
						while (repeat_val != "") {
							events[event_count-1].comp_num++;
							e = &events[event_count-1].components[events[event_count-1].comp_num];
							e->type = infile.key;
							e->s = repeat_val;
							e->x = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
							e->y = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
							e->z = atoi(infile.nextValue().c_str());

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

						// add repeating requires_status
						string repeat_val = infile.nextValue();
						while (repeat_val != "") {
							events[event_count-1].comp_num++;
							e = &events[event_count-1].components[events[event_count-1].comp_num];
							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
						string repeat_val = infile.nextValue();
						while (repeat_val != "") {
							events[event_count-1].comp_num++;
							e = &events[event_count-1].components[events[event_count-1].comp_num];
							e->type = infile.key;
							e->s = repeat_val;

							repeat_val = infile.nextValue();
						}
					}
					else if (infile.key == "requires_item") {
						e->x = atoi(infile.nextValue().c_str());

						// add repeating requires_item
						string repeat_val = infile.nextValue();
						while (repeat_val != "") {
							events[event_count-1].comp_num++;
							e = &events[event_count-1].components[events[event_count-1].comp_num];
							e->type = infile.key;
							e->x = atoi(repeat_val.c_str());

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

						// add repeating set_status
						string repeat_val = infile.nextValue();
						while (repeat_val != "") {
							events[event_count-1].comp_num++;
							e = &events[event_count-1].components[events[event_count-1].comp_num];
							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
						string repeat_val = infile.nextValue();
						while (repeat_val != "") {
							events[event_count-1].comp_num++;
							e = &events[event_count-1].components[events[event_count-1].comp_num];
							e->type = infile.key;
							e->s = repeat_val;

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

						// add repeating remove_item
						string repeat_val = infile.nextValue();
						while (repeat_val != "") {
							events[event_count-1].comp_num++;
							e = &events[event_count-1].components[events[event_count-1].comp_num];
							e->type = infile.key;
							e->x = atoi(repeat_val.c_str());

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

					events[event_count-1].comp_num++;
				}
			}
		}

		infile.close();

		// reached end of file.  Handle any final sections.
		if (enemy_awaiting_queue) {
			enemies.push(new_enemy);
			enemy_awaiting_queue = false;
		}
		if (npc_awaiting_queue) {
			npcs.push(new_npc);
			npc_awaiting_queue = false;
		}
		if (group_awaiting_queue){
			push_enemy_group(new_group);
			group_awaiting_queue = false;
		}
	}



	if (this->new_music) {
		loadMusic();
		this->new_music = false;
	}
	tset.load(this->tileset);

	return 0;
}
Ejemplo n.º 5
0
void GameStateConfig::readConfig () {
	//Load the menu configuration from file

	int offset_x = 0;
	int offset_y = 0;

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

			int x1 = popFirstInt(infile.val);
			int y1 = popFirstInt(infile.val);
			int x2 = popFirstInt(infile.val);
			int y2 = popFirstInt(infile.val);

			int setting_num = -1;

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

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

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

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

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

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

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

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

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

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

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

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

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

		}
		infile.close();
	}

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

	// Set positions of secondary key bindings
	for (unsigned int i = 29; i < 58; i++) {
		settings_key[i]->pos.x = settings_key[i-29]->pos.x + offset_x;
		settings_key[i]->pos.y = settings_key[i-29]->pos.y + offset_y;
	}
}
Ejemplo n.º 6
0
/**
 * NPCs are stored in simple config files
 *
 * @param npc_id Config file loaded at npcs/[npc_id].txt
 */
void NPC::load(const string& npc_id, int hero_level) {

	FileParser infile;
	ItemStack stack;

	string filename_portrait = "";

	if (infile.open("npcs/" + npc_id + ".txt")) {
		while (infile.next()) {
			if (infile.section == "dialog") {
				if (infile.new_section) {
					dialog.push_back(vector<Event_Component>());
				}
				Event_Component e;
				e.type = infile.key;
				if (infile.key == "requires_status")
					e.s = infile.val;
				else if (infile.key == "requires_not")
					e.s = infile.val;
				else if (infile.key == "requires_level")
					e.x = toInt(infile.val);
				else if (infile.key == "requires_not_level")
					e.x = toInt(infile.val);
				else if (infile.key == "requires_item")
					e.x = toInt(infile.val);
				else if (infile.key == "him" || infile.key == "her")
					e.s = msg->get(infile.val);
				else if (infile.key == "you")
					e.s = msg->get(infile.val);
				else if (infile.key == "reward_item") {
					// id,count
					e.x = toInt(infile.nextValue());
					e.y = toInt(infile.val);
				}
				else if (infile.key == "reward_xp")
					e.x = toInt(infile.val);
				else if (infile.key == "restore")
					e.s = infile.val;
				else if (infile.key == "reward_currency")
					e.x = toInt(infile.val);
				else if (infile.key == "remove_item")
					e.x = toInt(infile.val);
				else if (infile.key == "set_status")
					e.s = infile.val;
				else if (infile.key == "unset_status")
					e.s = infile.val;
				else if (infile.key == "voice") {
					e.x = loadSound(infile.val, NPC_VOX_QUEST);
				}
				else if (infile.key == "topic") {
					e.s = msg->get(infile.val);
				}
				else if (infile.key == "group") {
					e.s = infile.val;
				}

				dialog.back().push_back(e);
			}
			else {
				filename = npc_id;
				if (infile.key == "name") {
					name = msg->get(infile.val);
				}
				else if (infile.key == "level") {
					if (infile.val == "hero")
						level = hero_level;
					else
						level = toInt(infile.val);
				}
				else if (infile.key == "gfx") {
					gfx = infile.val;
				}

				// handle talkers
				else if (infile.key == "talker") {
					if (infile.val == "true") talker = true;
				}
				else if (infile.key == "portrait") {
					filename_portrait = infile.val;
				}

				// handle vendors
				else if (infile.key == "vendor") {
					if (infile.val == "true") vendor = true;
				}
				else if (infile.key == "constant_stock") {
					stack.quantity = 1;
					while (infile.val != "") {
						stack.item = toInt(infile.nextValue());
						stock.add(stack);
					}
				}
				else if (infile.key == "status_stock") {
					if (camp->checkStatus(infile.nextValue())) {
						stack.quantity = 1;
						while (infile.val != "") {
							stack.item = toInt(infile.nextValue());
							stock.add(stack);
						}
					}
				}

				// handle vocals
				else if (infile.key == "vox_intro") {
					loadSound(infile.val, NPC_VOX_INTRO);
				}
			}
		}
		infile.close();
	}
	loadGraphics(filename_portrait);
}
Ejemplo n.º 7
0
/**
 * load a statblock, typically for an enemy definition
 */
void StatBlock::load(const string& filename) {
	FileParser infile;
	if (!infile.open(mods->locate(filename))) {
		fprintf(stderr, "Unable to open %s!\n", filename.c_str());
		return;
	}

	int num = 0;
	while (infile.next()) {
		if (isInt(infile.val)) num = toInt(infile.val);
		bool valid = false;

		for (unsigned int i=0; i<ELEMENTS.size(); i++) {
			if (infile.key == "vulnerable_" + ELEMENTS[i].name) {
				vulnerable[i] = vulnerable_base[i] = num;
				valid = true;
			}
		}

		if (infile.key == "name") name = msg->get(infile.val);
		else if (infile.key == "humanoid") {
			if (infile.val == "true") humanoid = true;
		}
		else if (infile.key == "sfx_prefix") sfx_prefix = infile.val;

		else if (infile.key == "level") level = num;

		// enemy death rewards and events
		else if (infile.key == "xp") xp = num;
		else if (infile.key == "loot") {

			// loot entries format:
			// loot=[id],[percent_chance]

			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());
			loot.push_back(el);
		}
		else if (infile.key == "defeat_status") defeat_status = infile.val;
		else if (infile.key == "first_defeat_loot") first_defeat_loot = num;
		else if (infile.key == "quest_loot") {
			quest_loot_requires = infile.nextValue();
			quest_loot_not = infile.nextValue();
			quest_loot_id = toInt(infile.nextValue());
		}
		// combat stats
		else if (infile.key == "hp") hp = hp_base = maxhp = num;
		else if (infile.key == "mp") mp = mp_base = maxmp = num;
		else if (infile.key == "cooldown") cooldown = parse_duration(infile.val);
		else if (infile.key == "accuracy") accuracy = accuracy_base = num;
		else if (infile.key == "avoidance") avoidance = avoidance_base = num;
		else if (infile.key == "dmg_melee_min") dmg_melee_min = num;
		else if (infile.key == "dmg_melee_max") dmg_melee_max = num;
		else if (infile.key == "dmg_ment_min") dmg_ment_min = num;
		else if (infile.key == "dmg_ment_max") dmg_ment_max = num;
		else if (infile.key == "dmg_ranged_min") dmg_ranged_min = num;
		else if (infile.key == "dmg_ranged_max") dmg_ranged_max = num;
		else if (infile.key == "absorb_min") absorb_min = num;
		else if (infile.key == "absorb_max") absorb_max = num;
		else if (infile.key == "poise") poise = poise_base = num;

		// behavior stats
		else if (infile.key == "flying") {
			if (num == 1) flying = true;
		}
		else if (infile.key == "intangible") {
			if (num == 1) intangible = true;
		}
		else if (infile.key == "facing") {
			if (num == 0) facing = false;
		}

		else if (infile.key == "waypoint_pause") waypoint_pause = num;

		else if (infile.key == "speed") speed = speed_default = num;
		else if (infile.key == "dspeed") dspeed = dspeed_default = num;
		else if (infile.key == "turn_delay") turn_delay = num;
		else if (infile.key == "chance_pursue") chance_pursue = num;
		else if (infile.key == "chance_flee") chance_flee = num;

		else if (infile.key == "chance_melee_phys") power_chance[MELEE_PHYS] = num;
		else if (infile.key == "chance_melee_ment") power_chance[MELEE_MENT] = num;
		else if (infile.key == "chance_ranged_phys") power_chance[RANGED_PHYS] = num;
		else if (infile.key == "chance_ranged_ment") power_chance[RANGED_MENT] = num;
		else if (infile.key == "power_melee_phys") power_index[MELEE_PHYS] = num;
		else if (infile.key == "power_melee_ment") power_index[MELEE_MENT] = num;
		else if (infile.key == "power_ranged_phys") power_index[RANGED_PHYS] = num;
		else if (infile.key == "power_ranged_ment") power_index[RANGED_MENT] = num;
		else if (infile.key == "power_beacon") power_index[BEACON] = num;
		else if (infile.key == "cooldown_melee_phys") power_cooldown[MELEE_PHYS] = parse_duration(infile.val);
		else if (infile.key == "cooldown_melee_ment") power_cooldown[MELEE_MENT] = parse_duration(infile.val);
		else if (infile.key == "cooldown_ranged_phys") power_cooldown[RANGED_PHYS] = parse_duration(infile.val);
		else if (infile.key == "cooldown_ranged_ment") power_cooldown[RANGED_MENT] = parse_duration(infile.val);
		else if (infile.key == "power_on_hit") power_index[ON_HIT] = num;
		else if (infile.key == "power_on_death") power_index[ON_DEATH] = num;
		else if (infile.key == "power_on_half_dead") power_index[ON_HALF_DEAD] = num;
		else if (infile.key == "power_on_debuff") power_index[ON_DEBUFF] = num;
		else if (infile.key == "power_on_join_combat") power_index[ON_JOIN_COMBAT] = num;
		else if (infile.key == "chance_on_hit") power_chance[ON_HIT] = num;
		else if (infile.key == "chance_on_death") power_chance[ON_DEATH] = num;
		else if (infile.key == "chance_on_half_dead") power_chance[ON_HALF_DEAD] = num;
		else if (infile.key == "chance_on_debuff") power_chance[ON_DEBUFF] = num;
		else if (infile.key == "chance_on_join_combat") power_chance[ON_JOIN_COMBAT] = num;
		else if (infile.key == "cooldown_hit") cooldown_hit = num;

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

		else if (infile.key == "melee_range") melee_range = num;
		else if (infile.key == "threat_range") threat_range = num;

		// animation stats
		else if (infile.key == "melee_weapon_power") melee_weapon_power = num;
		else if (infile.key == "mental_weapon_power") mental_weapon_power = num;
		else if (infile.key == "ranged_weapon_power") ranged_weapon_power = num;

		else if (infile.key == "animations") animations = infile.val;

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

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

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

	// sort loot table
	std::sort(loot.begin(), loot.end(), sortLoot);
}
Ejemplo n.º 8
0
MenuManager::MenuManager(PowerManager *_powers, StatBlock *_stats, CampaignManager *_camp, ItemManager *_items)
	: icons(NULL)
	, powers(_powers)
	, stats(_stats)
	, camp(_camp)
	, tip_buf()
	, key_lock(false)
	, dragging(0)
	, drag_stack()
	, drag_power(0)
	, drag_src(0)
	, done(false)
	/*std::vector<Menu*> menus;*/
	, items(_items)
	, inv(NULL)
	, pow(NULL)
	, chr(NULL)
	, log(NULL)
	, hudlog(NULL)
	, act(NULL)
	, hp(NULL)
	, mp(NULL)
	, xp(NULL)
	, tip(NULL)
	, mini(NULL)
	, npc(NULL)
	, enemy(NULL)
	, vendor(NULL)
	, talker(NULL)
	, exit(NULL)
	, effects(NULL)
	, stash(NULL)
	, pause(false)
	, menus_open(false)
	, drop_stack()
{
	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(this, 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]
	npc = new MenuNPCActions();
	menus.push_back(npc); // menus[16]

	tip = new WidgetTooltip();

	// Load the menu layout and sound effects from menus/menus.txt
	FileParser infile;
	if (infile.open(mods->locate("menus/menus.txt"))) {

		int menu_index = -1;

		while (infile.next()) {

			if (infile.key == "id") {

				/* finalize previously parsed menu */
				if (menu_index != -1)
					menus[menu_index]->align();

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

			}

			if (menu_index == -1)
				continue;

			if (infile.key == "layout") {

				infile.val = infile.val + ',';
				int x = eatFirstInt(infile.val, ',');
				int y = eatFirstInt(infile.val, ',');
				int w = eatFirstInt(infile.val, ',');
				int h = eatFirstInt(infile.val, ',');

				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;

			} else if (infile.key == "align") {
				menus[menu_index]->alignment = infile.val;
			} else if (infile.key == "soundfx_open") {
				menus[menu_index]->sfx_open = snd->load(infile.val, "MenuManager open tab");
			} else if (infile.key == "soundfx_close") {
				menus[menu_index]->sfx_close = snd->load(infile.val, "MenuManager close tab");
			}

		}

		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;

	done = false;

	closeAll(); // make sure all togglable menus start closed
}
Ejemplo n.º 9
0
/**
 * Load a specific items file
 *
 * @param filename The full path and name of the file to load
 */
void ItemManager::load(const string& filename) {
	FileParser infile;
	int id = 0;
	bool id_line;
	string s;

	if (infile.open(filename)) {

		while (infile.next()) {
			if (infile.key == "id") {
				id_line = true;
				id = toInt(infile.val);
				if (id > 0 && id < (INT_MAX-1) && 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 || id > (INT_MAX-1)) {
				if (id_line) fprintf(stderr, "Item index %d out of bounds 1-%d, skipping\n", id, 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_small = toInt(infile.nextValue());
				items[id].icon_large = 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") {
				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) > -1 && toInt(infile.val) < (INT_MAX-1)) {
					items[id].power = toInt(infile.val);
				}
				else fprintf(stderr, "Power index %d inside item %d definition out of bounds 0-%d, skipping item\n", toInt(infile.val), 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();
	} else fprintf(stderr, "Unable to open %s!\n", filename.c_str());
}
Ejemplo n.º 10
0
void TileSet::load(const std::string& filename) {
	if (current_map == filename) return;

	reset();

	FileParser infile;
	string img;

	if (infile.open(mods->locate("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].src.x = eatFirstInt(infile.val, ',');
				tiles[index].src.y = eatFirstInt(infile.val, ',');
				tiles[index].src.w = eatFirstInt(infile.val, ',');
				tiles[index].src.h = eatFirstInt(infile.val, ',');
				tiles[index].offset.x = eatFirstInt(infile.val, ',');
				tiles[index].offset.y = eatFirstInt(infile.val, ',');
			}
			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);
	}  else fprintf(stderr, "Unable to open tilesetdefs/%s!\n", filename.c_str());

	current_map = filename;
}
Ejemplo n.º 11
0
/**
 * Loads a given power tree and sets up the menu accordingly
 */
void MenuPowers::loadPowerTree(const std::string &filename) {
	// only load the power tree once per instance
	if (tree_loaded) return;

	// First, parse the power tree file

	FileParser infile;
	// @CLASS MenuPowers: Power tree layout|Description of powers/trees/
	if (infile.open(filename)) {
		while (infile.next()) {
			if (infile.new_section) {
				// for sections that are stored in collections, add a new object here
				if (infile.section == "power") {
					slots.push_back(NULL);
					upgradeButtons.push_back(NULL);
					power_cell.push_back(Power_Menu_Cell());
				}
				else if (infile.section == "upgrade")
					power_cell_upgrade.push_back(Power_Menu_Cell());
				else if (infile.section == "tab")
					tabs.push_back(Power_Menu_Tab());
			}

			if (infile.section == "") {
				// @ATTR background|string|Filename of the default background image
				if (infile.key == "background") default_background = infile.val;
			}
			else if (infile.section == "tab")
				loadTab(infile);
			else if (infile.section == "power")
				loadPower(infile);
			else if (infile.section == "upgrade")
				loadUpgrade(infile);
		}
		infile.close();
	}

	// save a copy of the base level powers, as they get overwritten during upgrades
	power_cell_base = power_cell;

	// store the appropriate level for all upgrades
	for (unsigned i=0; i<power_cell_upgrade.size(); ++i) {
		for (unsigned j=0; j<power_cell_base.size(); j++) {
			std::vector<short>::iterator it = std::find(power_cell_base[j].upgrades.begin(), power_cell_base[j].upgrades.end(), power_cell_upgrade[i].id);
			if (it != power_cell_base[j].upgrades.end()) {
				power_cell_upgrade[i].upgrade_level = static_cast<short>(std::distance(power_cell_base[j].upgrades.begin(), it) + 2);
				break;
			}
		}
	}

	// combine base and upgrade powers into a single list
	for (unsigned i=0; i<power_cell_base.size(); ++i) {
		power_cell_all.push_back(power_cell_base[i]);
	}
	for (unsigned i=0; i<power_cell_upgrade.size(); ++i) {
		power_cell_all.push_back(power_cell_upgrade[i]);
	}

	// load any specified graphics into the tree_surf vector
	Image *graphics;
	if (tabs.empty() && default_background != "") {
		graphics = render_device->loadImage(default_background);
		if (graphics) {
			tree_surf.push_back(graphics->createSprite());
			graphics->unref();
		}
	}
	else {
		for (unsigned int i = 0; i < tabs.size(); ++i) {
			if (tabs[i].background == "")
				tabs[i].background = default_background;

			if (tabs[i].background == "") {
				tree_surf.push_back(NULL);
				continue;
			}

			graphics = render_device->loadImage(tabs[i].background);
			if (graphics) {
				tree_surf.push_back(graphics->createSprite());
				graphics->unref();
			}
			else {
				tree_surf.push_back(NULL);
			}
		}
	}

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

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

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

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

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

	applyPowerUpgrades();

	tree_loaded = true;

	align();
}
Ejemplo n.º 12
0
/**
 * load
 */
int MapRenderer::load(string filename) {
	FileParser infile;
	string val;
	string data_format;
	maprow *cur_layer;

	clearEvents();
	clearLayers();
	clearQueues();

	cur_layer = NULL;
	show_tooltip = false;

	if (!infile.open(mods->locate("maps/" + filename))) {
		cerr << "Unable to open maps/" << filename << endl;
		return 0;
	}

	while (infile.next()) {
		if (infile.new_section) {
			data_format = "dec"; // default

			if (enemy_awaiting_queue) {
				enemies.push(new_enemy);
				enemy_awaiting_queue = false;
			}
			if (npc_awaiting_queue) {
				npcs.push(new_npc);
				npc_awaiting_queue = false;
			}
			if (group_awaiting_queue) {
				push_enemy_group(new_group);
				group_awaiting_queue = false;
			}

			// for sections that are stored in collections, add a new object here
			if (infile.section == "enemy") {
				new_enemy.clear();
				enemy_awaiting_queue = true;
			}
			else if (infile.section == "enemygroup") {
				new_group.clear();
				group_awaiting_queue = true;
			}
			else if (infile.section == "npc") {
				new_npc.clear();
				npc_awaiting_queue = true;
			}
			else if (infile.section == "event") {
				events.push_back(Map_Event());
			}

		}
		if (infile.section == "header") {
			if (infile.key == "title") {
				this->title = msg->get(infile.val);
			}
			else if (infile.key == "width") {
				this->w = toInt(infile.val);
			}
			else if (infile.key == "height") {
				this->h = toInt(infile.val);
			}
			else if (infile.key == "tileset") {
				this->tileset = infile.val;
			}
			else if (infile.key == "music") {
				if (this->music_filename == infile.val) {
					this->new_music = false;
				}
				else {
					this->music_filename = infile.val;
					this->new_music = true;
				}
			}
			else if (infile.key == "location") {
				spawn.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
				spawn.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
				spawn_dir = toInt(infile.nextValue());
			}
		}
		else if (infile.section == "layer") {
			if (infile.key == "type") {
				cur_layer = new maprow[w];
				if (infile.val == "background") background = cur_layer;
				else if (infile.val == "fringe") fringe = cur_layer;
				else if (infile.val == "object") object = cur_layer;
				else if (infile.val == "foreground") foreground = cur_layer;
				else if (infile.val == "collision") collision = cur_layer;
			}
			else if (infile.key == "format") {
				data_format = infile.val;
			}
			else if (infile.key == "data") {
				// layer map data handled as a special case
				// The next h lines must contain layer data.  TODO: err
				for (int j=0; j<h; j++) {
					val = infile.getRawLine() + ',';
					for (int i=0; i<w; i++)
						cur_layer[i][j] = eatFirstInt(val, ',', (data_format == "hex" ? std::hex : std::dec));
				}
				if (cur_layer == collision)
					collider.setmap(collision, w, h);
			}
		}
		else if (infile.section == "enemy") {
			if (infile.key == "type") {
				new_enemy.type = infile.val;
			}
			else if (infile.key == "location") {
				new_enemy.pos.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
				new_enemy.pos.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
			}
			else if (infile.key == "direction") {
				new_enemy.direction = toInt(infile.val);
			}
			else if (infile.key == "waypoints") {
				string none = "";
				string a = infile.nextValue();
				string b = infile.nextValue();

				while (a != none) {
					Point p;
					p.x = toInt(a) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
					p.y = toInt(b) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
					new_enemy.waypoints.push(p);
					a = infile.nextValue();
					b = infile.nextValue();
				}
			} else if (infile.key == "wander_area") {
				new_enemy.wander = true;
				new_enemy.wander_area.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
				new_enemy.wander_area.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
				new_enemy.wander_area.w = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
				new_enemy.wander_area.h = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE / 2;
			}
		}
		else if (infile.section == "enemygroup") {
			if (infile.key == "type") {
				new_group.category = infile.val;
			}
			else if (infile.key == "level") {
				new_group.levelmin = toInt(infile.nextValue());
				new_group.levelmax = toInt(infile.nextValue());
			}
			else if (infile.key == "location") {
				new_group.pos.x = toInt(infile.nextValue());
				new_group.pos.y = toInt(infile.nextValue());
				new_group.area.x = toInt(infile.nextValue());
				new_group.area.y = toInt(infile.nextValue());
			}
			else if (infile.key == "number") {
				new_group.numbermin = toInt(infile.nextValue());
				new_group.numbermax = toInt(infile.nextValue());
			}
			else if (infile.key == "chance") {
				new_group.chance = toInt(infile.nextValue()) / 100.0f;
				if (new_group.chance > 1.0f) {
					new_group.chance = 1.0f;
				}
				if (new_group.chance < 0.0f) {
					new_group.chance = 0.0f;
				}
			}
		}
		else if (infile.section == "npc") {
			if (infile.key == "type") {
				new_npc.id = infile.val;
			}
			else if (infile.key == "location") {
				new_npc.pos.x = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
				new_npc.pos.y = toInt(infile.nextValue()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
			}
		}
		else if (infile.section == "event") {
			if (infile.key == "type") {
				events.back().type = infile.val;
			}
			else if (infile.key == "location") {
				events.back().location.x = toInt(infile.nextValue());
				events.back().location.y = toInt(infile.nextValue());
				events.back().location.w = toInt(infile.nextValue());
				events.back().location.h = toInt(infile.nextValue());
			}
			else if (infile.key == "hotspot") {
				if (infile.val == "location") {
					events.back().hotspot.x = events.back().location.x;
					events.back().hotspot.y = events.back().location.y;
					events.back().hotspot.w = events.back().location.w;
					events.back().hotspot.h = events.back().location.h;
				}
				else {
					events.back().hotspot.x = toInt(infile.nextValue());
					events.back().hotspot.y = toInt(infile.nextValue());
					events.back().hotspot.w = toInt(infile.nextValue());
					events.back().hotspot.h = toInt(infile.nextValue());
				}
			}
			else if (infile.key == "tooltip") {
				events.back().tooltip = msg->get(infile.val);
			}
			else if (infile.key == "power_path") {
				events.back().power_src.x = toInt(infile.nextValue());
				events.back().power_src.y = toInt(infile.nextValue());
				string dest = infile.nextValue();
				if (dest == "hero") {
					events.back().targetHero = true;
				}
				else {
					events.back().power_dest.x = toInt(dest);
					events.back().power_dest.y = toInt(infile.nextValue());
				}
			}
			else if (infile.key == "power_damage") {
				events.back().damagemin = toInt(infile.nextValue());
				events.back().damagemax = toInt(infile.nextValue());
			}
			else if (infile.key == "cooldown") {
				events.back().cooldown = toInt(infile.val);
			}
			else {
				// new event component
				Event_Component *e = &(events.back()).components[events.back().comp_num];
				e->type = infile.key;

				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
					string repeat_val = infile.nextValue();
					while (repeat_val != "") {
						events.back().comp_num++;
						e = &events.back().components[events.back().comp_num];
						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.val;
				}
				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;
					e->z = toInt(infile.nextValue());

					// add repeating loot
					string repeat_val = infile.nextValue();
					while (repeat_val != "") {
						events.back().comp_num++;
						e = &events.back().components[events.back().comp_num];
						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;
						e->z = toInt(infile.nextValue());

						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
					string repeat_val = infile.nextValue();
					while (repeat_val != "") {
						events.back().comp_num++;
						e = &events.back().components[events.back().comp_num];
						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
					string repeat_val = infile.nextValue();
					while (repeat_val != "") {
						events.back().comp_num++;
						e = &events.back().components[events.back().comp_num];
						e->type = infile.key;
						e->s = repeat_val;

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

					// add repeating requires_item
					string repeat_val = infile.nextValue();
					while (repeat_val != "") {
						events.back().comp_num++;
						e = &events.back().components[events.back().comp_num];
						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
					string repeat_val = infile.nextValue();
					while (repeat_val != "") {
						events.back().comp_num++;
						e = &events.back().components[events.back().comp_num];
						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
					string repeat_val = infile.nextValue();
					while (repeat_val != "") {
						events.back().comp_num++;
						e = &events.back().components[events.back().comp_num];
						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
					string repeat_val = infile.nextValue();
					while (repeat_val != "") {
						events.back().comp_num++;
						e = &events.back().components[events.back().comp_num];
						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
					string repeat_val = infile.nextValue();
					while (repeat_val != "") {
						events.back().comp_num++;
						e = &events.back().components[events.back().comp_num];
						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();
					}
				}
				events.back().comp_num++;
			}
		}
	}

	infile.close();

	// reached end of file.  Handle any final sections.
	if (enemy_awaiting_queue) {
		enemies.push(new_enemy);
		enemy_awaiting_queue = false;
	}
	if (npc_awaiting_queue) {
		npcs.push(new_npc);
		npc_awaiting_queue = false;
	}
	if (group_awaiting_queue){
		push_enemy_group(new_group);
		group_awaiting_queue = false;
	}

	if (this->new_music) {
		loadMusic();
		this->new_music = false;
	}
	tset.load(this->tileset);

	// some events automatically trigger when the map loads
	// e.g. change map state based on campaign status
	executeOnLoadEvents();

	return 0;
}
Ejemplo n.º 13
0
/**
 * load a statblock, typically for an enemy definition
 */
void StatBlock::load(const string& filename) {
	FileParser infile;
	int num = 0;

	if (infile.open(mods->locate(filename))) {
		while (infile.next()) {
			if (isInt(infile.val)) num = toInt(infile.val);

			if (infile.key == "name") name = msg->get(infile.val);
			else if (infile.key == "humanoid") {
				if (infile.val == "true") humanoid = true;
			}
			else if (infile.key == "sfx_prefix") sfx_prefix = infile.val;
			else if (infile.key == "gfx_prefix") gfx_prefix = infile.val;

			else if (infile.key == "level") level = num;

			// enemy death rewards and events
			else if (infile.key == "xp") xp = num;
			else if (infile.key == "loot_chance") loot_chance = num;
			else if (infile.key == "item_class") {
				string str;
				while ((str = infile.nextValue()) != "") {
					if (!isInt(str)) {
						item_classes.push_back(str);
						item_class_prob.push_back(1);
						item_class_prob_sum++;
					}
					else {
						num = toInt(str);
						item_class_prob[item_classes.size()-1] = num;
						item_class_prob_sum += num - 1; // one was already added, so add one less
					}
				}
			}
			else if (infile.key == "defeat_status") defeat_status = infile.val;
			else if (infile.key == "first_defeat_loot") first_defeat_loot = num;
			else if (infile.key == "quest_loot") {
				quest_loot_requires = infile.nextValue();
				quest_loot_not = infile.nextValue();
				quest_loot_id = toInt(infile.nextValue());
			}
			// combat stats
			else if (infile.key == "hp") {
				hp = num;
				maxhp = num;
			}
			else if (infile.key == "mp") {
				mp = num;
				maxmp = num;
			}
			else if (infile.key == "cooldown") cooldown = num;
			else if (infile.key == "accuracy") accuracy = num;
			else if (infile.key == "avoidance") avoidance = num;
			else if (infile.key == "dmg_melee_min") dmg_melee_min = num;
			else if (infile.key == "dmg_melee_max") dmg_melee_max = num;
			else if (infile.key == "dmg_ment_min") dmg_ment_min = num;
			else if (infile.key == "dmg_ment_max") dmg_ment_max = num;
			else if (infile.key == "dmg_ranged_min") dmg_ranged_min = num;
			else if (infile.key == "dmg_ranged_max") dmg_ranged_max = num;
			else if (infile.key == "absorb_min") absorb_min = num;
			else if (infile.key == "absorb_max") absorb_max = num;

			// behavior stats
			else if (infile.key == "flying") {
				if (num == 1) flying = true;
			}
			else if (infile.key == "intangible") {
				if (num == 1) intangible = true;
			}
			else if (infile.key == "facing") {
				if (num == 0) facing = false;
			}

			else if (infile.key == "waypoint_pause") waypoint_pause = num;

			else if (infile.key == "speed") speed = num;
			else if (infile.key == "dspeed") dspeed = num;
			else if (infile.key == "turn_delay") turn_delay = num;
			else if (infile.key == "chance_pursue") chance_pursue = num;
			else if (infile.key == "chance_flee") chance_flee = num;

			else if (infile.key == "chance_melee_phys") power_chance[MELEE_PHYS] = num;
			else if (infile.key == "chance_melee_ment") power_chance[MELEE_MENT] = num;
			else if (infile.key == "chance_ranged_phys") power_chance[RANGED_PHYS] = num;
			else if (infile.key == "chance_ranged_ment") power_chance[RANGED_MENT] = num;
			else if (infile.key == "power_melee_phys") power_index[MELEE_PHYS] = num;
			else if (infile.key == "power_melee_ment") power_index[MELEE_MENT] = num;
			else if (infile.key == "power_ranged_phys") power_index[RANGED_PHYS] = num;
			else if (infile.key == "power_ranged_ment") power_index[RANGED_MENT] = num;
			else if (infile.key == "power_beacon") power_index[BEACON] = num;
			else if (infile.key == "cooldown_melee_phys") power_cooldown[MELEE_PHYS] = num;
			else if (infile.key == "cooldown_melee_ment") power_cooldown[MELEE_MENT] = num;
			else if (infile.key == "cooldown_ranged_phys") power_cooldown[RANGED_PHYS] = num;
			else if (infile.key == "cooldown_ranged_ment") power_cooldown[RANGED_MENT] = num;
			else if (infile.key == "power_on_hit") power_index[ON_HIT] = num;
			else if (infile.key == "power_on_death") power_index[ON_DEATH] = num;
			else if (infile.key == "power_on_half_dead") power_index[ON_HALF_DEAD] = num;
			else if (infile.key == "power_on_debuff") power_index[ON_DEBUFF] = num;
			else if (infile.key == "power_on_join_combat") power_index[ON_JOIN_COMBAT] = num;
			else if (infile.key == "chance_on_hit") power_chance[ON_HIT] = num;
			else if (infile.key == "chance_on_death") power_chance[ON_DEATH] = num;
			else if (infile.key == "chance_on_half_dead") power_chance[ON_HALF_DEAD] = num;
			else if (infile.key == "chance_on_debuff") power_chance[ON_DEBUFF] = num;
			else if (infile.key == "chance_on_join_combat") power_chance[ON_JOIN_COMBAT] = num;


			else if (infile.key == "melee_range") melee_range = num;
			else if (infile.key == "threat_range") threat_range = num;

			// animation stats
			else if (infile.key == "melee_weapon_power") melee_weapon_power = num;
			else if (infile.key == "mental_weapon_power") mental_weapon_power = num;
			else if (infile.key == "ranged_weapon_power") ranged_weapon_power = num;

			else if (infile.key == "animations") animations = infile.val;
			else if (infile.key == "animation_speed") animationSpeed = num;

			// hp countdown
			else if (infile.key == "hp_countdown_ticks") hp_countdown_ticks = num;

			// hide enemy HP bar
			else if (infile.key == "suppress_hp") suppress_hp = num;

			for (unsigned int i=0; i<ELEMENTS.size(); i++) {
				if (infile.key == "vulnerable_" + ELEMENTS[i].name) vulnerable[i] = num;
			}
		}
		infile.close();
	} else fprintf(stderr, "Unable to open %s!\n", filename.c_str());
}
Ejemplo n.º 14
0
void loadMiscSettings() {
	// reset to defaults
	ELEMENTS.clear();
	EQUIP_FLAGS.clear();
	HERO_CLASSES.clear();
	FRAME_W = 0;
	FRAME_H = 0;
	IGNORE_TEXTURE_FILTER = false;
	ICON_SIZE = 0;
	AUTOPICKUP_CURRENCY = false;
	MAX_ABSORB = 90;
	MAX_RESIST = 90;
	MAX_BLOCK = 100;
	MAX_AVOIDANCE = 99;
	MIN_ABSORB = 0;
	MIN_RESIST = 0;
	MIN_BLOCK = 0;
	MIN_AVOIDANCE = 0;
	CURRENCY = "Gold";
	VENDOR_RATIO = 0.25;
	DEATH_PENALTY = true;
	DEATH_PENALTY_PERMADEATH = false;
	DEATH_PENALTY_CURRENCY = 50;
	DEATH_PENALTY_XP = 0;
	DEATH_PENALTY_XP_CURRENT = 0;
	DEATH_PENALTY_ITEM = false;
	MENUS_PAUSE = false;
	SAVE_HPMP = false;
	ENABLE_PLAYGAME = false;
	CORPSE_TIMEOUT = 60*MAX_FRAMES_PER_SEC;
	SELL_WITHOUT_VENDOR = true;
	AIM_ASSIST = 0;
	SAVE_PREFIX = "";
	WINDOW_TITLE = "Flare";
	SOUND_FALLOFF = 15;
	PARTY_EXP_PERCENTAGE = 100;
	ENABLE_ALLY_COLLISION_AI = true;
	ENABLE_ALLY_COLLISION = true;
	CURRENCY_ID = 1;
	INTERACT_RANGE = 3;
	SAVE_ONLOAD = true;
	SAVE_ONEXIT = true;
	TOOLTIP_OFFSET = 0;
	TOOLTIP_WIDTH = 1;
	TOOLTIP_MARGIN = 0;
	TOOLTIP_MARGIN_NPC = 0;

	FileParser infile;
	// @CLASS Settings: Misc|Description of engine/misc.txt
	if (infile.open("engine/misc.txt")) {
		while (infile.next()) {
			// @ATTR save_hpmp|boolean|When saving the game, keep the hero's current HP and MP.
			if (infile.key == "save_hpmp")
				SAVE_HPMP = toBool(infile.val);
			// @ATTR corpse_timeout|duration|Duration that a corpse can exist on the map in 'ms' or 's'.
			else if (infile.key == "corpse_timeout")
				CORPSE_TIMEOUT = parse_duration(infile.val);
			// @ATTR sell_without_vendor|boolean|Allows selling items when not at a vendor via CTRL-Click.
			else if (infile.key == "sell_without_vendor")
				SELL_WITHOUT_VENDOR = toBool(infile.val);
			// @ATTR aim_assist|integer|The pixel offset for powers that use aim_assist.
			else if (infile.key == "aim_assist")
				AIM_ASSIST = toInt(infile.val);
			// @ATTR window_title|string|Sets the text in the window's titlebar.
			else if (infile.key == "window_title")
				WINDOW_TITLE = infile.val;
			// @ATTR save_prefix|string|A string that's prepended to save filenames to prevent conflicts between mods.
			else if (infile.key == "save_prefix")
				SAVE_PREFIX = infile.val;
			// @ATTR sound_falloff|integer|The maximum radius in tiles that any single sound is audible.
			else if (infile.key == "sound_falloff")
				SOUND_FALLOFF = toInt(infile.val);
			// @ATTR party_exp_percentage|integer|The percentage of XP given to allies.
			else if (infile.key == "party_exp_percentage")
				PARTY_EXP_PERCENTAGE = toInt(infile.val);
			// @ATTR enable_ally_collision|boolean|Allows allies to block the player's path.
			else if (infile.key == "enable_ally_collision")
				ENABLE_ALLY_COLLISION = toBool(infile.val);
			// @ATTR enable_ally_collision_ai|boolean|Allows allies to block the path of other AI creatures.
			else if (infile.key == "enable_ally_collision_ai")
				ENABLE_ALLY_COLLISION_AI = toBool(infile.val);
			else if (infile.key == "currency_id") {
				// @ATTR currency_id|integer|An item id that will be used as currency.
				CURRENCY_ID = toInt(infile.val);
				if (CURRENCY_ID < 1) {
					CURRENCY_ID = 1;
					logError("Settings: Currency ID below the minimum allowed value. Resetting it to %d", CURRENCY_ID);
				}
			}
			// @ATTR interact_range|float|Distance where the player can interact with objects and NPCs.
			else if (infile.key == "interact_range")
				INTERACT_RANGE = toFloat(infile.val);
			// @ATTR menus_pause|boolean|Opening any menu will pause the game.
			else if (infile.key == "menus_pause")
				MENUS_PAUSE = toBool(infile.val);
			// @ATTR save_onload|boolean|Save the game upon changing maps.
			else if (infile.key == "save_onload")
				SAVE_ONLOAD = toBool(infile.val);
			// @ATTR save_onexit|boolean|Save the game upon quitting to the title screen or desktop.
			else if (infile.key == "save_onexit")
				SAVE_ONEXIT = toBool(infile.val);

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

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

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

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

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

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

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

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

	// @CLASS Settings: Elements|Description of engine/elements.txt
	if (infile.open("engine/elements.txt")) {
		while (infile.next()) {
			if (infile.new_section) {
				if (infile.section == "element") {
					// check if the previous element and remove it if there is no identifier
					if (!ELEMENTS.empty() && ELEMENTS.back().id == "") {
						ELEMENTS.pop_back();
					}
					ELEMENTS.resize(ELEMENTS.size()+1);
				}
			}

			if (ELEMENTS.empty() || infile.section != "element")
				continue;

			// @ATTR element.id|string|An identifier for this element.
			if (infile.key == "id") ELEMENTS.back().id = infile.val;
			// @ATTR element.name|string|The displayed name of this element.
			else if (infile.key == "name") ELEMENTS.back().name = msg->get(infile.val);

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

		// check if the last element and remove it if there is no identifier
		if (!ELEMENTS.empty() && ELEMENTS.back().id == "") {
			ELEMENTS.pop_back();
		}
	}

	// @CLASS Settings: Equip flags|Description of engine/equip_flags.txt
	if (infile.open("engine/equip_flags.txt")) {
		while (infile.next()) {
			if (infile.new_section) {
				if (infile.section == "flag") {
					// check if the previous flag and remove it if there is no identifier
					if (!EQUIP_FLAGS.empty() && EQUIP_FLAGS.back().id == "") {
						EQUIP_FLAGS.pop_back();
					}
					EQUIP_FLAGS.resize(EQUIP_FLAGS.size()+1);
				}
			}

			if (EQUIP_FLAGS.empty() || infile.section != "flag")
				continue;

			// @ATTR flag.id|string|An identifier for this equip flag.
			if (infile.key == "id") EQUIP_FLAGS.back().id = infile.val;
			// @ATTR flag.name|string|The displayed name of this equip flag.
			else if (infile.key == "name") EQUIP_FLAGS.back().name = infile.val;

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

		// check if the last flag and remove it if there is no identifier
		if (!EQUIP_FLAGS.empty() && EQUIP_FLAGS.back().id == "") {
			EQUIP_FLAGS.pop_back();
		}
	}

	// @CLASS Settings: Classes|Description of engine/classes.txt
	if (infile.open("engine/classes.txt")) {
		while (infile.next()) {
			if (infile.new_section) {
				if (infile.section == "class") {
					// check if the previous class and remove it if there is no name
					if (!HERO_CLASSES.empty() && HERO_CLASSES.back().name == "") {
						HERO_CLASSES.pop_back();
					}
					HERO_CLASSES.resize(HERO_CLASSES.size()+1);
				}
			}

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

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

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

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

		// check if the last class and remove it if there is no name
		if (!HERO_CLASSES.empty() && HERO_CLASSES.back().name == "") {
			HERO_CLASSES.pop_back();
		}
	}
	// Make a default hero class if none were found
	if (HERO_CLASSES.empty()) {
		HeroClass c;
		c.name = "Adventurer";
		msg->get("Adventurer"); // this is needed for translation
		HERO_CLASSES.push_back(c);
	}

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

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

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

	// @CLASS Settings: Loot|Description of engine/loot.txt
	if (infile.open("engine/loot.txt")) {
		while (infile.next()) {
			if (infile.key == "currency_name") {
				// @ATTR currency_name|string|Define the name of currency in game
				CURRENCY = msg->get(infile.val);
			}
		}
		infile.close();
	}
}
Ejemplo n.º 15
0
Avatar::Avatar()
	: Entity()
	, lockAttack(false)
	, path()
	, prev_target()
	, target_visible(false)
	, target_anim(NULL)
	, target_animset(NULL)
	, lock_cursor(false)
	, hero_stats(NULL)
	, charmed_stats(NULL)
	, act_target()
	, drag_walking(false)
	, respawn(false)
	, close_menus(false)
	, allow_movement(true)
	, enemy_pos(FPoint(-1,-1)) {

	init();

	// load the hero's animations from hero definition file
	anim->increaseCount("animations/hero.txt");
	animationSet = anim->getAnimationSet("animations/hero.txt");
	activeAnimation = animationSet->getAnimation();

	// set cooldown_hit to duration of hit animation if undefined
	if (stats.cooldown_hit == -1) {
		Animation *hit_anim = animationSet->getAnimation("hit");
		if (hit_anim) {
			stats.cooldown_hit = hit_anim->getDuration();
			delete hit_anim;
		}
		else {
			stats.cooldown_hit = 0;
		}
	}

	loadLayerDefinitions();

	// load target animation
	if (SHOW_TARGET) {
		anim->increaseCount("animations/target.txt");
		target_animset = anim->getAnimationSet("animations/target.txt");
		target_anim = target_animset->getAnimation();
	}

	// load foot-step definitions
	// @CLASS Avatar: Step sounds|Description of items/step_sounds.txt
	FileParser infile;
	if (infile.open("items/step_sounds.txt", true, "")) {
		while (infile.next()) {
			if (infile.key == "id") {
				// @ATTR id|string|An identifier name for a set of step sounds.
				step_def.push_back(Step_sfx());
				step_def.back().id = infile.val;
			}

			if (step_def.empty()) continue;

			if (infile.key == "step") {
				// @ATTR step|filename|Filename of a step sound effect.
				step_def.back().steps.push_back(infile.val);
			}
		}
		infile.close();
	}

	loadStepFX(stats.sfx_step);
}
Ejemplo n.º 16
0
GameStateLoad::GameStateLoad() : GameState()
	, background(NULL)
	, selection(NULL)
	, portrait_border(NULL)
	, portrait(NULL) {
	items = new ItemManager();
	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()) {
			if (infile.key == "action_button") {
				button_action->pos.x = popFirstInt(infile.val);
				button_action->pos.y = popFirstInt(infile.val);
			}
			else if (infile.key == "alternate_button") {
				button_alternate->pos.x = popFirstInt(infile.val);
				button_alternate->pos.y = popFirstInt(infile.val);
			}
			else if (infile.key == "portrait") {
				portrait_dest = toRect(infile.val);
				portrait_dest.x += (VIEW_W - FRAME_W) / 2;
				portrait_dest.y += (VIEW_H - FRAME_H) / 2;
			}
			else if (infile.key == "gameslot") {
				gameslot_pos = toRect(infile.val);
			}
			else if (infile.key == "preview") {
				preview_pos = toRect(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 = toPoint(infile.val);
			}
		}
		infile.close();
	}

	// get displayable types list
	bool found_layer = false;
	if (infile.open("engine/hero_layers.txt")) {
		while(infile.next()) {
			if (infile.key == "layer") {
				unsigned dir = popFirstInt(infile.val);
				if (dir != 6) continue;
				else found_layer = true;

				string layer = popFirstString(infile.val);
				while (layer != "") {
					preview_layer.push_back(layer);
					layer = popFirstString(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");
}
Ejemplo n.º 17
0
MenuNPCActions::MenuNPCActions()
	: Menu()
	, npc(NULL)
	, is_selected(false)
	, is_empty(true)
	, first_dialog_node(-1)
	, current_action(-1)
	, action_menu(NULL)
	, vendor_label(msg->get("Trade"))
	, cancel_label(msg->get("Cancel"))
	, dialog_selected(false)
	, vendor_selected(false)
	, cancel_selected(false)
	, selected_dialog_node(-1)
{
	// Load config settings
	FileParser infile;
	if(infile.open(mods->locate("menus/npc.txt"))) {
		while(infile.next()) {
			infile.val = infile.val + ',';

			if(infile.key == "background_color") {
				background_color.r = eatFirstInt(infile.val,',');
				background_color.g = eatFirstInt(infile.val,',');
				background_color.b = eatFirstInt(infile.val,',');
				background_alpha = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "topic_normal_color") {
				topic_normal_color.r = eatFirstInt(infile.val,',');
				topic_normal_color.g = eatFirstInt(infile.val,',');
				topic_normal_color.b = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "topic_hilight_color") {
				topic_hilight_color.r = eatFirstInt(infile.val,',');
				topic_hilight_color.g = eatFirstInt(infile.val,',');
				topic_hilight_color.b = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "vendor_normal_color") {
				vendor_normal_color.r = eatFirstInt(infile.val,',');
				vendor_normal_color.g = eatFirstInt(infile.val,',');
				vendor_normal_color.b = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "vendor_hilight_color") {
				vendor_hilight_color.r = eatFirstInt(infile.val,',');
				vendor_hilight_color.g = eatFirstInt(infile.val,',');
				vendor_hilight_color.b = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "cancel_normal_color") {
				cancel_normal_color.r = eatFirstInt(infile.val,',');
				cancel_normal_color.g = eatFirstInt(infile.val,',');
				cancel_normal_color.b = eatFirstInt(infile.val,',');
			}
			else if(infile.key == "cancel_hilight_color") {
				cancel_hilight_color.r = eatFirstInt(infile.val,',');
				cancel_hilight_color.g = eatFirstInt(infile.val,',');
				cancel_hilight_color.b = eatFirstInt(infile.val,',');
			}
		}
		infile.close();
	}
}
Ejemplo n.º 18
0
MenuActionBar::MenuActionBar(Avatar *_hero)
	: emptyslot(NULL)
	, disabled(NULL)
	, attention(NULL)
	, hero(_hero)
	, slots_count(0)
	, drag_prev_slot(-1)
	, updated(false)
	, twostep_slot(-1) {

	src.w = ICON_SIZE;
	src.h = ICON_SIZE;

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

	tablist = TabList(HORIZONTAL, ACTIONBAR_BACK, ACTIONBAR_FORWARD, ACTIONBAR);

	for (unsigned int i=0; i<4; i++) {
		menus[i] = new WidgetSlot(-1, ACTIONBAR);
		tablist.add(menus[i]);
	}

	// Read data from config file
	FileParser infile;

	// @CLASS MenuActionBar|Description of menus/actionbar.txt
	if (infile.open("menus/actionbar.txt")) {
		while (infile.next()) {
			if (parseMenuKey(infile.key, infile.val))
				continue;

			// @ATTR slot|index(integer), x (integer), y (integer)|Index (max 10) and position for power slot.
			if (infile.key == "slot") {
				unsigned index = popFirstInt(infile.val, ',');
				if (index == 0 || index > 10) {
					infile.error("MenuActionBar: Slot index must be in range 1-10.");
				}
				else {
					int x = popFirstInt(infile.val, ',');
					int y = popFirstInt(infile.val, ',');
					addSlot(index-1, x, y);
				}
			}
			// @ATTR slot_M1|x (integer), y (integer)|Position for the primary action slot.
			else if (infile.key == "slot_M1") {
				int x = popFirstInt(infile.val, ',');
				int y = popFirstInt(infile.val, ',');
				addSlot(10, x, y);
			}
			// @ATTR slot_M2|x (integer), y (integer)|Position for the secondary action slot.
			else if (infile.key == "slot_M2") {
				int x = popFirstInt(infile.val, ',');
				int y = popFirstInt(infile.val, ',');
				addSlot(11, x, y);
			}

			// @ATTR char_menu|x (integer), y (integer)|Position for the Character menu button.
			else if (infile.key == "char_menu") {
				int x = popFirstInt(infile.val, ',');
				int y = popFirstInt(infile.val, ',');
				menus[MENU_CHARACTER]->setBasePos(x, y);
				menus[MENU_CHARACTER]->pos.w = menus[MENU_CHARACTER]->pos.h = ICON_SIZE;
			}
			// @ATTR inv_menu|x (integer), y (integer)|Position for the Inventory menu button.
			else if (infile.key == "inv_menu") {
				int x = popFirstInt(infile.val, ',');
				int y = popFirstInt(infile.val, ',');
				menus[MENU_INVENTORY]->setBasePos(x, y);
				menus[MENU_INVENTORY]->pos.w = menus[MENU_INVENTORY]->pos.h = ICON_SIZE;
			}
			// @ATTR powers_menu|x (integer), y (integer)|Position for the Powers menu button.
			else if (infile.key == "powers_menu") {
				int x = popFirstInt(infile.val, ',');
				int y = popFirstInt(infile.val, ',');
				menus[MENU_POWERS]->setBasePos(x, y);
				menus[MENU_POWERS]->pos.w = menus[MENU_POWERS]->pos.h = ICON_SIZE;
			}
			// @ATTR log_menu|x (integer), y (integer)|Position for the Log menu button.
			else if (infile.key == "log_menu") {
				int x = popFirstInt(infile.val, ',');
				int y = popFirstInt(infile.val, ',');
				menus[MENU_LOG]->setBasePos(x, y);
				menus[MENU_LOG]->pos.w = menus[MENU_LOG]->pos.h = ICON_SIZE;
			}

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

	slots_count = slots.size();

	hotkeys.resize(slots_count);
	hotkeys_temp.resize(slots_count);
	hotkeys_mod.resize(slots_count);
	locked.resize(slots_count);
	slot_item_count.resize(slots_count);
	slot_enabled.resize(slots_count);
	slot_activated.resize(slots_count);

	clear();

	loadGraphics();

	align();

	menu_act = this;
}
Ejemplo n.º 19
0
SDLFontEngine::SDLFontEngine() : FontEngine(), active_font(NULL) {
	// Initiate SDL_ttf
	if(!TTF_WasInit() && TTF_Init()==-1) {
		logError("SDLFontEngine: TTF_Init: %s", TTF_GetError());
		Exit(2);
	}

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

			if (font_styles.empty()) continue;

			SDLFontStyle *style = &(font_styles.back());

			if (infile.key == "id") {
				// @ATTR font.id|string|An identifier used to reference this font.
				style->name = infile.val;
			}
			else if (infile.key == "style") {
				// @ATTR font.style|repeatable(["default", predefined_string], filename, int, bool) : Language, Font file, Point size, Blending|Filename, point size, and blend mode of the font to use for this language. Language can be "default" or a 2-letter region code.

				std::string lang = popFirstString(infile.val);

				if ((lang == "default" && style->path == "") || lang == LANGUAGE) {
					style->path = popFirstString(infile.val);
					style->ptsize = popFirstInt(infile.val);
					style->blend = toBool(popFirstString(infile.val));

					style->ttfont = TTF_OpenFont(mods->locate("fonts/" + style->path).c_str(), style->ptsize);
					if(style->ttfont == NULL) {
						logError("FontEngine: TTF_OpenFont: %s", TTF_GetError());
					}
					else {
						int lineskip = TTF_FontLineSkip(style->ttfont);
						style->line_height = lineskip;
						style->font_height = lineskip;
					}
				}
			}
		}
		infile.close();
	}

	// set the font colors
	Color color;
	if (infile.open("engine/font_colors.txt")) {
		while (infile.next()) {
			// @ATTR menu_normal|color|Basic menu text color. Recommended: white.
			// @ATTR menu_bonus|color|Positive menu text color. Recommended: green.
			// @ATTR menu_penalty|color|Negative menu text color. Recommended: red.
			// @ATTR widget_normal|color|Basic widget text color. Recommended: white.
			// @ATTR widget_disabled|color|Disabled widget text color. Recommended: grey.
			// @ATTR combat_givedmg|color|Enemy damage text color. Recommended: white.
			// @ATTR combat_takedmg|color|Player damage text color. Recommended: red.
			// @ATTR combat_crit|color|Enemy critical damage text color. Recommended: yellow.
			// @ATTR requirements_no_met|color|Unmet requirements text color. Recommended: red.
			// @ATTR item_bonus|color|Item bonus text color. Recommended: green.
			// @ATTR item_penalty|color|Item penalty text color. Recommended: red.
			// @ATTR item_flavor|color|Item flavor text color. Recommended: grey.
			color_map[infile.key] = toRGB(infile.val);
		}
		infile.close();
	}

	// Attempt to set the default active font
	setFont("font_regular");
	if (!active_font) {
		logError("FontEngine: Unable to determine default font!");
		Exit(1);
	}
}
Ejemplo n.º 20
0
void TileSet::load(const std::string& filename) {
	if (current_map == filename) return;

	reset();

	FileParser infile;

	// @CLASS TileSet|Description of tilesets in tilesets/
	if (infile.open(filename)) {
		while (infile.next()) {
			if (infile.key == "img") {
				// @ATTR img|string|Filename of a tile sheet image.
				loadGraphics(infile.val);
			}
			else if (infile.key == "tile") {
				// @ATTR tile|index (integer), x (integer), y (integer), w (integer), h (integer), x offset (integer), y offset (integer)|A single tile definition.

				// Verify that we have graphics for tiles
				if (!sprites) {
					std::cerr << "No graphics for tileset definition '" << filename << "', aborting." << std::endl;
					exit(0);
				}

				unsigned index = popFirstInt(infile.val);

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

				tiles[index].tile = sprites->getGraphics()->createSprite();

				tiles[index].tile->setClipX(popFirstInt(infile.val));
				tiles[index].tile->setClipY(popFirstInt(infile.val));
				tiles[index].tile->setClipW(popFirstInt(infile.val));
				tiles[index].tile->setClipH(popFirstInt(infile.val));
				tiles[index].offset.x = popFirstInt(infile.val);
				tiles[index].offset.y = popFirstInt(infile.val);
				max_size_x = std::max(max_size_x, (tiles[index].tile->getClip().w / TILE_W) + 1);
				max_size_y = std::max(max_size_y, (tiles[index].tile->getClip().h / TILE_H) + 1);
			}
			else if (infile.key == "transparency") {
				// @ATTR transparency|r (integer), g (integer), b (integer)|An RGB color to key out and treat as transparent.
				alpha_background = false;

				trans_r = (Uint8)popFirstInt(infile.val);
				trans_g = (Uint8)popFirstInt(infile.val);
				trans_b = (Uint8)popFirstInt(infile.val);

			}
			else if (infile.key == "animation") {
				// @ATTR animation|tile index (integer), x (integer), y (integer), duration (duration), ...|An animation for a tile. Durations are in 'ms' or 's'.
				int frame = 0;
				unsigned TILE_ID = toInt(infile.nextValue());

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

				std::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] = parse_duration(infile.nextValue());

					frame++;
					repeat_val = infile.nextValue();
				}
			}
			else {
				infile.error("TileSet: '%s' is not a valid key.", infile.key.c_str());
			}
		}
		infile.close();
	}

	current_map = filename;
}
Ejemplo n.º 21
0
void StatBlock::loadHeroStats() {
	// Redefine numbers from config file if present
	FileParser infile;
	if (!infile.open(mods->locate("engine/stats.txt"))) {
		fprintf(stderr, "Unable to open engine/stats.txt!\n");
		return;
	}

	while (infile.next()) {
		int value = toInt(infile.val);

		if (infile.key == "max_points_per_stat") {
			max_points_per_stat = value;
		} else if (infile.key == "hp_base") {
			hp_base = value;
		} else if (infile.key == "hp_per_level") {
			hp_per_level = value;
		} else if (infile.key == "hp_per_physical") {
			hp_per_physical = value;
		} else if (infile.key == "hp_regen_base") {
			hp_regen_base = value;
		} else if (infile.key == "hp_regen_per_level") {
			hp_regen_per_level = value;
		} else if (infile.key == "hp_regen_per_physical") {
			hp_regen_per_physical = value;
		} else if (infile.key == "mp_base") {
			mp_base = value;
		} else if (infile.key == "mp_per_level") {
			mp_per_level = value;
		} else if (infile.key == "mp_per_mental") {
			mp_per_mental = value;
		} else if (infile.key == "mp_regen_base") {
			mp_regen_base = value;
		} else if (infile.key == "mp_regen_per_level") {
			mp_regen_per_level = value;
		} else if (infile.key == "mp_regen_per_mental") {
			mp_regen_per_mental = value;
		} else if (infile.key == "accuracy_base") {
			accuracy_base = value;
		} else if (infile.key == "accuracy_per_level") {
			accuracy_per_level = value;
		} else if (infile.key == "accuracy_per_offense") {
			accuracy_per_offense = value;
		} else if (infile.key == "avoidance_base") {
			avoidance_base = value;
		} else if (infile.key == "avoidance_per_level") {
			avoidance_per_level = value;
		} else if (infile.key == "avoidance_per_defense") {
			avoidance_per_defense = value;
		} else if (infile.key == "crit_base") {
			crit_base = value;
		} else if (infile.key == "crit_per_level") {
			crit_per_level = value;
		} else if (infile.key == "dmg_melee_min") {
			dmg_melee_min = dmg_melee_min_default = value;
		} else if (infile.key == "dmg_melee_max") {
			dmg_melee_max = dmg_melee_max_default = value;
		} else if (infile.key == "dmg_ranged_min") {
			dmg_ranged_min = dmg_ranged_min_default = value;
		} else if (infile.key == "dmg_ranged_max") {
			dmg_ranged_max = dmg_ranged_max_default = value;
		} else if (infile.key == "dmg_ment_min") {
			dmg_ment_min = dmg_ment_min_default = value;
		} else if (infile.key == "dmg_ment_max") {
			dmg_ment_max = dmg_ment_max_default = value;
		} else if (infile.key == "absorb_min") {
			absorb_min = absorb_min_default = value;
		} else if (infile.key == "absorb_max") {
			absorb_max = absorb_max_default = value;
		} else if (infile.key == "speed") {
			speed = speed_default = value;
		} else if (infile.key == "dspeed") {
			dspeed = dspeed_default = value;
		} else if (infile.key == "bonus_per_physical") {
			bonus_per_physical = value;
		} else if (infile.key == "bonus_per_mental") {
			bonus_per_mental = value;
		} else if (infile.key == "bonus_per_offense") {
			bonus_per_offense = value;
		} else if (infile.key == "bonus_per_defense") {
			bonus_per_defense = value;
		} else if (infile.key == "sfx_step") {
			sfx_step = infile.val;
		} else if (infile.key == "stat_points_per_level") {
			stat_points_per_level = value;
		} else if (infile.key == "power_points_per_level") {
			power_points_per_level = value;
		} else if (infile.key == "cooldown_hit") {
			cooldown_hit = value;
		}
	}
	infile.close();
	if (max_points_per_stat == 0) max_points_per_stat = max_spendable_stat_points / 4 + 1;
	statsLoaded = true;

	// Load the XP table as well
	if (!infile.open(mods->locate("engine/xp_table.txt"))) {
		fprintf(stderr, "Unable to open engine/xp_table.txt!\n");
		return;
	}
	while(infile.next()) {
		xp_table[toInt(infile.key) - 1] = toInt(infile.val);
	}
	max_spendable_stat_points = toInt(infile.key) * stat_points_per_level;
	infile.close();
}
Ejemplo n.º 22
0
/**
 * When loading the game, load from file if possible
 */
void GameStatePlay::loadGame() {

	// 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 << "save" << game_slot << ".txt";

	if (infile.open(ss.str())) {
		while (infile.next()) {
			if (infile.key == "name") pc->stats.name = infile.val;
			else if (infile.key == "permadeath") {
			    pc->stats.permadeath = atoi(infile.val.c_str());
			}
			else if (infile.key == "option") {
				pc->stats.base = infile.nextValue();
				pc->stats.head = infile.nextValue();
				pc->stats.portrait = infile.nextValue();
			}
			else if (infile.key == "xp") pc->stats.xp = atoi(infile.val.c_str());
			else if (infile.key == "build") {
				pc->stats.physical_character = atoi(infile.nextValue().c_str());
				pc->stats.mental_character = atoi(infile.nextValue().c_str());
				pc->stats.offense_character = atoi(infile.nextValue().c_str());
				pc->stats.defense_character = atoi(infile.nextValue().c_str());
			}
			else if (infile.key == "gold") {
				menu->inv->gold = atoi(infile.val.c_str());
			}
			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") {
				map->teleport_mapname = infile.nextValue();
				
				if (fileExists(mods->locate("maps/" + map->teleport_mapname))) {
					map->teleport_destination.x = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
					map->teleport_destination.y = atoi(infile.nextValue().c_str()) * UNITS_PER_TILE + UNITS_PER_TILE/2;
					map->teleportation = true;
				
					// prevent spawn.txt from putting us on the starting map
					map->clearEvents();
				}
				else {
					map->teleport_mapname = "spawn.txt";
					map->teleport_destination.x = 1;
					map->teleport_destination.y = 1;
					map->teleportation = true;
					
				}
			}
			else if (infile.key == "actionbar") {
				for (int i=0; i<12; i++)
					hotkeys[i] = atoi(infile.nextValue().c_str());
				menu->act->set(hotkeys);
			}
			else if (infile.key == "transformed") {
				pc->stats.transform_type = infile.nextValue().c_str();
				if (pc->stats.transform_type != "") pc->stats.transform_duration = -1;
			}
			else if (infile.key == "campaign") camp->setAll(infile.val);
		}
			
		infile.close();
	}

	// initialize vars
	pc->stats.recalc();
	menu->inv->applyEquipment(menu->inv->inventory[EQUIPMENT].storage);
	pc->stats.hp = pc->stats.maxhp;
	pc->stats.mp = pc->stats.maxmp;
	
	// 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.portrait);

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

}
Ejemplo n.º 23
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, FileParser::MOD_FILE, FileParser::ERROR_NORMAL))
		return;

	bool clear_loot = true;
	bool flee_range_defined = false;

	while (infile.next()) {
		if (infile.new_section) {
			// APPENDed file
			clear_loot = true;
		}

		int num = Parse::toInt(infile.val);
		float fnum = Parse::toFloat(infile.val);
		bool valid = loadCoreStat(&infile) || loadSfxStat(&infile);

		// @ATTR name|string|Name
		if (infile.key == "name") name = msg->get(infile.val);
		// @ATTR humanoid|bool|This creature gives human traits when transformed into, such as the ability to talk with NPCs.
		else if (infile.key == "humanoid") humanoid = Parse::toBool(infile.val);
		// @ATTR lifeform|bool|Determines whether or not this entity is referred to as a living thing, such as displaying "Dead" vs "Destroyed" when their HP is 0.
		else if (infile.key == "lifeform") lifeform = Parse::toBool(infile.val);

		// @ATTR level|int|Level
		else if (infile.key == "level") level = num;

		// enemy death rewards and events
		// @ATTR xp|int|XP awarded upon death.
		else if (infile.key == "xp") xp = num;
		else if (infile.key == "loot") {
			// @ATTR loot|repeatable(loot)|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(EventComponent());
			loot->parseLoot(infile.val, &loot_table.back(), &loot_table);
		}
		else if (infile.key == "loot_count") {
			// @ATTR loot_count|int, int : Min, Max|Sets the minimum (and optionally, the maximum) amount of loot this creature can drop. Overrides the global drop_max setting.
			loot_count.x = Parse::popFirstInt(infile.val);
			loot_count.y = Parse::popFirstInt(infile.val);
			if (loot_count.x != 0 || loot_count.y != 0) {
				loot_count.x = std::max(loot_count.x, 1);
				loot_count.y = std::max(loot_count.y, loot_count.x);
			}
		}
		// @ATTR defeat_status|string|Campaign status to set upon death.
		else if (infile.key == "defeat_status") defeat_status = camp->registerStatus(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 = camp->registerStatus(infile.val);
		// @ATTR first_defeat_loot|item_id|Drops this item upon first death.
		else if (infile.key == "first_defeat_loot") first_defeat_loot = num;
		// @ATTR quest_loot|string, string, item_id : Required status, Required not status, Item|Drops this item when campaign status is met.
		else if (infile.key == "quest_loot") {
			quest_loot_requires_status = camp->registerStatus(Parse::popFirstString(infile.val));
			quest_loot_requires_not_status = camp->registerStatus(Parse::popFirstString(infile.val));
			quest_loot_id = Parse::popFirstInt(infile.val);
		}

		// behavior stats
		// @ATTR flying|bool|Creature can move over gaps/water.
		else if (infile.key == "flying") flying = Parse::toBool(infile.val);
		// @ATTR intangible|bool|Creature can move through walls.
		else if (infile.key == "intangible") intangible = Parse::toBool(infile.val);
		// @ATTR facing|bool|Creature can turn to face their target.
		else if (infile.key == "facing") facing = Parse::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::toDuration(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::toDuration(infile.val);
		// @ATTR chance_pursue|int|Percentage change that the creature will chase their target.
		else if (infile.key == "chance_pursue") chance_pursue = num;
		// @ATTR chance_flee|int|Percentage chance that the creature will run away from their target.
		else if (infile.key == "chance_flee") chance_flee = num;

		else if (infile.key == "power") {
			// @ATTR power|["melee", "ranged", "beacon", "on_hit", "on_death", "on_half_dead", "on_join_combat", "on_debuff"], power_id, int : State, Power, Chance|A power that has a chance of being triggered in a certain state.
			AIPower ai_power;

			std::string ai_type = Parse::popFirstString(infile.val);

			ai_power.id = powers->verifyID(Parse::popFirstInt(infile.val), &infile, !PowerManager::ALLOW_ZERO_ID);
			if (ai_power.id == 0)
				continue; // verifyID() will print our error message

			ai_power.chance = Parse::popFirstInt(infile.val);

			if (ai_type == "melee") ai_power.type = AI_POWER_MELEE;
			else if (ai_type == "ranged") ai_power.type = AI_POWER_RANGED;
			else if (ai_type == "beacon") ai_power.type = AI_POWER_BEACON;
			else if (ai_type == "on_hit") ai_power.type = AI_POWER_HIT;
			else if (ai_type == "on_death") ai_power.type = AI_POWER_DEATH;
			else if (ai_type == "on_half_dead") ai_power.type = AI_POWER_HALF_DEAD;
			else if (ai_type == "on_join_combat") ai_power.type = AI_POWER_JOIN_COMBAT;
			else if (ai_type == "on_debuff") ai_power.type = AI_POWER_DEBUFF;
			else {
				infile.error("StatBlock: '%s' is not a valid enemy power type.", ai_type.c_str());
				continue;
			}

			if (ai_power.type == AI_POWER_HALF_DEAD)
				half_dead_power = true;

			powers_ai.push_back(ai_power);
		}

		else if (infile.key == "passive_powers") {
			// @ATTR passive_powers|list(power_id)|A list of passive powers this creature has.
			powers_passive.clear();
			std::string p = Parse::popFirstString(infile.val);
			while (p != "") {
				powers_passive.push_back(Parse::toInt(p));
				p = Parse::popFirstString(infile.val);

				// if a passive power has a post power, add it to the AI power list so we can track its cooldown
				int post_power = powers->powers[powers_passive.back()].post_power;
				if (post_power > 0) {
					AIPower passive_post_power;
					passive_post_power.type = AI_POWER_PASSIVE_POST;
					passive_post_power.id = post_power;
					passive_post_power.chance = 0; // post_power chance is used instead
					powers_ai.push_back(passive_post_power);
				}
			}
		}

		// @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, float: Engage distance, Stop distance|The first value is the radius of the area this creature will be able to start chasing the hero. The second, optional, value is the radius at which this creature will stop pursuing their target and defaults to double the first value.
		else if (infile.key == "threat_range") {
			threat_range = Parse::toFloat(Parse::popFirstString(infile.val));

			std::string tr_far = Parse::popFirstString(infile.val);
			if (!tr_far.empty())
				threat_range_far = Parse::toFloat(tr_far);
			else
				threat_range_far = threat_range * 2;
		}
		// @ATTR flee_range|float|The radius at which this creature will start moving to a safe distance. Defaults to half of the threat_range.
		else if (infile.key == "flee_range") {
			flee_range = fnum;
			flee_range_defined = true;
		}
		// @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|filename|Filename of an animation definition.
		else if (infile.key == "animations") animations = infile.val;

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

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

		// @ATTR flee_duration|duration|The minimum amount of time that this creature will flee. They may flee longer than the specified time.
		else if (infile.key == "flee_duration") flee_duration = Parse::toDuration(infile.val);
		// @ATTR flee_cooldown|duration|The amount of time this creature must wait before they can start fleeing again.
		else if (infile.key == "flee_cooldown") flee_cooldown = Parse::toDuration(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) {
			infile.error("StatBlock: '%s' is not a valid key.", infile.key.c_str());
		}
	}
	infile.close();

	hp = starting[Stats::HP_MAX];
	mp = starting[Stats::MP_MAX];

	if (!flee_range_defined)
		flee_range = threat_range / 2;

	applyEffects();
}
Ejemplo n.º 24
0
/**
 * load a statblock, typically for an enemy definition
 */
void StatBlock::load(const string& filename) {
	FileParser infile;
	int num = 0;
	
	if (infile.open(mods->locate(filename))) {
		while (infile.next()) {
			if (isInt(infile.val)) num = atoi(infile.val.c_str());
			
			if (infile.key == "name") name = msg->get(infile.val);
			else if (infile.key == "sfx_prefix") sfx_prefix = infile.val;
			else if (infile.key == "gfx_prefix") gfx_prefix = infile.val;
			
			else if (infile.key == "level") level = num;
			
			// enemy death rewards and events
			else if (infile.key == "xp") xp = num;
			else if (infile.key == "loot_chance") loot_chance = num;
			else if (infile.key == "defeat_status") defeat_status = infile.val;
			else if (infile.key == "first_defeat_loot") first_defeat_loot = num;
			else if (infile.key == "quest_loot") {
				quest_loot_requires = infile.nextValue();
				quest_loot_not = infile.nextValue();
				quest_loot_id = atoi(infile.nextValue().c_str());
			}
			
			// combat stats
			else if (infile.key == "hp") {
				hp = num;
				maxhp = num;
			}
			else if (infile.key == "mp") {
				mp = num;
				maxmp = num;
			}
			else if (infile.key == "cooldown") cooldown = num;
			else if (infile.key == "accuracy") accuracy = num;
			else if (infile.key == "avoidance") avoidance = num;
			else if (infile.key == "dmg_melee_min") dmg_melee_min = num;
			else if (infile.key == "dmg_melee_max") dmg_melee_max = num;
			else if (infile.key == "dmg_ment_min") dmg_ment_min = num;
			else if (infile.key == "dmg_ment_max") dmg_ment_max = num;
			else if (infile.key == "dmg_ranged_min") dmg_ranged_min = num;
			else if (infile.key == "dmg_ranged_max") dmg_ranged_max = num;
			else if (infile.key == "absorb_min") absorb_min = num;
			else if (infile.key == "absorb_max") absorb_max = num;
			
			// behavior stats
			else if (infile.key == "speed") speed = num;
			else if (infile.key == "dspeed") dspeed = num;
			else if (infile.key == "dir_favor") dir_favor = num;
			else if (infile.key == "chance_pursue") chance_pursue = num;
			else if (infile.key == "chance_flee") chance_flee = num;

			else if (infile.key == "chance_melee_phys") power_chance[MELEE_PHYS] = num;
			else if (infile.key == "chance_melee_ment") power_chance[MELEE_MENT] = num;
			else if (infile.key == "chance_ranged_phys") power_chance[RANGED_PHYS] = num;
			else if (infile.key == "chance_ranged_ment") power_chance[RANGED_MENT] = num;
			else if (infile.key == "power_melee_phys") power_index[MELEE_PHYS] = num;
			else if (infile.key == "power_melee_ment") power_index[MELEE_MENT] = num;
			else if (infile.key == "power_ranged_phys") power_index[RANGED_PHYS] = num;
			else if (infile.key == "power_ranged_ment") power_index[RANGED_MENT] = num;
			else if (infile.key == "power_beacon") power_index[BEACON] = num;
			else if (infile.key == "cooldown_melee_phys") power_cooldown[MELEE_PHYS] = num;
			else if (infile.key == "cooldown_melee_ment") power_cooldown[MELEE_MENT] = num;
			else if (infile.key == "cooldown_ranged_phys") power_cooldown[RANGED_PHYS] = num;
			else if (infile.key == "cooldown_ranged_ment") power_cooldown[RANGED_MENT] = num;
            else if (infile.key == "power_on_hit") power_index[ON_HIT] = num;
			else if (infile.key == "power_on_death") power_index[ON_DEATH] = num;
			else if (infile.key == "power_on_half_dead") power_index[ON_HALF_DEAD] = num;
			else if (infile.key == "power_on_debuff") power_index[ON_DEBUFF] = num;
			else if (infile.key == "power_on_join_combat") power_index[ON_JOIN_COMBAT] = num;
            else if (infile.key == "chance_on_hit") power_chance[ON_HIT] = num;
			else if (infile.key == "chance_on_death") power_chance[ON_DEATH] = num;
			else if (infile.key == "chance_on_half_dead") power_chance[ON_HALF_DEAD] = num;
			else if (infile.key == "chance_on_debuff") power_chance[ON_DEBUFF] = num;
			else if (infile.key == "chance_on_join_combat") power_chance[ON_JOIN_COMBAT] = num;

			
			else if (infile.key == "melee_range") melee_range = num;
			else if (infile.key == "threat_range") threat_range = num;
			
			else if (infile.key == "attunement_fire") attunement_fire=num;
			else if (infile.key == "attunement_ice") attunement_ice=num;

			// animation stats
			else if (infile.key == "melee_weapon_power") melee_weapon_power = num;
			else if (infile.key == "mental_weapon_power") mental_weapon_power = num;
			else if (infile.key == "ranged_weapon_power") ranged_weapon_power = num;

			else if (infile.key == "animations") animations = infile.val;
			else if (infile.key == "animation_speed") animationSpeed = num;
		}
		infile.close();
	}
}
Ejemplo n.º 25
0
void PowerManager::loadPowers() {
	FileParser infile;

	// @CLASS Power|Description about powers...
	if (!infile.open("powers/powers.txt", true, false))
		return;

	int input_id = 0;
	bool skippingEntry = false;

	while (infile.next()) {
		// id needs to be the first component of each power.  That is how we write
		// data to the correct power.
		if (infile.key == "id") {
			// @ATTR id|integer|Uniq identifier for the power definition.
			input_id = toInt(infile.val);
			skippingEntry = input_id < 1;
			if (skippingEntry)
				fprintf(stderr, "Power index out of bounds 1-%d, skipping\n", INT_MAX);
			if (static_cast<int>(powers.size()) < input_id + 1)
				powers.resize(input_id + 1);
			continue;
		}
		if (skippingEntry)
			continue;

		if (infile.key == "type") {
			// @ATTR type|[fixed:missile:repeater:spawn:transform]|Defines the type of power definiton
			if (infile.val == "fixed") powers[input_id].type = POWTYPE_FIXED;
			else if (infile.val == "missile") powers[input_id].type = POWTYPE_MISSILE;
			else if (infile.val == "repeater") powers[input_id].type = POWTYPE_REPEATER;
			else if (infile.val == "spawn") powers[input_id].type = POWTYPE_SPAWN;
			else if (infile.val == "transform") powers[input_id].type = POWTYPE_TRANSFORM;
			else fprintf(stderr, "unknown type %s\n", infile.val.c_str());
		}
		else if (infile.key == "name")
			// @ATTR name|string|The name of the power
			powers[input_id].name = msg->get(infile.val);
		else if (infile.key == "description")
			// @ATTR description|string|Description of the power
			powers[input_id].description = msg->get(infile.val);
		else if (infile.key == "icon")
			// @ATTR icon|string|The icon to visually represent the power eg. in skill tree or action bar.
			powers[input_id].icon = toInt(infile.val);
		else if (infile.key == "new_state") {
			// @ATTR new_state|string|When power is used, hero or enemy will change to this state. Must be one of the states [block, instant, user defined]
			if (infile.val == "block") powers[input_id].new_state = POWSTATE_BLOCK;
			else if (infile.val == "instant") powers[input_id].new_state = POWSTATE_INSTANT;
			else {
				powers[input_id].new_state = POWSTATE_ATTACK;
				powers[input_id].attack_anim = infile.val;
			}
		}
		else if (infile.key == "face")
			// @ATTR face|bool|Power will make hero or enemy to face the target location.
			powers[input_id].face = toBool(infile.val);
		else if (infile.key == "source_type") {
			// @ATTR source_type|[hero:neutral:enemy]|
			if (infile.val == "hero") powers[input_id].source_type = SOURCE_TYPE_HERO;
			else if (infile.val == "neutral") powers[input_id].source_type = SOURCE_TYPE_NEUTRAL;
			else if (infile.val == "enemy") powers[input_id].source_type = SOURCE_TYPE_ENEMY;
			else fprintf(stderr, "unknown source_type %s\n", infile.val.c_str());
		}
		else if (infile.key == "beacon")
			// @ATTR beacon|bool|True if enemy is calling its allies.
			powers[input_id].beacon = toBool(infile.val);
		else if (infile.key == "count")
			// @ATTR count|integer|The count of hazards/effect or spawns to be created by this power.
			powers[input_id].count = toInt(infile.val);
		else if (infile.key == "passive")
			// @ATTR passive|bool|If power is unlocked when the hero or enemy spawns it will be automatically activated.
			powers[input_id].passive = toBool(infile.val);
		else if (infile.key == "passive_trigger") {
			// @ATTR passive_trigger|[on_block:on_hit:on_halfdeath:on_joincombat:on_death]|This will only activate a passive power under a certain condition.
			if (infile.val == "on_block") powers[input_id].passive_trigger = TRIGGER_BLOCK;
			else if (infile.val == "on_hit") powers[input_id].passive_trigger = TRIGGER_HIT;
			else if (infile.val == "on_halfdeath") powers[input_id].passive_trigger = TRIGGER_HALFDEATH;
			else if (infile.val == "on_joincombat") powers[input_id].passive_trigger = TRIGGER_JOINCOMBAT;
			else if (infile.val == "on_death") powers[input_id].passive_trigger = TRIGGER_DEATH;
			else fprintf(stderr, "unknown passive trigger %s\n", infile.val.c_str());
		}
		// power requirements
		else if (infile.key == "requires_flags") {
			std::string flag = popFirstString(infile.val);

			while (flag != "") {
				powers[input_id].requires_flags.insert(flag);
				flag = popFirstString(infile.val);
			}
		}
		else if (infile.key == "requires_mp")
			// @ATTR requires_mp|integer|Restrict power usage to a specified MP level.
			powers[input_id].requires_mp = toInt(infile.val);
		else if (infile.key == "requires_hp")
			// @ATTR requires_hp|integer|Restrict power usage to a specified HP level.
			powers[input_id].requires_hp = toInt(infile.val);
		else if (infile.key == "sacrifice")
			// @ATTR sacrifice|bool|
			powers[input_id].sacrifice = toBool(infile.val);
		else if (infile.key == "requires_los")
			// @ATTR requires_los|bool|Requires a line-of-sight to target.
			powers[input_id].requires_los = toBool(infile.val);
		else if (infile.key == "requires_empty_target")
			// @ATTR requires_empty_target|bool|The power can only be cast when target tile is empty.
			powers[input_id].requires_empty_target = toBool(infile.val);
		else if (infile.key == "requires_item")
			// @ATTR requires_item|item_id|Requires a specific item in inventory.
			powers[input_id].requires_item = toInt(infile.val);
		else if (infile.key == "requires_equipped_item")
			// @ATTR requires_equipped_item|item_id|Requires a specific item to be equipped on hero.
			powers[input_id].requires_equipped_item = toInt(infile.val);
		else if (infile.key == "requires_targeting")
			// @ATTR requires_targeting|bool|Power is only used when targeting using click-to-target.
			powers[input_id].requires_targeting = toBool(infile.val);
		else if (infile.key == "cooldown")
			// @ATTR cooldown|duration|Specify the duration for cooldown of the power.
			powers[input_id].cooldown = parse_duration(infile.val);
		// animation info
		else if (infile.key == "animation")
			// @ATTR animation|string|The name of power animation.
			powers[input_id].animation_name = infile.val;
		else if (infile.key == "soundfx")
			// @ATTR soundfx|string|Sound effect to play when use of power.
			powers[input_id].sfx_index = loadSFX(infile.val);
		else if (infile.key == "directional")
			// @ATTR directional|bool|The animation sprite sheet contains 8 directions, one per row.
			powers[input_id].directional = toBool(infile.val);
		else if (infile.key == "visual_random")
			// @ATTR visual_random|integer|The animation sprite sheet contains rows of random options
			powers[input_id].visual_random = toInt(infile.val);
		else if (infile.key == "visual_option")
			// @ATTR visual_option|integer|The animation sprite sheet containers rows of similar effects, use a specific option.
			powers[input_id].visual_option = toInt(infile.val);
		else if (infile.key == "aim_assist")
			// @ATTR aim_assist|bool|Power is aim assisted.
			powers[input_id].aim_assist = toBool(infile.val);
		else if (infile.key == "speed")
			// @ATTR speed|integer|The speed of missile hazard, the unit is defined as map units per frame.
			powers[input_id].speed = toFloat(infile.val) / MAX_FRAMES_PER_SEC;
		else if (infile.key == "lifespan")
			// @ATTR lifespan|duration|How long the hazard/animation lasts.
			powers[input_id].lifespan = parse_duration(infile.val);
		else if (infile.key == "floor")
			// @ATTR floor|bool|The hazard is drawn between the background and the object layer.
			powers[input_id].floor = toBool(infile.val);
		else if (infile.key == "complete_animation")
			// @ATTR complete_animation|bool|
			powers[input_id].complete_animation = toBool(infile.val);
		// hazard traits
		else if (infile.key == "use_hazard")
			// @ATTR use_hazard|bool|Power uses hazard.
			powers[input_id].use_hazard = toBool(infile.val);
		else if (infile.key == "no_attack")
			// @ATTR no_attack|bool|
			powers[input_id].no_attack = toBool(infile.val);
		else if (infile.key == "radius")
			// @ATTR radius|integer|Radius in pixels
			powers[input_id].radius = toFloat(infile.val);
		else if (infile.key == "base_damage") {
			// @ATTR base_damage|[melee:ranged:ment]|
			if (infile.val == "none")        powers[input_id].base_damage = BASE_DAMAGE_NONE;
			else if (infile.val == "melee")  powers[input_id].base_damage = BASE_DAMAGE_MELEE;
			else if (infile.val == "ranged") powers[input_id].base_damage = BASE_DAMAGE_RANGED;
			else if (infile.val == "ment")   powers[input_id].base_damage = BASE_DAMAGE_MENT;
			else fprintf(stderr, "unknown base_damage %s\n", infile.val.c_str());
		}
		else if (infile.key == "starting_pos") {
			// @ATTR starting_pos|[source, target, melee]|Start position for hazard
			if (infile.val == "source")      powers[input_id].starting_pos = STARTING_POS_SOURCE;
			else if (infile.val == "target") powers[input_id].starting_pos = STARTING_POS_TARGET;
			else if (infile.val == "melee")  powers[input_id].starting_pos = STARTING_POS_MELEE;
			else fprintf(stderr, "unknown starting_pos %s\n", infile.val.c_str());
		}
		else if (infile.key == "multitarget")
			// @ATTR multitarget|bool|
			powers[input_id].multitarget = toBool(infile.val);
		else if (infile.key == "trait_armor_penetration")
			// @ATTR trait_armor_penetration|bool|
			powers[input_id].trait_armor_penetration = toBool(infile.val);
		else if (infile.key == "trait_avoidance_ignore")
			// @ATTR trait_avoidance_ignore|bool|
			powers[input_id].trait_avoidance_ignore = toBool(infile.val);
		else if (infile.key == "trait_crits_impaired")
			// @ATTR trait_crits_impaired|bool|
			powers[input_id].trait_crits_impaired = toInt(infile.val);
		else if (infile.key == "trait_elemental") {
			// @ATTR, trait_elemental|string|
			for (unsigned int i=0; i<ELEMENTS.size(); i++) {
				if (infile.val == ELEMENTS[i].name) powers[input_id].trait_elemental = i;
			}
		}
		else if (infile.key == "target_range")
			// @ATTR, target_range|float||The distance from the caster that the power can be activated
			powers[input_id].target_range = toFloat(infile.nextValue());
		//steal effects
		else if (infile.key == "hp_steal")
			// @ATTR, hp_steal|integer|Percentage of damage to steal into HP
			powers[input_id].hp_steal = toInt(infile.val);
		else if (infile.key == "mp_steal")
			// @ATTR, mp_steal|integer|Percentage of damage to steal into MP
			powers[input_id].mp_steal = toInt(infile.val);
		//missile modifiers
		else if (infile.key == "missile_angle")
			// @ATTR missile_angle|integer|Angle of missile
			powers[input_id].missile_angle = toInt(infile.val);
		else if (infile.key == "angle_variance")
			// @ATTR angle_variance|integer|Percentage of variance added to missile angle
			powers[input_id].angle_variance = toInt(infile.val);
		else if (infile.key == "speed_variance")
			// @ATTR speed_variance|integer|Percentage of variance added to missile speed
			powers[input_id].speed_variance = toFloat(infile.val);
		//repeater modifiers
		else if (infile.key == "delay")
			// @ATTR delay|duration|Delay between repeats
			powers[input_id].delay = parse_duration(infile.val);
		// buff/debuff durations
		else if (infile.key == "transform_duration")
			// @ATTR transform_duration|duration|Duration for transform
			powers[input_id].transform_duration = toInt(infile.val);
		else if (infile.key == "manual_untransform")
			// @ATTR transform_duration|bool|Force manual untranform
			powers[input_id].manual_untransform = toBool(infile.val);
		else if (infile.key == "keep_equipment")
			// @ATTR keep_equipment|bool|Keep  equipment while transformed
			powers[input_id].keep_equipment = toBool(infile.val);
		// buffs
		else if (infile.key == "buff")
			// @ATTR buff|bool|
			powers[input_id].buff= toBool(infile.val);
		else if (infile.key == "buff_teleport")
			// @ATTR buff_teleport|bool|
			powers[input_id].buff_teleport = toBool(infile.val);
		else if (infile.key == "buff_party")
			// @ATTR buff_part|bool|
			powers[input_id].buff_party = toBool(infile.val);
		else if (infile.key == "buff_party_power_id")
			// @ATTR buff_part_power_id|bool|
			powers[input_id].buff_party_power_id = toInt(infile.val);
		else if (infile.key == "post_effect") {
			// @ATTR post_effect|[effect_id, magnitude (integer), duration (integer)]|Post effect.
			PostEffect pe;
			pe.id = popFirstString(infile.val);
			pe.magnitude = popFirstInt(infile.val);
			pe.duration = popFirstInt(infile.val);
			powers[input_id].post_effects.push_back(pe);
		}
		// pre and post power effects
		else if (infile.key == "post_power")
			// @ATTR post_power|power_id|Post power
			powers[input_id].post_power = toInt(infile.val);
		else if (infile.key == "wall_power")
			// @ATTR wall_power|power_id|Wall power
			powers[input_id].wall_power = toInt(infile.val);
		else if (infile.key == "allow_power_mod")
			// @ATTR allow_power_mod|bool|Allow power modifiers
			powers[input_id].allow_power_mod = toBool(infile.val);
		// spawn info
		else if (infile.key == "spawn_type")
			// @ATTR spawn_type|string|Type of spawn.
			powers[input_id].spawn_type = infile.val;
		else if (infile.key == "target_neighbor")
			// @ATTR target_neighbor|int|Neigbor target.
			powers[input_id].target_neighbor = toInt(infile.val);
		else if (infile.key == "spawn_limit") {
			// @ATTR spawn_limit|[fixed:stat:unlimited],stat[physical:mental:offense:defens]|
			std::string mode = popFirstString(infile.val);
			if (mode == "fixed") powers[input_id].spawn_limit_mode = SPAWN_LIMIT_MODE_FIXED;
			else if (mode == "stat") powers[input_id].spawn_limit_mode = SPAWN_LIMIT_MODE_STAT;
			else if (mode == "unlimited") powers[input_id].spawn_limit_mode = SPAWN_LIMIT_MODE_UNLIMITED;
			else fprintf(stderr, "unknown spawn_limit_mode %s\n", mode.c_str());

			if(powers[input_id].spawn_limit_mode != SPAWN_LIMIT_MODE_UNLIMITED) {
				powers[input_id].spawn_limit_qty = popFirstInt(infile.val);

				if(powers[input_id].spawn_limit_mode == SPAWN_LIMIT_MODE_STAT) {
					powers[input_id].spawn_limit_every = popFirstInt(infile.val);

					std::string stat = popFirstString(infile.val);
					if (stat == "physical") powers[input_id].spawn_limit_stat = SPAWN_LIMIT_STAT_PHYSICAL;
					else if (stat == "mental") powers[input_id].spawn_limit_stat = SPAWN_LIMIT_STAT_MENTAL;
					else if (stat == "offense") powers[input_id].spawn_limit_stat = SPAWN_LIMIT_STAT_OFFENSE;
					else if (stat == "defense") powers[input_id].spawn_limit_stat = SPAWN_LIMIT_STAT_DEFENSE;
					else fprintf(stderr, "unknown spawn_limit_stat %s\n", stat.c_str());
				}
			}
		}
		else if (infile.key == "spawn_level") {
			std::string mode = popFirstString(infile.val);
			if (mode == "default") powers[input_id].spawn_level_mode = SPAWN_LEVEL_MODE_DEFAULT;
			else if (mode == "fixed") powers[input_id].spawn_level_mode = SPAWN_LEVEL_MODE_FIXED;
			else if (mode == "stat") powers[input_id].spawn_level_mode = SPAWN_LEVEL_MODE_STAT;
			else if (mode == "level") powers[input_id].spawn_level_mode = SPAWN_LEVEL_MODE_LEVEL;
			else fprintf(stderr, "unknown spawn_level_mode %s\n", mode.c_str());

			if(powers[input_id].spawn_level_mode != SPAWN_LEVEL_MODE_DEFAULT) {
				powers[input_id].spawn_level_qty = popFirstInt(infile.val);

				if(powers[input_id].spawn_level_mode != SPAWN_LEVEL_MODE_FIXED) {
					powers[input_id].spawn_level_every = popFirstInt(infile.val);

					if(powers[input_id].spawn_level_mode == SPAWN_LEVEL_MODE_STAT) {
						std::string stat = popFirstString(infile.val);
						if (stat == "physical") powers[input_id].spawn_level_stat = SPAWN_LEVEL_STAT_PHYSICAL;
						else if (stat == "mental") powers[input_id].spawn_level_stat = SPAWN_LEVEL_STAT_MENTAL;
						else if (stat == "offense") powers[input_id].spawn_level_stat = SPAWN_LEVEL_STAT_OFFENSE;
						else if (stat == "defense") powers[input_id].spawn_level_stat = SPAWN_LEVEL_STAT_DEFENSE;
						else fprintf(stderr, "unknown spawn_level_stat %s\n", stat.c_str());
					}
				}
			}
		}
		else if (infile.key == "target_party")
			// @ATTR target_party|bool|
			powers[input_id].target_party = toBool(infile.val);
		else if (infile.key == "target_categories") {
			// @ATTR target_categories|string,...|
			string cat;
			while ((cat = infile.nextValue()) != "") {
				powers[input_id].target_categories.push_back(cat);
			}
		}
		else if (infile.key == "modifier_accuracy") {
			// @ATTR modifier_accuracy|[multiply:add:absolute], integer|
			std::string mode = popFirstString(infile.val);
			if(mode == "multiply") powers[input_id].mod_accuracy_mode = STAT_MODIFIER_MODE_MULTIPLY;
			else if(mode == "add") powers[input_id].mod_accuracy_mode = STAT_MODIFIER_MODE_ADD;
			else if(mode == "absolute") powers[input_id].mod_accuracy_mode = STAT_MODIFIER_MODE_ABSOLUTE;
			else fprintf(stderr, "unknown stat_modifier_mode %s\n", mode.c_str());

			powers[input_id].mod_accuracy_value = popFirstInt(infile.val);
		}
		else if (infile.key == "modifier_damage") {
			// @ATTR modifier_damage|[multiply:add:absolute], integer|
			std::string mode = popFirstString(infile.val);
			if(mode == "multiply") powers[input_id].mod_damage_mode = STAT_MODIFIER_MODE_MULTIPLY;
			else if(mode == "add") powers[input_id].mod_damage_mode = STAT_MODIFIER_MODE_ADD;
			else if(mode == "absolute") powers[input_id].mod_damage_mode = STAT_MODIFIER_MODE_ABSOLUTE;
			else fprintf(stderr, "unknown stat_modifier_mode %s\n", mode.c_str());

			powers[input_id].mod_damage_value_min = popFirstInt(infile.val);
			powers[input_id].mod_damage_value_max = popFirstInt(infile.val);
		}
		else if (infile.key == "modifier_critical") {
			// @ATTR modifier_critical|[multiply:add:absolute], integer|
			std::string mode = popFirstString(infile.val);
			if(mode == "multiply") powers[input_id].mod_crit_mode = STAT_MODIFIER_MODE_MULTIPLY;
			else if(mode == "add") powers[input_id].mod_crit_mode = STAT_MODIFIER_MODE_ADD;
			else if(mode == "absolute") powers[input_id].mod_crit_mode = STAT_MODIFIER_MODE_ABSOLUTE;
			else fprintf(stderr, "unknown stat_modifier_mode %s\n", mode.c_str());

			powers[input_id].mod_crit_value = popFirstInt(infile.val);
		}
		else
			fprintf(stderr, "ignoring unknown key %s set to %s in file %s\n",
					infile.key.c_str(), infile.val.c_str(), infile.getFileName().c_str());
	}
	infile.close();
}
Ejemplo n.º 26
0
void StatBlock::loadHeroStats() {
	// set the default global cooldown
	cooldown = parse_duration("66ms");

	// Redefine numbers from config file if present
	FileParser infile;
	// @CLASS StatBlock: Hero stats|Description of engine/stats.txt
	if (infile.open("engine/stats.txt")) {
		while (infile.next()) {
			int value = toInt(infile.val);

			bool valid = loadCoreStat(&infile);

			if (infile.key == "max_points_per_stat") {
				// @ATTR max_points_per_stat|int|Maximum points for each primary stat.
				max_points_per_stat = value;
			}
			else if (infile.key == "sfx_step") {
				// @ATTR sfx_step|string|An id for a set of step sound effects. See items/step_sounds.txt.
				sfx_step = infile.val;
			}
			else if (infile.key == "stat_points_per_level") {
				// @ATTR stat_points_per_level|int|The amount of stat points awarded each level.
				stat_points_per_level = value;
			}
			else if (infile.key == "power_points_per_level") {
				// @ATTR power_points_per_level|int|The amount of power points awarded each level.
				power_points_per_level = value;
			}
			else if (!valid) {
				infile.error("StatBlock: '%s' is not a valid key.", infile.key.c_str());
			}
		}
		infile.close();
	}

	if (max_points_per_stat == 0) max_points_per_stat = max_spendable_stat_points / 4 + 1;
	statsLoaded = true;

	// load the XP table
	// @CLASS StatBlock: XP table|Description of engine/xp_table.txt
	if (infile.open("engine/xp_table.txt")) {
		while(infile.next()) {
			if (infile.key == "level") {
				// @ATTR level|int, int : Level, XP|The amount of XP required for this level.
				unsigned lvl_id = popFirstInt(infile.val);
				unsigned long lvl_xp = toUnsignedLong(popFirstString(infile.val));

				if (lvl_id > xp_table.size())
					xp_table.resize(lvl_id);

				xp_table[lvl_id - 1] = lvl_xp;
			}
		}
		infile.close();
	}

	if (xp_table.empty()) {
		logError("StatBlock: No XP table defined.");
		xp_table.push_back(0);
	}

	max_spendable_stat_points = static_cast<int>(xp_table.size()) * stat_points_per_level;
}
Ejemplo n.º 27
0
void MenuActionBar::update() {

	// Read data from config file
	FileParser infile;

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

			if (infile.key == "slot1") {
				slots[0]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[0]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[0]->pos.w = eatFirstInt(infile.val, ',');
				slots[0]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "slot2") {
				slots[1]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[1]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[1]->pos.w = eatFirstInt(infile.val, ',');
				slots[1]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "slot3") {
				slots[2]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[2]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[2]->pos.w = eatFirstInt(infile.val, ',');
				slots[2]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "slot4") {
				slots[3]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[3]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[3]->pos.w = eatFirstInt(infile.val, ',');
				slots[3]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "slot5") {
				slots[4]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[4]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[4]->pos.w = eatFirstInt(infile.val, ',');
				slots[4]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "slot6") {
				slots[5]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[5]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[5]->pos.w = eatFirstInt(infile.val, ',');
				slots[5]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "slot7") {
				slots[6]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[6]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[6]->pos.w = eatFirstInt(infile.val, ',');
				slots[6]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "slot8") {
				slots[7]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[7]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[7]->pos.w = eatFirstInt(infile.val, ',');
				slots[7]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "slot9") {
				slots[8]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[8]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[8]->pos.w = eatFirstInt(infile.val, ',');
				slots[8]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "slot10") {
				slots[9]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[9]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[9]->pos.w = eatFirstInt(infile.val, ',');
				slots[9]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "slot_M1") {
				slots[10]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[10]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[10]->pos.w = eatFirstInt(infile.val, ',');
				slots[10]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "slot_M2") {
				slots[11]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				slots[11]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				slots[11]->pos.w = eatFirstInt(infile.val, ',');
				slots[11]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "char_menu") {
				menus[MENU_CHARACTER]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				menus[MENU_CHARACTER]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				menus[MENU_CHARACTER]->pos.w = eatFirstInt(infile.val, ',');
				menus[MENU_CHARACTER]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "inv_menu") {
				menus[MENU_INVENTORY]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				menus[MENU_INVENTORY]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				menus[MENU_INVENTORY]->pos.w = eatFirstInt(infile.val, ',');
				menus[MENU_INVENTORY]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "powers_menu") {
				menus[MENU_POWERS]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				menus[MENU_POWERS]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				menus[MENU_POWERS]->pos.w = eatFirstInt(infile.val, ',');
				menus[MENU_POWERS]->pos.h = eatFirstInt(infile.val, ',');
			}
			else if (infile.key == "log_menu") {
				menus[MENU_LOG]->pos.x = window_area.x+eatFirstInt(infile.val, ',');
				menus[MENU_LOG]->pos.y = window_area.y+eatFirstInt(infile.val, ',');
				menus[MENU_LOG]->pos.w = eatFirstInt(infile.val, ',');
				menus[MENU_LOG]->pos.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();
	}

	// 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]->pos.x+slots[i]->pos.w, slots[i]->pos.y+slots[i]->pos.h-font->getFontHeight(), JUSTIFY_RIGHT, VALIGN_TOP, inpt->mouse_button[inpt->binding[i+6]-1], font->getColor("menu_normal"));
		else
			labels[i]->set(slots[i]->pos.x+slots[i]->pos.w, slots[i]->pos.y+slots[i]->pos.h-font->getFontHeight(), 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]->pos.x+slots[i+10]->pos.w, slots[i+10]->pos.y+slots[i+10]->pos.h-font->getFontHeight(), JUSTIFY_RIGHT, VALIGN_TOP, inpt->mouse_button[inpt->binding[i+20]-1], font->getColor("menu_normal"));
		else
			labels[i+10]->set(slots[i+10]->pos.x+slots[i+10]->pos.w, slots[i+10]->pos.y+slots[i+10]->pos.h-font->getFontHeight(), 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]->pos.x+menus[i]->pos.w, menus[i]->pos.y+menus[i]->pos.h-font->getFontHeight(), JUSTIFY_RIGHT, VALIGN_TOP, inpt->mouse_button[inpt->binding[i+16]-1], font->getColor("menu_normal"));
		else
			labels[i+12]->set(menus[i]->pos.x+menus[i]->pos.w, menus[i]->pos.y+menus[i]->pos.h-font->getFontHeight(), JUSTIFY_RIGHT, VALIGN_TOP, SDL_GetKeyName((SDLKey)inpt->binding[i+16]), font->getColor("menu_normal"));
	}
}
Ejemplo n.º 28
0
MenuCharacter::MenuCharacter(StatBlock *_stats) {
	stats = _stats;

	skill_points = 0;

	visible = false;
	newPowerNotification = false;

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

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

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

	// menu title
	labelCharacter = new WidgetLabel();

	// unspent points
	labelUnspent = new WidgetLabel();

	// Load config settings
	FileParser infile;
	if(infile.open(mods->locate("menus/character.txt"))) {
		while(infile.next()) {
			infile.val = infile.val + ',';

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

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

	loadGraphics();
}
Ejemplo n.º 29
0
void loadMiscSettings() {
	FileParser infile;
	// load miscellaneous settings from engine config
	// misc.txt
	if (infile.open("engine/misc.txt")) {
		while (infile.next()) {
			if (infile.key == "save_hpmp")
				SAVE_HPMP = toBool(infile.val);
			else if (infile.key == "corpse_timeout")
				CORPSE_TIMEOUT = toInt(infile.val);
			else if (infile.key == "sell_without_vendor")
				SELL_WITHOUT_VENDOR = toBool(infile.val);
			else if (infile.key == "aim_assist")
				AIM_ASSIST = toInt(infile.val);
			else if (infile.key == "window_title")
				WINDOW_TITLE = infile.val;
			else if (infile.key == "game_prefix")
				GAME_PREFIX = infile.val;
			else if (infile.key == "sound_falloff")
				SOUND_FALLOFF = toInt(infile.val);
			else if (infile.key == "party_exp_percentage")
				PARTY_EXP_PERCENTAGE = toInt(infile.val);
			else if (infile.key == "enable_ally_collision")
				ENABLE_ALLY_COLLISION = toBool(infile.val);
			else if (infile.key == "enable_ally_collision_ai")
				ENABLE_ALLY_COLLISION_AI = toBool(infile.val);
			else if (infile.key == "currency_id") {
				CURRENCY_ID = toInt(infile.val);
				if (CURRENCY_ID < 1) {
					CURRENCY_ID = 1;
					fprintf(stderr, "Currency ID below the minimum allowed value. Resetting it to %d\n", CURRENCY_ID);
				}
			}
			else if (infile.key == "interact_range")
				INTERACT_RANGE = toFloat(infile.val);

		}
		infile.close();
	}
	// resolutions.txt
	if (infile.open("engine/resolutions.txt")) {
		while (infile.next()) {
			if (infile.key == "menu_frame_width")
				FRAME_W = toInt(infile.val);
			else if (infile.key == "menu_frame_height")
				FRAME_H = toInt(infile.val);
			else if (infile.key == "icon_size")
				ICON_SIZE = toInt(infile.val);
			else if (infile.key == "required_width") {
				MIN_VIEW_W = toInt(infile.val);
				if (VIEW_W < MIN_VIEW_W) VIEW_W = MIN_VIEW_W;
				VIEW_W_HALF = VIEW_W/2;
			}
			else if (infile.key == "required_height") {
				MIN_VIEW_H = toInt(infile.val);
				if (VIEW_H < MIN_VIEW_H) VIEW_H = MIN_VIEW_H;
				VIEW_H_HALF = VIEW_H/2;
			}
		}
		infile.close();
	}
	// gameplay.txt
	if (infile.open("engine/gameplay.txt")) {
		while (infile.next()) {
			if (infile.key == "enable_playgame") {
				ENABLE_PLAYGAME = toBool(infile.val);
			}
		}
		infile.close();
	}
	// combat.txt
	if (infile.open("engine/combat.txt")) {
		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);
			else if (infile.key == "min_absorb_percent") MIN_ABSORB = toInt(infile.val);
			else if (infile.key == "min_resist_percent") MIN_RESIST = toInt(infile.val);
			else if (infile.key == "min_block_percent") MIN_BLOCK = toInt(infile.val);
			else if (infile.key == "min_avoidance_percent") MIN_AVOIDANCE = toInt(infile.val);
		}
		infile.close();
	}
	// elements.txt
	if (infile.open("engine/elements.txt")) {
		Element e;
		ELEMENTS.clear();
		while (infile.next()) {
			if (infile.key == "name") e.name = infile.val;
			else if (infile.key == "description") e.description = infile.val;

			if (e.name != "" && e.description != "") {
				ELEMENTS.push_back(e);
				e.name = e.description = "";
			}
		}
		infile.close();
	}
	// equip_flags.txt
	if (infile.open("engine/equip_flags.txt", true, false)) {
		string type,description;
		type = description = "";

		while (infile.next()) {
			if (infile.key == "name") type = infile.val;
			else if (infile.key == "description") description = infile.val;

			if (type != "" && description != "") {
				EQUIP_FLAGS[type] = description;
				type = description = "";
			}
		}
		infile.close();
	}
	// classes.txt
	if (infile.open("engine/classes.txt")) {
		HeroClass c;
		HERO_CLASSES.clear();
		while (infile.next()) {
			if (infile.key == "name") c.name = infile.val;

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

			if (!HERO_CLASSES.empty()) {
				if (infile.key == "description") HERO_CLASSES.back().description = infile.val;
				else if (infile.key == "currency") HERO_CLASSES.back().currency = toInt(infile.val);
				else if (infile.key == "equipment") HERO_CLASSES.back().equipment = infile.val;
				else if (infile.key == "physical") HERO_CLASSES.back().physical = toInt(infile.val);
				else if (infile.key == "mental") HERO_CLASSES.back().mental = toInt(infile.val);
				else if (infile.key == "offense") HERO_CLASSES.back().offense = toInt(infile.val);
				else if (infile.key == "defense") HERO_CLASSES.back().defense = toInt(infile.val);
				else if (infile.key == "actionbar") {
					for (int i=0; i<12; i++) {
						HERO_CLASSES.back().hotkeys[i] = toInt(infile.nextValue());
					}
				}
				else if (infile.key == "powers") {
					string power;
					while ( (power = infile.nextValue()) != "") {
						HERO_CLASSES.back().powers.push_back(toInt(power));
					}
				}
				else if (infile.key == "campaign") {
					string status;
					while ( (status = infile.nextValue()) != "") {
						HERO_CLASSES.back().statuses.push_back(status);
					}
				}
			}
		}
		infile.close();
	}
	// Make a default hero class if none were found
	if (HERO_CLASSES.empty()) {
		HeroClass c;
		c.name = msg->get("Adventurer");
		HERO_CLASSES.push_back(c);
	}

	// death_penalty.txt
	if (infile.open("engine/death_penalty.txt")) {
		while (infile.next()) {
			if (infile.key == "enable") DEATH_PENALTY = toBool(infile.val);
			else if (infile.key == "permadeath") DEATH_PENALTY_PERMADEATH = toBool(infile.val);
			else if (infile.key == "currency") DEATH_PENALTY_CURRENCY = toInt(infile.val);
			else if (infile.key == "xp_total") DEATH_PENALTY_XP = toInt(infile.val);
			else if (infile.key == "xp_current_level") DEATH_PENALTY_XP_CURRENT = toInt(infile.val);
			else if (infile.key == "random_item") DEATH_PENALTY_ITEM = toBool(infile.val);
		}
		infile.close();
	}
}
Ejemplo n.º 30
0
GameStateLoad::GameStateLoad() : GameState() {
	items = new ItemManager();
	portrait = NULL;
	loading_requested = false;
	loading = false;
	loaded = false;

	label_loading = new WidgetLabel();
	label_slots = new WidgetLabel();

	// Confirmation box to confirm deleting
	confirm = new MenuConfirm(msg->get("Delete Save"), msg->get("Delete this save?"));
	button_exit = new WidgetButton(mods->locate("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(mods->locate("images/menus/buttons/button_default.png"));
	button_action->label = msg->get("Choose a Slot");
	button_action->enabled = false;

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

	// Read positions from config file 
	FileParser infile;
	int counter = -1;
	if (infile.open(mods->locate("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.x = eatFirstInt(infile.val, ',');
			name_pos.y = eatFirstInt(infile.val, ',');
		} else if (infile.key == "level") {
			level_pos.x = eatFirstInt(infile.val, ',');
			level_pos.y = eatFirstInt(infile.val, ',');
		} else if (infile.key == "map") {
			map_pos.x = eatFirstInt(infile.val, ',');
			map_pos.y = eatFirstInt(infile.val, ',');
		} else if (infile.key == "sprite") {
			sprites_pos.x = eatFirstInt(infile.val, ',');
			sprites_pos.y = eatFirstInt(infile.val, ',');
		} else if (infile.key == "loading_label") {
			loading_pos.x = eatFirstInt(infile.val, ',');
			loading_pos.y = eatFirstInt(infile.val, ',');
		}
	  }
	  infile.close();
	} else fprintf(stderr, "Unable to open gameload.txt!\n");

	// Load the MenuConfirm positions and alignments from menus/menus.txt
	if (infile.open(mods->locate("menus/menus.txt"))) {
		while (infile.next()) {
			infile.val = infile.val + ',';

			if (infile.key == "confirm") {
				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, ',');
				confirm->alignment = eatFirstString(infile.val, ',');
				confirm->align();
				confirm->update();
				break;
			}
		}
	} else {
		fprintf(stderr, "Unable to open menus.txt!\n");
	}
	infile.close();

	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++) {
		sprites[i] = NULL;
		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");
}