Ejemplo n.º 1
0
	void target_closest_enemy::execute_leaf_goal_callback(tree::execution_occurence occ, tree::state_of_traversal& t) const {
		if (occ == tree::execution_occurence::LAST)
			return;

		auto& cosmos = t.step.cosm;
		auto subject = t.subject;
		auto pos = position(subject);
		auto& los = t.step.transient.calculated_line_of_sight.at(subject);
		auto& attitude = subject.get<components::attitude>();

		entity_id closest_hostile_raw;

		float min_distance = std::numeric_limits<float>::max();

		for (auto s_raw : los.visible_sentiences) {
			auto s = cosmos[s_raw];
			auto att = calculate_attitude(s, subject);

			if (att == attitude_type::WANTS_TO_KILL || att == attitude_type::WANTS_TO_KNOCK_UNCONSCIOUS) {
				auto dist = distance_sq(s, subject);

				if (dist < min_distance) {
					closest_hostile_raw = s;
					min_distance = dist;
				}
			}
		}

		auto closest_hostile = cosmos[closest_hostile_raw];

		attitude.currently_attacked_visible_entity = closest_hostile;

		if (closest_hostile.alive()) {
			attitude.is_alert = true;
			attitude.last_seen_target_position_inspected = false;
			attitude.last_seen_target_position = position(closest_hostile);
			attitude.last_seen_target_velocity = velocity(closest_hostile);
		}

		auto crosshair = subject[sub_entity_name::CHARACTER_CROSSHAIR];

		if (crosshair.alive()) {
			auto& crosshair_offset = crosshair.get<components::crosshair>().base_offset;

			float vel1 = assess_projectile_velocity_of_weapon(subject[slot_function::PRIMARY_HAND].get_item_if_any());
			float vel2 = assess_projectile_velocity_of_weapon(subject[slot_function::SECONDARY_HAND].get_item_if_any());
			float vel = std::max(vel1, vel2);

			if (vel > 1.0 && closest_hostile.alive()) {
				vec2 leaded;

				if (velocity(closest_hostile).length_sq() > 1)
					leaded = position(closest_hostile) + velocity(closest_hostile) * distance(closest_hostile, subject) / vel;// direct_solution(position(closest_hostile), velocity(closest_hostile), vel);
				else
					leaded = position(closest_hostile);

				crosshair_offset = leaded - position(subject);
			}
			else if (is_entity_physical(subject)) {
				crosshair_offset = velocity(subject).length() > 3.0 ? velocity(subject) : vec2(10, 0);
			}
			else
				crosshair_offset = vec2(10, 0);
		}
	}
Ejemplo n.º 2
0
	void draw_crosshair_lines(
		std::function<void(vec2, vec2, rgba)> callback,
		std::function<void(vec2, vec2)> dashed_line_callback,
		const interpolation_system& interp,
		const const_entity_handle crosshair, 
		const const_entity_handle character) {
		if (crosshair.alive()) {
			const auto& cosmos = crosshair.get_cosmos();
			const auto& physics = cosmos.systems_temporary.get<physics_system>();

			vec2 line_from[2];
			vec2 line_to[2];

			const auto crosshair_pos = crosshair.viewing_transform(interp).pos;

			const auto guns = character.guns_wielded();

			auto calculate_color = [&](const const_entity_handle target) {
				const auto att = calculate_attitude(character, target);

				if (att == attitude_type::WANTS_TO_KILL || att == attitude_type::WANTS_TO_KNOCK_UNCONSCIOUS) {
					return red;
				}
				else if (att == attitude_type::WANTS_TO_HEAL) {
					return green;
				}
				else {
					return cyan;
				}
			};

			if (guns.size() >= 1) {
				const auto subject_item = guns[0];

				const auto& gun = subject_item.get<components::gun>();

				const auto rifle_transform = subject_item.viewing_transform(interp);
				const auto barrel_center = gun.calculate_barrel_center(rifle_transform);
				const auto muzzle = gun.calculate_muzzle_position(rifle_transform);

				line_from[0] = muzzle;
				
				const auto proj = crosshair_pos.get_projection_multiplier(barrel_center, muzzle);

				if (proj > 1.f) {
					line_to[0] = barrel_center + (muzzle - barrel_center) * proj;
					
					const auto raycast = physics.ray_cast_px(line_from[0], line_to[0], filters::bullet(), subject_item);

					auto col = cyan;

					if (raycast.hit) {
						dashed_line_callback(raycast.intersection, line_to[0]);

						line_to[0] = raycast.intersection;
						col = calculate_color(cosmos[raycast.what_entity]);
					}

					callback(line_from[0], line_to[0], col);
				}
			}

			if (guns.size() >= 2) {
				const auto subject_item = guns[1];

				const auto& gun = subject_item.get<components::gun>();

				const auto rifle_transform = subject_item.viewing_transform(interp);
				const auto barrel_center = gun.calculate_barrel_center(rifle_transform);
				const auto muzzle = gun.calculate_muzzle_position(rifle_transform);

				line_from[1] = muzzle;

				const auto proj = crosshair_pos.get_projection_multiplier(barrel_center, muzzle);

				if (proj > 1.f) {
					line_to[1] = barrel_center + (muzzle - barrel_center) * proj;
					
					const auto raycast = physics.ray_cast_px(line_from[1], line_to[1], filters::bullet(), subject_item);

					auto col = cyan;

					if (raycast.hit) {
						dashed_line_callback(raycast.intersection, line_to[1]);

						line_to[1] = raycast.intersection;
						col = calculate_color(cosmos[raycast.what_entity]);
					}

					callback(line_from[1], line_to[1], col);
				}
			}
		}
	}