Пример #1
0
void GameStatePlay::checkCutscene() {
	if (!mapr->cutscene)
		return;

	GameStateCutscene *cutscene = new GameStateCutscene(NULL);

	if (!cutscene->load(mapr->cutscene_file)) {
		delete cutscene;
		mapr->cutscene = false;
		return;
	}

	// handle respawn point and set game play game_slot
	cutscene->game_slot = save_load->getGameSlot();

	if (mapr->teleportation) {

		if (mapr->teleport_mapname != "")
			mapr->respawn_map = mapr->teleport_mapname;

		mapr->respawn_point = mapr->teleport_destination;

	}
	else {
		mapr->respawn_point = FPointToPoint(pc->stats.pos);
	}

	if (SAVE_ONLOAD)
		save_load->saveGame();

	delete requestedGameState;
	requestedGameState = cutscene;
}
Пример #2
0
void GameStatePlay::checkSaveEvent() {
	if (mapr->save_game) {
		mapr->respawn_point = FPointToPoint(pc->stats.pos);
		save_load->saveGame();
		mapr->save_game = false;
	}
}
Пример #3
0
void GameStateLoad::render() {

	Rect src;
	Rect dest;


	// portrait
	if (selected_slot >= 0 && portrait != NULL && portrait_border != NULL) {
		render_device->render(portrait);
		dest.x = int(portrait->getDest().x);
		dest.y = int(portrait->getDest().y);
		portrait_border->setDest(dest);
		render_device->render(portrait_border);
	}

	Point label;
	std::stringstream ss;

	if (loading_requested || loading || loaded) {
		label.x = loading_pos.x + (VIEW_W - FRAME_W)/2;
		label.y = loading_pos.y + (VIEW_H - FRAME_H)/2;

		if ( loaded) {
			label_loading->set(msg->get("Entering game world..."));
		}
		else {
			label_loading->set(msg->get("Loading saved game..."));
		}

		label_loading->set(label.x, label.y, loading_pos.justify, loading_pos.valign, label_loading->get(), color_normal, loading_pos.font_style);
		label_loading->render();
	}

	Color color_permadeath_enabled = font->getColor("hardcore_color_name");

	// display text
	for (int slot=0; slot<visible_slots; slot++) {
		int off_slot = slot+scroll_offset;

		// slot background
		if (background) {
			src.x = 0;
			src.y = (off_slot % 4) * gameslot_pos.h;
			dest.w = dest.h = 0;

			src.w = gameslot_pos.w;
			src.h = gameslot_pos.h;
			dest.x = slot_pos[slot].x;
			dest.y = slot_pos[slot].y;

			background->setClip(src);
			background->setDest(dest);
			render_device->render(background);
		}
		Point slot_dest = FPointToPoint(background->getDest());

		Color color_used = game_slots[off_slot]->stats.permadeath ? color_permadeath_enabled : color_normal;

		// name
		label.x = slot_pos[slot].x + name_pos.x;
		label.y = slot_pos[slot].y + name_pos.y;
		game_slots[off_slot]->label_name.set(label.x, label.y, name_pos.justify, name_pos.valign, game_slots[off_slot]->stats.name, color_used, name_pos.font_style);
		if (text_trim_boundary > 0 && game_slots[off_slot]->label_name.bounds.x + game_slots[off_slot]->label_name.bounds.w >= text_trim_boundary + slot_dest.x)
			game_slots[off_slot]->label_name.setMaxWidth(text_trim_boundary - (game_slots[off_slot]->label_name.bounds.x - slot_dest.x));
		game_slots[off_slot]->label_name.render();

		// level
		ss.str("");
		label.x = slot_pos[slot].x + level_pos.x;
		label.y = slot_pos[slot].y + level_pos.y;
		ss << msg->get("Level %d", game_slots[off_slot]->stats.level);
		if (game_slots[off_slot]->stats.permadeath)
			ss << ", " + msg->get("Permadeath");
		game_slots[off_slot]->label_level.set(label.x, label.y, level_pos.justify, level_pos.valign, ss.str(), color_normal, level_pos.font_style);
		if (text_trim_boundary > 0 && game_slots[off_slot]->label_level.bounds.x + game_slots[off_slot]->label_level.bounds.w >= text_trim_boundary + slot_dest.x)
			game_slots[off_slot]->label_level.setMaxWidth(text_trim_boundary - (game_slots[off_slot]->label_level.bounds.x - slot_dest.x));
		game_slots[off_slot]->label_level.render();

		// class
		label.x = slot_pos[slot].x + class_pos.x;
		label.y = slot_pos[slot].y + class_pos.y;
		game_slots[off_slot]->label_class.set(label.x, label.y, class_pos.justify, class_pos.valign, game_slots[off_slot]->stats.getLongClass(), color_normal, class_pos.font_style);
		if (text_trim_boundary > 0 && game_slots[off_slot]->label_class.bounds.x + game_slots[off_slot]->label_class.bounds.w >= text_trim_boundary + slot_dest.x)
			game_slots[off_slot]->label_class.setMaxWidth(text_trim_boundary - (game_slots[off_slot]->label_class.bounds.x - slot_dest.x));
		game_slots[off_slot]->label_class.render();

		// map
		label.x = slot_pos[slot].x + map_pos.x;
		label.y = slot_pos[slot].y + map_pos.y;
		game_slots[off_slot]->label_map.set(label.x, label.y, map_pos.justify, map_pos.valign, game_slots[off_slot]->current_map, color_normal, map_pos.font_style);
		if (text_trim_boundary > 0 && game_slots[off_slot]->label_map.bounds.x + game_slots[off_slot]->label_map.bounds.w >= text_trim_boundary + slot_dest.x)
			game_slots[off_slot]->label_map.setMaxWidth(text_trim_boundary - (game_slots[off_slot]->label_map.bounds.x - slot_dest.x));
		game_slots[off_slot]->label_map.render();

		// render character preview
		dest.x = slot_pos[slot].x + sprites_pos.x;
		dest.y = slot_pos[slot].y + sprites_pos.y;
		game_slots[off_slot]->preview.setPos(Point(dest.x, dest.y));
		game_slots[off_slot]->preview.render();

		// slot number
		std::stringstream off_slot_str;
		off_slot_str << "#" << off_slot + 1;
		label.x = slot_pos[slot].x + slot_number_pos.x;
		label.y = slot_pos[slot].y + slot_number_pos.y;
		game_slots[off_slot]->label_slot_number.set(label.x, label.y, slot_number_pos.justify, slot_number_pos.valign, off_slot_str.str(), color_normal, slot_number_pos.font_style);
		if (text_trim_boundary > 0 && game_slots[off_slot]->label_slot_number.bounds.x + game_slots[off_slot]->label_slot_number.bounds.w >= text_trim_boundary + slot_dest.x)
			game_slots[off_slot]->label_slot_number.setMaxWidth(text_trim_boundary - (game_slots[off_slot]->label_slot_number.bounds.x - slot_dest.x));
		game_slots[off_slot]->label_slot_number.render();

	}

	// display selection
	if (selected_slot >= scroll_offset && selected_slot < visible_slots+scroll_offset && selection != NULL) {
		selection->setDest(slot_pos[selected_slot-scroll_offset]);
		render_device->render(selection);
	}

	if (has_scroll_bar)
		scrollbar->render();

	// display warnings
	if (confirm->visible) confirm->render();

	// display buttons
	button_exit->render();
	button_new->render();
	button_load->render();
	button_delete->render();
}
Пример #4
0
void LootManager::checkLoot(std::vector<Event_Component> &loot_table, FPoint *pos, std::vector<ItemStack> *itemstack_vec) {
	if (hero == NULL) {
		logError("LootManager: checkLoot() failed, no hero.");
		return;
	}

	FPoint p;
	Event_Component *ec;
	ItemStack new_loot;
	std::vector<Event_Component*> possible_ids;

	int chance = rand() % 100;

	// first drop any 'fixed' (0% chance) items
	for (size_t i = loot_table.size(); i > 0; i--) {
		ec = &loot_table[i-1];
		if (ec->z == 0) {
			Point src;
			if (pos) {
				src = FPointToPoint(*pos);
			}
			else {
				src.x = ec->x;
				src.y = ec->y;
			}
			p.x = static_cast<float>(src.x) + 0.5f;
			p.y = static_cast<float>(src.y) + 0.5f;

			if (!mapr->collider.is_valid_position(p.x, p.y, MOVEMENT_NORMAL, false)) {
				p = mapr->collider.get_random_neighbor(src, drop_radius);

				if (!mapr->collider.is_valid_position(p.x, p.y, MOVEMENT_NORMAL, false)) {
					p = hero->pos;
				}
				else {
					if (src.x == static_cast<int>(p.x) && src.y == static_cast<int>(p.y))
						p = hero->pos;

					mapr->collider.block(p.x, p.y, false);
					tiles_to_unblock.push_back(FPointToPoint(p));
				}
			}

			new_loot.quantity = randBetween(ec->a,ec->b);

			// an item id of 0 means we should drop currency instead
			if (ec->c == 0 || ec->c == CURRENCY_ID) {
				new_loot.item = CURRENCY_ID;
				new_loot.quantity = new_loot.quantity * (100 + hero->get(STAT_CURRENCY_FIND)) / 100;
			}
			else {
				new_loot.item = ec->c;
			}

			if (itemstack_vec)
				itemstack_vec->push_back(new_loot);
			else
				addLoot(new_loot, p);

			loot_table.erase(loot_table.begin()+i-1);
		}
	}

	// now pick up to 1 random item to drop
	int threshold = hero->get(STAT_ITEM_FIND) + 100;
	for (unsigned i = 0; i < loot_table.size(); i++) {
		ec = &loot_table[i];

		int real_chance = ec->z;

		if (ec->c != 0 && ec->c != CURRENCY_ID) {
			real_chance = static_cast<int>(static_cast<float>(ec->z) * static_cast<float>(hero->get(STAT_ITEM_FIND) + 100) / 100.f);
		}

		if (real_chance >= chance) {
			if (real_chance <= threshold) {
				if (real_chance != threshold) {
					possible_ids.clear();
				}

				threshold = real_chance;
			}

			if (chance <= threshold) {
				possible_ids.push_back(ec);
			}
		}
	}

	if (!possible_ids.empty()) {
		// if there was more than one item with the same chance, randomly pick one of them
		size_t chosen_loot = static_cast<size_t>(rand()) % possible_ids.size();

		ec = possible_ids[chosen_loot];

		Point src;
		if (pos) {
			src = FPointToPoint(*pos);
		}
		else {
			src.x = ec->x;
			src.y = ec->y;
		}
		p.x = static_cast<float>(src.x) + 0.5f;
		p.y = static_cast<float>(src.y) + 0.5f;

		if (!mapr->collider.is_valid_position(p.x, p.y, MOVEMENT_NORMAL, false)) {
			p = mapr->collider.get_random_neighbor(src, drop_radius);

			if (!mapr->collider.is_valid_position(p.x, p.y, MOVEMENT_NORMAL, false)) {
				p = hero->pos;
			}
			else {
				if (src.x == static_cast<int>(p.x) && src.y == static_cast<int>(p.y))
					p = hero->pos;

				mapr->collider.block(p.x, p.y, false);
				tiles_to_unblock.push_back(FPointToPoint(p));
			}
		}

		new_loot.quantity = randBetween(ec->a,ec->b);

		// an item id of 0 means we should drop currency instead
		if (ec->c == 0 || ec->c == CURRENCY_ID) {
			new_loot.item = CURRENCY_ID;
			new_loot.quantity = new_loot.quantity * (100 + hero->get(STAT_CURRENCY_FIND)) / 100;
		}
		else {
			new_loot.item = ec->c;
		}

		if (itemstack_vec)
			itemstack_vec->push_back(new_loot);
		else
			addLoot(new_loot, p);
	}
}
Пример #5
0
void GameStatePlay::checkTeleport() {
	bool on_load_teleport = false;

	// both map events and player powers can cause teleportation
	if (mapr->teleportation || pc->stats.teleportation) {

		mapr->collider.unblock(pc->stats.pos.x, pc->stats.pos.y);

		if (mapr->teleportation) {
			mapr->cam.x = pc->stats.pos.x = mapr->teleport_destination.x;
			mapr->cam.y = pc->stats.pos.y = mapr->teleport_destination.y;
		}
		else {
			mapr->cam.x = pc->stats.pos.x = pc->stats.teleport_destination.x;
			mapr->cam.y = pc->stats.pos.y = pc->stats.teleport_destination.y;
		}

		// if we're not changing map, move allies to a the player's new position
		// when changing maps, enemies->handleNewMap() does something similar to this
		if (mapr->teleport_mapname.empty()) {
			FPoint spawn_pos = mapr->collider.get_random_neighbor(FPointToPoint(pc->stats.pos), 1, false);
			for (unsigned int i=0; i < enemies->enemies.size(); i++) {
				if(enemies->enemies[i]->stats.hero_ally && enemies->enemies[i]->stats.alive) {
					mapr->collider.unblock(enemies->enemies[i]->stats.pos.x, enemies->enemies[i]->stats.pos.y);
					enemies->enemies[i]->stats.pos = spawn_pos;
					mapr->collider.block(enemies->enemies[i]->stats.pos.x, enemies->enemies[i]->stats.pos.y, true);
				}
			}
		}

		// process intermap teleport
		if (mapr->teleportation && !mapr->teleport_mapname.empty()) {
			std::string teleport_mapname = mapr->teleport_mapname;
			mapr->teleport_mapname = "";
			inpt->lock_all = (teleport_mapname == "maps/spawn.txt");
			mapr->executeOnMapExitEvents();
			showLoading();
			mapr->load(teleport_mapname);
			setLoadingFrame();
			enemies->handleNewMap();
			hazards->handleNewMap();
			loot->handleNewMap();
			powers->handleNewMap(&mapr->collider);
			menu->enemy->handleNewMap();
			npcs->handleNewMap();
			resetNPC();
			menu->stash->visible = false;
			menu->mini->prerender(&mapr->collider, mapr->w, mapr->h);
			npc_id = nearest_npc = -1;

			// use the default hero spawn position for this map
			if (mapr->teleport_destination.x == -1 && mapr->teleport_destination.y == -1) {
				mapr->cam.x = pc->stats.pos.x = mapr->hero_pos.x;
				mapr->cam.y = pc->stats.pos.y = mapr->hero_pos.y;
			}

			// store this as the new respawn point (provided the tile is open)
			if (mapr->collider.is_valid_position(pc->stats.pos.x, pc->stats.pos.y, MOVEMENT_NORMAL, true)) {
				mapr->respawn_map = teleport_mapname;
				mapr->respawn_point = pc->stats.pos;
			}
			else {
				logError("GameStatePlay: Spawn position (%d, %d) is blocked.", static_cast<int>(pc->stats.pos.x), static_cast<int>(pc->stats.pos.y));
			}

			// return to title (permadeath) OR auto-save
			if (pc->stats.permadeath && pc->stats.corpse) {
				removeSaveDir(save_load->getGameSlot());

				snd->stopMusic();
				delete requestedGameState;
				requestedGameState = new GameStateTitle();
			}
			else if (SAVE_ONLOAD) {
				save_load->saveGame();
			}

			// switch off teleport flag so we can check if an on_load event has teleportation
			mapr->teleportation = false;

			mapr->executeOnLoadEvents();
			if (mapr->teleportation)
				on_load_teleport = true;
		}

		mapr->collider.block(pc->stats.pos.x, pc->stats.pos.y, false);

		pc->stats.teleportation = false;

	}

	if (!on_load_teleport && mapr->teleport_mapname.empty())
		mapr->teleportation = false;
}