void editor_entity_selector::for_each_selected_entity(
	F callback,
	const current_selections_type& signi_selections
) const {
	for (const auto e : signi_selections) {
		if (!found_in(in_rectangular_selection, e)) {
			callback(e);
		}
	}

	for (const auto e : in_rectangular_selection) {
		if (!found_in(signi_selections, e)) {
			callback(e);
		}
	}
}
attitude_type calc_attitude(const const_entity_handle targeter, const const_entity_handle target) {
	const auto& targeter_attitude = targeter.get<components::attitude>();
	const auto* const target_attitude = target.find<components::attitude>();

	if (target_attitude) {
		if (targeter_attitude.official_faction != target_attitude->official_faction) {
			return attitude_type::WANTS_TO_KILL;
		}
		else {
			return attitude_type::WANTS_TO_HEAL;
		}
	}

	if (found_in(targeter_attitude.specific_hostile_entities, target)) {
		return attitude_type::WANTS_TO_KILL;
	}

	return attitude_type::NEUTRAL;
}
Beispiel #3
0
void physics_system::contact_listener::BeginContact(b2Contact* contact) {
	auto& sys = get_sys();
	auto& cosmos = cosm;
	auto delta = cosm.get_fixed_delta();

	for (int i = 0; i < 2; ++i) {
		auto fix_a = contact->GetFixtureA();
		auto fix_b = contact->GetFixtureB();

		int numPoints = contact->GetManifold()->pointCount;
		b2WorldManifold worldManifold;
		contact->GetWorldManifold(&worldManifold);

		if (i == 1) {
			std::swap(fix_a, fix_b);
			if (numPoints > 1) {
				std::swap(worldManifold.points[0], worldManifold.points[1]);
				std::swap(worldManifold.separations[0], worldManifold.separations[1]);
			}
			worldManifold.normal *= -1;
		}

		auto body_a = fix_a->GetBody();
		auto body_b = fix_b->GetBody();

		messages::collision_message msg;

		if (fix_a->IsSensor() || fix_b->IsSensor())
			msg.one_is_sensor = true;

		msg.type = messages::collision_message::event_type::BEGIN_CONTACT;

		auto subject = cosmos[fix_a->GetUserData()];
		auto collider = cosmos[fix_b->GetUserData()];

		msg.subject = subject;
		msg.collider = collider;

		auto& subject_fixtures = subject.get<components::fixtures>();
		auto& collider_fixtures = collider.get<components::fixtures>();

		if (subject_fixtures.is_friction_ground()) {
#if FRICTION_FIELDS_COLLIDE
			if (!collider_fixtures.is_friction_ground)
#endif
			{
				auto& collider_physics = collider_fixtures.get_owner_body().get<components::special_physics>();

				bool found_suitable = false;

				// always accept my own children
				if (are_connected_by_friction(collider, subject)) {
					found_suitable = true;
				}
				else if (collider_physics.since_dropped.lasts(cosm.get_timestamp(), delta)) {
					collider_physics.since_dropped.unset();
					found_suitable = true;
				}
				else {
					for (int i = 0; i < 1; i++) {
						const b2Vec2 pointVelOther = body_b->GetLinearVelocityFromWorldPoint(worldManifold.points[i]);
						const auto velOtherPixels = vec2(pointVelOther) * METERS_TO_PIXELSf;

						if (velOtherPixels.length() > 1) {
							const auto angle = vec2(worldManifold.normal).degrees_between(velOtherPixels);

							if (angle > 90) {
								found_suitable = true;
							}
						}

						if (augs::renderer::get_current().debug_draw_friction_field_collisions_of_entering) {
							augs::renderer::get_current().blink_lines.draw_yellow(METERS_TO_PIXELSf*worldManifold.points[i], METERS_TO_PIXELSf* worldManifold.points[i] + vec2(worldManifold.normal).set_length(150));
							augs::renderer::get_current().blink_lines.draw_red(METERS_TO_PIXELSf*worldManifold.points[i], METERS_TO_PIXELSf* worldManifold.points[i] + velOtherPixels);
						}
					}
				}

				if (found_suitable) {
					auto new_owner = subject_fixtures.get_owner_body().get_id();
					auto& grounds = collider_physics.owner_friction_grounds;
					
					components::special_physics::friction_connection connection(new_owner);
					connection.fixtures_connected = 1;

					if (found_in(grounds, new_owner)) {
						auto found = find_in(grounds, new_owner);
						 LOG("Incr: %x", new_owner);

						connection.fixtures_connected = (*found).fixtures_connected + 1;
						grounds.erase(found);
					}
					else {
						 LOG("Reg: %x", new_owner);
					}
					
					grounds.push_back(connection);

					sys.rechoose_owner_friction_body(collider_fixtures.get_owner_body());
				}
			}
		}

		msg.point = worldManifold.points[0];
		msg.point *= METERS_TO_PIXELSf;

		msg.subject_impact_velocity = body_a->GetLinearVelocityFromWorldPoint(worldManifold.points[0]);
		msg.collider_impact_velocity = body_b->GetLinearVelocityFromWorldPoint(worldManifold.points[0]);
		sys.accumulated_messages.push_back(msg);
	}
}