예제 #1
0
int Map::addEventStatBlock(Event &evnt) {
	statblocks.push_back(StatBlock());
	StatBlock *statb = &statblocks.back();

	statb->perfect_accuracy = true; // never miss AND never overhit

	Event_Component *ec_path = evnt.getComponent(EC_POWER_PATH);
	if (ec_path) {
		// source is power path start
		statb->pos.x = static_cast<float>(ec_path->x) + 0.5f;
		statb->pos.y = static_cast<float>(ec_path->y) + 0.5f;
	}
	else {
		// source is event location
		statb->pos.x = static_cast<float>(evnt.location.x) + 0.5f;
		statb->pos.y = static_cast<float>(evnt.location.y) + 0.5f;
	}

	Event_Component *ec_damage = evnt.getComponent(EC_POWER_DAMAGE);
	if (ec_damage) {
		for (size_t i = 0; i < DAMAGE_TYPES_COUNT; ++i) {
			if (i % 2 == 0) {
				statb->starting[STAT_COUNT + i] = ec_damage->a; // min
			}
			else {
				statb->starting[STAT_COUNT + i] = ec_damage->b; // max
			}
		}
	}

	// this is used to store cooldown ticks for a map power
	// the power id, type, etc are not used
	statb->powers_ai.resize(1);

	// make this StatBlock immune to negative status effects
	// this is mostly to prevent a player with a damage return bonus from damaging this StatBlock
	// create a temporary EffectDef for immunity; will be used for map StatBlocks
	EffectDef immunity_effect;
	immunity_effect.id = "MAP_EVENT_IMMUNITY";
	immunity_effect.type = "immunity";
	statb->effects.addEffect(immunity_effect, 0, 0, false, -1, 0, SOURCE_TYPE_ENEMY);

	// ensure the statblock will be alive
	statb->hp = statb->starting[STAT_HP_MAX] = statb->current[STAT_HP_MAX] = 1;

	// ensure that stats are ready to be used by running logic once
	statb->logic();

	return static_cast<int>(statblocks.size())-1;
}
예제 #2
0
Entity& Entity::operator=(const Entity& e) {
	if (this == &e)
		return *this;

	sprites = e.sprites;
	sound_attack = e.sound_attack;
	sound_hit = e.sound_hit;
	sound_die = e.sound_die;
	sound_critdie = e.sound_critdie;
	sound_block = e.sound_block;
	sound_levelup = e.sound_levelup;
	sound_lowhp = e.sound_lowhp;
	activeAnimation = new Animation(*e.activeAnimation);
	animationSet = e.animationSet;
	stats = StatBlock(e.stats);

	return *this;
}
예제 #3
0
Entity::Entity(const Entity &e)
	: sprites(e.sprites)
	, sound_melee(e.sound_melee)
	, sound_mental(e.sound_mental)
	, sound_hit(e.sound_hit)
	, sound_die(e.sound_die)
	, sound_critdie(e.sound_critdie)
	, sound_block(e.sound_block)
	, sound_levelup(e.sound_levelup)
	, play_sfx_phys(e.play_sfx_phys)
	, play_sfx_ment(e.play_sfx_ment)
	, play_sfx_hit(e.play_sfx_hit)
	, play_sfx_die(e.play_sfx_die)
	, play_sfx_critdie(e.play_sfx_critdie)
	, play_sfx_block(e.play_sfx_block)
	, activeAnimation(new Animation(*e.activeAnimation))
	, animationSet(e.animationSet)
	, stats(StatBlock(e.stats)) {
}
예제 #4
0
int Map::load(const std::string& fname) {
	FileParser infile;

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

	music_filename = "";

	// @CLASS Map|Description of maps/
	if (!infile.open(fname))
		return 0;

	this->filename = fname;

	while (infile.next()) {
		if (infile.new_section) {

			// for sections that are stored in collections, add a new object here
			if (infile.section == "enemy")
				enemy_groups.push(Map_Group());
			else if (infile.section == "npc")
				npcs.push(Map_NPC());
			else if (infile.section == "event")
				events.push_back(Event());

		}
		if (infile.section == "header")
			loadHeader(infile);
		else if (infile.section == "layer")
			loadLayer(infile);
		else if (infile.section == "enemy")
			loadEnemyGroup(infile, &enemy_groups.back());
		else if (infile.section == "npc")
			loadNPC(infile);
		else if (infile.section == "event")
			EventManager::loadEvent(infile, &events.back());
	}

	infile.close();

	// create a temporary EffectDef for immunity; will be used for map StatBlocks
	EffectDef immunity_effect;
	immunity_effect.id = "MAP_EVENT_IMMUNITY";
	immunity_effect.type = "immunity";

	// create StatBlocks for events that need powers
	for (unsigned i=0; i<events.size(); ++i) {
		Event_Component *ec_power = events[i].getComponent(EC_POWER);
		if (ec_power) {
			statblocks.push_back(StatBlock());
			StatBlock *statb = &statblocks.back();

			if (!statb) {
				logError("Map: Could not create StatBlock for Event.");
				continue;
			}

			// store the index of this StatBlock so that we can find it when the event is activated
			ec_power->y = static_cast<int>(statblocks.size())-1;

			statb->starting[STAT_ACCURACY] = 1000; // always hit the target

			Event_Component *ec_path = events[i].getComponent(EC_POWER_PATH);
			if (ec_path) {
				// source is power path start
				statb->pos.x = static_cast<float>(ec_path->x) + 0.5f;
				statb->pos.y = static_cast<float>(ec_path->y) + 0.5f;
			}
			else {
				// source is event location
				statb->pos.x = static_cast<float>(events[i].location.x) + 0.5f;
				statb->pos.y = static_cast<float>(events[i].location.y) + 0.5f;
			}

			Event_Component *ec_damage = events[i].getComponent(EC_POWER_DAMAGE);
			if (ec_damage) {
				statb->starting[STAT_DMG_MELEE_MIN] = statb->starting[STAT_DMG_RANGED_MIN] = statb->starting[STAT_DMG_MENT_MIN] = ec_damage->a;
				statb->starting[STAT_DMG_MELEE_MAX] = statb->starting[STAT_DMG_RANGED_MAX] = statb->starting[STAT_DMG_MENT_MAX] = ec_damage->b;
			}

			// this is used to store cooldown ticks for a map power
			// the power id, type, etc are not used
			statb->powers_ai.resize(1);

			// make this StatBlock immune to negative status effects
			// this is mostly to prevent a player with a damage return bonus from damaging this StatBlock
			statb->effects.addEffect(immunity_effect, 0, 0, false, -1, 0, SOURCE_TYPE_ENEMY);
		}
	}

	// ensure that our map contains a collison layer
	if (std::find(layernames.begin(), layernames.end(), "collision") == layernames.end()) {
		layernames.push_back("collision");
		layers.resize(layers.size()+1);
		layers.back().resize(w);
		for (size_t i=0; i<layers.back().size(); ++i) {
			layers.back()[i].resize(h, 0);
		}
		collision_layer = static_cast<int>(layers.size())-1;
	}

	return 0;
}
예제 #5
0
void GameStateLoad::logic() {

	frame_ticker++;
	if (frame_ticker == 64) frame_ticker = 0;
	if (frame_ticker < 32)
		current_frame = frame_ticker / 8;
	else
		current_frame = (63 - frame_ticker) / 8;

	if (button_exit->checkClick()) {
		requestedGameState = new GameStateTitle(screen, inp, font, msg);
	}
	
	if(loading_requested) {
		loading = true;
		loading_requested = false;
		logicLoading();
	}

	if (button_action->checkClick()) {
		if (stats[selected_slot].name == "") {
			// create a new game
			GameStateNew* newgame = new GameStateNew(screen, inp, font, msg);
			newgame->game_slot = selected_slot + 1;
			requestedGameState = newgame;
		}
		else {
			loading_requested = true;
		}
	}
	if (button_alternate->checkClick())
	{
		// Display pop-up to make sure save should be deleted
		confirm->visible = true;
		confirm->render();
	}
	if (confirm->visible) {
		confirm->logic();
		if(confirm->confirmClicked) {
			stringstream filename;
			filename << PATH_USER << "save" << (selected_slot+1) << ".txt";
			if(remove(filename.str().c_str()) != 0)
				perror("Error deleting save from path");
			stats[selected_slot] = StatBlock();
			readGameSlot(selected_slot);
			loadPreview(selected_slot);
			loadPortrait(selected_slot);
			button_alternate->enabled = false;
			button_action->label = msg->get("new_game_button");
			confirm->visible = false;
			confirm->confirmClicked = false;
		}
	}
	// check clicking game slot
	if (inp->pressing[MAIN1] && !inp->lock[MAIN1]) {
		for (int i=0; i<GAME_SLOT_MAX; i++) {
			if (isWithin(slot_pos[i], inp->mouse)) {
				selected_slot = i;
				inp->lock[MAIN1] = true;
				loadPortrait(selected_slot);
				
				button_action->enabled = true;
				if (stats[selected_slot].name == "") {
					button_action->label = msg->get("new_game_button");
					button_alternate->enabled = false;
				}
				else {
					button_action->label = msg->get("load_game_button");
					button_alternate->enabled = true;
				}
			}
		}
	}
}