diff options
-rw-r--r-- | src/client/targets.cc | 33 | ||||
-rw-r--r-- | src/client/targets.h | 3 | ||||
-rw-r--r-- | src/core/entity.cc | 2 | ||||
-rw-r--r-- | src/game/base/ship.cc | 46 |
4 files changed, 59 insertions, 25 deletions
diff --git a/src/client/targets.cc b/src/client/targets.cc index 6809939..8a7f402 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -39,6 +39,7 @@ unsigned int current_target_id = 0; unsigned int current_hover = 0; const core::Entity *current_target = 0; +math::Vector3f cursor_aim; bool is_valid_map_target(const core::Entity *entity) { @@ -295,6 +296,11 @@ void shutdown() core::Func::remove("target_center"); } +const math::Vector3f & aim() +{ + return cursor_aim; +} + // render targets and sounds (in world coordinates) void frame() { @@ -327,14 +333,9 @@ void frame() y = (float)(input::mouse_position_y() - render::State::height() / 2) / (float)render::State::height() / render::State::aspect(); } - Vector3f cursor = render::Camera::eye() + render::Camera::axis().forward() * (render::FRUSTUMFRONT + 0.001); - cursor -= render::Camera::axis().left() * x; - cursor -= render::Camera::axis().up() * y; - - // set aim - if (core::localcontrol()) { - core::localcontrol()->set_target_aim(cursor); - } + cursor_aim.assign(render::Camera::eye() + render::Camera::axis().forward() * (render::FRUSTUMFRONT + 0.001)); + cursor_aim -= render::Camera::axis().left() * x; + cursor_aim -= render::Camera::axis().up() * y; //math::Vector3f center = render::Camera::eye() + (render::Camera::axis().forward() * (render::FRUSTUMFRONT + 0.001f)); for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { @@ -359,7 +360,7 @@ void frame() if (math::dotproduct(render::Camera::axis().forward(), v) > 0.75) { // calculate the distance from entity location to the line [eye - cursor] - float d = math::Vector3f::length(math::crossproduct((cursor - render::Camera::eye()) , (render::Camera::eye() - entity->location()))) / math::Vector3f::length(cursor - render::Camera::eye()); + float d = math::Vector3f::length(math::crossproduct((cursor_aim - render::Camera::eye()) , (render::Camera::eye() - entity->location()))) / math::Vector3f::length(cursor_aim - render::Camera::eye()); float r = entity->radius() * 0.5f; @@ -372,7 +373,7 @@ void frame() // if the cursor-beam hits the entity sphere if (d < r) { - float myz = math::distance(cursor, entity->location()); + float myz = math::distance(cursor_aim, entity->location()); if (z < 0 || myz < z) { current_hover = entity->id(); z = myz; @@ -384,13 +385,21 @@ void frame() } } + float d = 64.0f; // default aim distance + if (!current_target) { current_target_id = 0; } else { current_target_id = current_target->id(); - - + d = math::distance(render::Camera::eye(), current_target->location()); + } + cursor_aim = render::Camera::eye() + (cursor_aim - render::Camera::eye()) / math::distance(render::Camera::eye(), cursor_aim) * d; + + // set aim + if (core::localcontrol()) { + core::localcontrol()->set_target_aim(cursor_aim); } + } } diff --git a/src/client/targets.h b/src/client/targets.h index e66ff97..ed681c3 100644 --- a/src/client/targets.h +++ b/src/client/targets.h @@ -48,6 +48,9 @@ void set_target(unsigned int id); /// target a specific entity void set_target(const core::Entity *entity); +/// return current cursor aim location in world space +const math::Vector3f &cursor_aim(); + } } diff --git a/src/core/entity.cc b/src/core/entity.cc index 4a603f1..589d132 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -1177,6 +1177,7 @@ void EntityControlable::serialize_client_update(std::ostream & os) const os << target_vstrafe << " "; os << target_afterburner << " "; os << target_controlflags << " "; + os << target_aim << " "; } void EntityControlable::receive_client_update(std::istream &is) @@ -1190,6 +1191,7 @@ void EntityControlable::receive_client_update(std::istream &is) is >> target_vstrafe; is >> target_afterburner; is >> target_controlflags; + is >> target_aim; } void EntityControlable::serialize_server_update(std::ostream & os) const diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index ea793af..219cb0c 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -917,22 +917,42 @@ void Ship::frame(const unsigned long elapsed) const Weapon *weapon = static_cast<const Weapon *>(slot->item()->info()); if ((weapon->subtype() == Weapon::Cannon) && (weapon->projectile_interval() > 0) && (slot->last_fired() + weapon->projectile_interval() <= core::server()->timestamp())) { - // spawn a new projectile - core::EntityProjectile *projectile = new core::EntityProjectile(this); + // aim + const float projectile_radius = 0.01f; // FIXME this should be defined somewhere + + math::Axis projectile_axis(axis() * slot->axis()); + math::Vector3f projectile_location(location() + (axis() * slot->location() * modelscale) + projectile_axis.forward() * projectile_radius); + math::Vector3f projectile_direction(target_aim - projectile_location); + projectile_direction.normalize(); + float cosa = math::dotproduct(projectile_direction, projectile_axis.forward()); + + // fire a projectile if the angle between the aim direction and the slot's forward direction is small enough + // TODO configurable aim cone + if (cosa > 0.5f) { + // aim + math::Vector3f normal(math::crossproduct(projectile_direction, projectile_axis.forward())); + if (normal.length() > MIN_DELTA) { + float sina = sqrt(1 - cosa * cosa); + + normal.normalize(); + projectile_axis.rotate(normal, cosa, sina); + } - projectile->set_damage(weapon->damage()); - projectile->set_lifespan(weapon->projectile_lifespan()); - projectile->set_projectile_modelname(weapon->projectile_modelname()); - projectile->set_projectile_soundname(weapon->projectile_soundname()); - - projectile->set_axis(axis() * slot->axis()); - projectile->set_location(location() + (axis() * slot->location() * modelscale) + projectile->axis().forward() * projectile->radius()); - projectile->set_speed(weapon->projectile_speed()); + // spawn a new projectile + core::EntityProjectile *projectile = new core::EntityProjectile(this); - projectile->reset(); - - slot->set_last_fired(core::server()->timestamp()); + projectile->set_damage(weapon->damage()); + projectile->set_lifespan(weapon->projectile_lifespan()); + projectile->set_projectile_modelname(weapon->projectile_modelname()); + projectile->set_projectile_soundname(weapon->projectile_soundname()); + + projectile->set_axis(projectile_axis); + projectile->set_location(projectile_location); + projectile->set_speed(weapon->projectile_speed()); + projectile->reset(); + slot->set_last_fired(core::server()->timestamp()); + } } } } |