diff options
Diffstat (limited to 'src/client/targets.cc')
-rw-r--r-- | src/client/targets.cc | 177 |
1 files changed, 171 insertions, 6 deletions
diff --git a/src/client/targets.cc b/src/client/targets.cc index a6699b0..00a2e86 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -15,31 +15,150 @@ #include "audio/audio.h" #include "audio/sources.h" #include "client/view.h" +#include "core/application.h" #include "core/gameinterface.h" #include "core/entity.h" +#include "core/func.h" +#include "math/vector3f.h" #include "render/render.h" #include "render/gl.h" #include "render/text.h" namespace client { -core::Cvar *draw_target = 0; +namespace targets { +const float TARGETBOXRADIUS = 0.025f; +unsigned int current_target_id = 0; +core::Entity *current_target = 0; core::Cvar *snd_engines = 0; -namespace targets { +bool is_legal_target(core::Entity *entity) +{ + if (entity->id() == core::localcontrol()->id()) + return false; + else + return true; +} + +void func_target_next(std::string const &args) +{ + if (!core::localcontrol()) + return; + + if (!core::Entity::registry.size()) { + current_target = 0; + current_target_id = 0; + return; + } + + std::map<unsigned int, core::Entity *>::iterator it = core::Entity::registry.begin(); + if (!current_target_id) { + // last entity + it = core::Entity::registry.begin(); + } else { + // current entity + it = core::Entity::registry.find(current_target_id); + + // next entity + if (it != core::Entity::registry.end()) + it++; + if (it == core::Entity::registry.end()) { + it = core::Entity::registry.begin(); + } + } +/* + // next while not a legal target + while (it != core::Entity::registry.end() && !is_legal_target((*it).second)) + it++; +*/ + if (it != core::Entity::registry.end()) { + current_target = (*it).second; + current_target_id = current_target->id(); + core::application()->notify_sound("ui/target"); + } else { + current_target = 0; + current_target_id = 0; + + } +} + +void func_target_prev(std::string const &args) +{ + if (!core::localcontrol()) + return; + + if (!core::Entity::registry.size()) { + current_target = 0; + current_target_id = 0; + return; + } + + std::map<unsigned int, core::Entity *>::reverse_iterator rit = core::Entity::registry.rbegin(); + if (!current_target_id) { + // last entity + rit = core::Entity::registry.rbegin(); + } else { + // current entity + while (rit != core::Entity::registry.rend() && ((*rit).first != current_target_id)) + ++rit; + // previous entity + if (rit != core::Entity::registry.rend()) + ++rit; + if (rit == core::Entity::registry.rend()) + rit = core::Entity::registry.rbegin(); + } +/* + // previous while not a legal target + while (rit != core::Entity::registry.rend() && is_legal_target((*rit).second)) + ++rit; +*/ + if (rit != core::Entity::registry.rend()) { + current_target = (*rit).second; + current_target_id = current_target->id(); + core::application()->notify_sound("ui/target"); + } else { + current_target = 0; + current_target_id = 0; + + } +} + +core::Entity* current() +{ + return current_target; +} void init() { snd_engines = core::Cvar::get("snd_engines", "1", core::Cvar::Archive); snd_engines->set_info("[bool] enable or disable engine sounds"); - draw_target = core::Cvar::get("draw_target", "1", core::Cvar::Archive); - draw_target->set_info("[bool] draw target information"); + core::Func *func = 0; + + func = core::Func::add("target_next", func_target_next); + func->set_info("select next target"); + + core::Func::add("target_prev", func_target_prev); + func->set_info("select previous target"); + + current_target = 0; + current_target_id = 0; } void shutdown() { + current_target = 0; + current_target_id = 0; + + core::Func::remove("target_next"); + core::Func::remove("target_prev"); +} + +void reset() +{ + current_target = 0; + current_target_id = 0; } void render_listener_sound() @@ -68,7 +187,7 @@ void render_entity_sound(core::Entity *entity) core::EntityControlable *entitycontrolable = (core::EntityControlable *) entity; core::ClientState *state = entity->state(); - if (entity->model() && state->detailvisible() && entitycontrolable->thrust() > 0 ) { + if (entity->model() && state->detailvisible() && entitycontrolable->thrust() > 0 ) { float speed = entitycontrolable->speed(); float pitch = 0.2f + entitycontrolable->thrust() * 0.8f; @@ -95,15 +214,61 @@ void render_entity_sound(core::Entity *entity) } } -// render ingame sounds +// render client targets void draw() { + + using math::Vector3f; + render_listener_sound(); + current_target = 0; + + math::Vector3f center = render::Camera::eye() + (render::Camera::axis().forward() * (render::frustum_front +0.01f)); for (std::map<unsigned int, core::Entity *>::iterator it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) { core::Entity *entity = (*it).second; + // render entity sound render_entity_sound(entity); + + // calculate target information + if (entity->id() == current_target_id) { + current_target = entity; + + // if target is in visible space + Vector3f v(entity->state()->location() - render::Camera::eye()); + v.normalize(); + if (math::dotproduct(render::Camera::axis().forward(), v) > 0.75 ) { + + // find the intersection of the line [ eye - target ] in the frustum front plane + Vector3f const &plane_normal = render::Camera::axis().forward(); + Vector3f const &plane_point = render::Camera::eye() + render::Camera::axis().forward() * (render::frustum_front + 0.001); + + float d = (plane_normal.x * plane_point.x + plane_normal.y * plane_point.y + plane_normal.z * plane_point.z); + float t = d - plane_normal.x * render::Camera::eye().x + - plane_normal.y * render::Camera::eye().y + - plane_normal.z * render::Camera::eye().z; + t /= plane_normal.x * (entity->state()->location().x - render::Camera::eye().x) + + plane_normal.y * (entity->state()->location().y - render::Camera::eye().y) + + plane_normal.z * (entity->state()->location().z - render::Camera::eye().z); + + Vector3f intersection = render::Camera::eye() + (entity->state()->location() - render::Camera::eye()) * t; + + // draw the target cursor in the frustum front plane, but in real world coordinates + const float r = 0.05; + render::gl::color(1, 1, 1, 1); + render::gl::begin(render::gl::LineLoop); + render::gl::vertex(intersection + render::Camera::axis().up() * r); + render::gl::vertex(intersection + render::Camera::axis().left() * r); + render::gl::vertex(intersection - render::Camera::axis().up() * r); + render::gl::vertex(intersection - render::Camera::axis().left() * r); + render::gl::end(); + } + } + } + + if (!current_target) { + current_target_id = 0; } } |