Intersection World::trace(const Segment &segment, const FindFilter &filter) const { Intersection out; if(filter.m_flags & Flags::tile) { pair<int, float> isect = m_tile_map.trace(segment, -1, filter.m_flags); if(isect.first != -1) out = Intersection(ObjectRef(isect.first, false), isect.second); } if(filter.m_flags & Flags::entity) { int ignore_index = filterIgnoreIndex(filter); pair<int, float> isect = m_entity_map.trace(segment, ignore_index, filter.m_flags); if(isect.first != -1 && isect.second <= out.distance()) out = Intersection(ObjectRef(isect.first, true), isect.second); } return out; }
Intersection WorldViewer::trace(const Segment &segment, const FindFilter &filter) const { Intersection out; if(filter.flags() & Flags::tile) out = m_world->trace(segment, (filter.flags() & ~Flags::entity) | Flags::visible); if(filter.flags() & Flags::entity) { int ignore_index = m_world->filterIgnoreIndex(filter); for(int n = 0; n < (int)m_entities.size(); n++) { const Entity *entity = refEntity(n); if(!entity || !m_occluder_config.isVisible(m_entities[n].occluder_id) || !Flags::test(entity->flags(), filter.flags()) || n == ignore_index) continue; float distance = intersection(segment, entity->boundingBox()); if(distance < out.distance()) out = Intersection(ObjectRef(n, true), distance); } } return out; }
void Turret::fireProjectile(const FBox &target_box, const Weapon &weapon, float randomness) { if(isClient()) return; Segment best_ray = computeBestShootingRay(target_box, weapon); if(randomness > 0.0f) { float3 dir = perturbVector(best_ray.dir(), random(), random(), randomness); best_ray = Ray(best_ray.origin(), dir); } #ifdef DEBUG_SHOOTING { m_aiming_lines.clear(); m_aiming_lines.push_back(best_ray.origin()); Intersection isect = trace(best_ray, {Flags::all | Flags::colliding, ref()}); m_aiming_lines.push_back(best_ray.origin() + best_ray.dir() * isect.distance()); } #endif //TODO: spawned projectiles should be centered if( const ProjectileProto *proj_proto = weapon.projectileProto() ) addNewEntity<Projectile>(best_ray.origin(), *proj_proto, actualDirAngle(), best_ray.dir(), ref(), weapon.proto().damage_mod); }