Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/targets.cc33
-rw-r--r--src/client/targets.h3
-rw-r--r--src/core/entity.cc2
-rw-r--r--src/game/base/ship.cc46
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());
+ }
}
}
}