bool simulated_attack(const map_location& attacker_loc, const map_location& defender_loc, double attacker_hp, double defender_hp){
	LOG_AI_SIM_ACTIONS << "Simulated attack" << std::endl;

	unit_map::iterator attack_unit = resources::gameboard->units().find(attacker_loc);
	unit_map::iterator defend_unit = resources::gameboard->units().find(defender_loc);

	LOG_AI_SIM_ACTIONS << attack_unit->type_name() << " at " << attacker_loc << " attack "
		<< defend_unit->type_name() << " at " << defender_loc << std::endl;
	LOG_AI_SIM_ACTIONS << "attacker's hp before attack: " << attack_unit->hitpoints() << std::endl;
	LOG_AI_SIM_ACTIONS << "defender's hp before attack: " << defend_unit->hitpoints() << std::endl;

	attack_unit->set_hitpoints(static_cast<int>(attacker_hp));
	defend_unit->set_hitpoints(static_cast<int>(defender_hp));

	LOG_AI_SIM_ACTIONS << "attacker's hp after attack: " << attack_unit->hitpoints() << std::endl;
	LOG_AI_SIM_ACTIONS << "defender's hp after attack: " << defend_unit->hitpoints() << std::endl;

	int attacker_xp = game_config::combat_xp(defend_unit->level());
	int defender_xp = game_config::combat_xp(attack_unit->level());
	bool attacker_died = false;
	bool defender_died = false;
	if(attack_unit->hitpoints() <= 0){
		attacker_xp = 0;
		defender_xp = game_config::kill_xp(attack_unit->level());
		(resources::gameboard->units()).erase(attacker_loc);
		attacker_died = true;
	}

	if(defend_unit->hitpoints() <= 0){
		defender_xp = 0;
		attacker_xp = game_config::kill_xp(defend_unit->level());
		(resources::gameboard->units()).erase(defender_loc);
		defender_died = true;
	}

	if(!attacker_died){
		attack_unit->set_experience(attack_unit->experience()+attacker_xp);
		helper_advance_unit(attacker_loc);
		simulated_stopunit(attacker_loc, true, true);
	}

	if(!defender_died){
		defend_unit->set_experience(defend_unit->experience()+defender_xp);
		helper_advance_unit(defender_loc);
		simulated_stopunit(defender_loc, true, true);
	}

	return true;
}
示例#2
0
void stopunit_result::do_execute()
{
	LOG_AI_ACTIONS << "start of execution of: " << *this << std::endl;
	assert(is_success());
	unit_map::iterator un = resources::gameboard->units().find(unit_location_);

	if(resources::simulation_){
		bool gamestate_changed = simulated_stopunit(unit_location_, remove_movement_, remove_attacks_);

		sim_gamestate_changed(this, gamestate_changed);

		return;
	}

	try {
		if (remove_movement_){
			un->remove_movement_ai();
			set_gamestate_changed();
			manager::raise_gamestate_changed();
		}
		if (remove_attacks_){
			un->remove_attacks_ai();
			set_gamestate_changed();
			manager::raise_gamestate_changed();//to be on the safe side
		}
	} catch (...) {
		if (!is_ok()) { DBG_AI_ACTIONS << "Return value of AI ACTION was not checked." << std::endl; } //Demotes to DBG "unchecked result" warning
		throw;
	}
}
示例#3
0
void move_result::do_execute()
{
	LOG_AI_ACTIONS << "start of execution of: "<< *this << std::endl;
	assert(is_success());

	if(resources::simulation_){
		bool gamestate_changed = false;
		if(from_ != to_){
			int step = route_->steps.size();
			gamestate_changed = simulated_move(get_side(), from_, to_, step, unit_location_);
		} else {
			assert(remove_movement_);
		}

		unit_map::const_iterator un = resources::gameboard->units().find(unit_location_);
		if(remove_movement_ && un->movement_left() > 0 && unit_location_ == to_){
			gamestate_changed = simulated_stopunit(unit_location_, true, false);
		}

		sim_gamestate_changed(this, gamestate_changed);

		return;
	}

	::actions::move_unit_spectator move_spectator(resources::gameboard->units());
	move_spectator.set_unit(resources::gameboard->units().find(from_));

	if (from_ != to_) {
		size_t num_steps = ::actions::move_unit_and_record(
			/*std::vector<map_location> steps*/ route_->steps,
			/*::actions::undo_list* undo_stack*/ nullptr,
			/*bool continue_move*/ true, ///@todo 1.9 set to false after implemeting interrupt awareness
			/*bool show_move*/ !preferences::skip_ai_moves(),
			/*bool* interrupted*/ nullptr,
			/*::actions::move_unit_spectator* move_spectator*/ &move_spectator);

		if ( num_steps > 0 ) {
			set_gamestate_changed();
		} else if ( move_spectator.get_ambusher().valid() ) {
			// Unlikely, but some types of strange WML (or bad pathfinding)
			// could cause an ambusher to be found without moving.
			set_gamestate_changed();
		}
	} else {
		assert(remove_movement_);
	}

	if (move_spectator.get_unit().valid()){
		unit_location_ = move_spectator.get_unit()->get_location();
		if (remove_movement_ && move_spectator.get_unit()->movement_left() > 0 && unit_location_ == to_)
		{
			stopunit_result_ptr stopunit_res = actions::execute_stopunit_action(get_side(),true,unit_location_,true,false);
			if (!stopunit_res->is_ok()) {
				set_error(stopunit_res->get_status());
			}
			if (stopunit_res->is_gamestate_changed()) {
				set_gamestate_changed();
			}
		}
	} else {
		unit_location_ = map_location();
	}

	has_ambusher_ = move_spectator.get_ambusher().valid();
	has_interrupted_teleport_ = move_spectator.get_failed_teleport().valid();

	if (is_gamestate_changed()) {
		try {
			manager::raise_gamestate_changed();
		} catch (...) {
			if (!is_ok()) { DBG_AI_ACTIONS << "Return value of AI ACTION was not checked." << std::endl; } //Demotes to DBG "unchecked result" warning
			throw;
		}
	}
}