From 8ad20ed0462227463a5e3b94683d8c1c5a650494 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 20 Jul 2008 17:37:03 +0000 Subject: targetting --- src/client/keyboard.cc | 7 +- src/client/targets.cc | 177 +++++++++++++++++++++++++++++++++++++++++++++++-- src/client/targets.h | 6 +- src/client/video.cc | 5 ++ src/client/view.cc | 22 ++++-- 5 files changed, 203 insertions(+), 14 deletions(-) (limited to 'src/client') diff --git a/src/client/keyboard.cc b/src/client/keyboard.cc index be2240a..4237b20 100644 --- a/src/client/keyboard.cc +++ b/src/client/keyboard.cc @@ -87,9 +87,9 @@ Keyboard::Keyboard() add_key("k", SDLK_k, 'k'); add_key("l", SDLK_l, 'l'); add_key("m", SDLK_m, 'm'); - add_key("n", SDLK_n, 'n'); + add_key("n", SDLK_n, 'n', "target_next"); add_key("o", SDLK_o, 'o'); - add_key("p", SDLK_p, 'p'); + add_key("p", SDLK_p, 'p', "target_prev"); add_key("q", SDLK_q, 'q'); add_key("r", SDLK_r, 'r'); add_key("s", SDLK_s, 's'); @@ -213,9 +213,12 @@ void Keyboard::save_binds() Key *key = (*it).second; if (key->bind().size()) { ofs << "bind " << key->name() << " " << key->bind() << std::endl; + } + /* } else { ofs << "unbind " << key->name() << std::endl; } + */ } ofs.close(); } 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::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::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::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; } } diff --git a/src/client/targets.h b/src/client/targets.h index 7e7ce26..32ea7cd 100644 --- a/src/client/targets.h +++ b/src/client/targets.h @@ -7,6 +7,7 @@ #ifndef __INCLUDED_CLIENT_TARGETS_H__ #define __INCLUDED_CLIENT_TARGETS_H__ +#include "core/entity.h" #include "render/render.h" #include "render/gl.h" #include "render/text.h" @@ -29,9 +30,12 @@ void render_listener_sound(); /// render the sound for one entity void render_entity_sound(core::Entity *Entity); +/// current selected target, 0 if there is no current targer +core::Entity *current(); + } } -#endif +#endif //__INCLUDED_CLIENT_TARGETS_H__ diff --git a/src/client/video.cc b/src/client/video.cc index 0dfe8ef..3566481 100644 --- a/src/client/video.cc +++ b/src/client/video.cc @@ -57,8 +57,13 @@ bool init() // initialize cvars r_width = core::Cvar::get("r_width", width_default, core::Cvar::Archive); + r_width->set_info("[int] video resolution width"); + r_height = core::Cvar::get("r_height", height_default, core::Cvar::Archive); + r_height->set_info("[int] video resolution height"); + r_fullscreen = core::Cvar::get("r_fullscreen", "0", core::Cvar::Archive); + r_fullscreen->set_info("[bool] enable or disable fullscreen video"); int bpp = 0; int flags = 0; diff --git a/src/client/view.cc b/src/client/view.cc index 8f01ad5..1ee50ed 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -132,6 +132,22 @@ void draw_status() std::setw(7) << core::localcontrol()->location().z; Text::draw(4, video::height - Text::fontheight()*2 -4, location); } + + core::Entity *entity = targets::current(); + if (entity) { + std::stringstream target; + target << "^B" << entity->name() << "\n"; + target << "^Ndist ^B"; + + math::Vector3f v = entity->state()->location() - core::localcontrol()->state()->location(); + float d = v.length() - entity->radius() - core::localcontrol()->radius(); + if (d > 0 ) + target << std::fixed << std::setprecision(2) << std::setfill(' ') << std::setw(8) << d; + else + target << " --"; + + Text::draw(video::width - 4-Text::fontwidth()*24, video::height - Text::fontheight()*2 -4, target); + } } } @@ -299,6 +315,7 @@ void frame(float seconds) if (core::application()->connected() && core::game()->serverframetime()) { render::draw(seconds); // draw the world + targets::draw(); } // switch to ortographic projection to draw the GUI @@ -336,11 +353,6 @@ void frame(float seconds) draw_cursor(); } - // render sound and gui targets - if (core::application()->connected() && core::game()->serverframetime()) { - targets::draw(); - } - Text::setfont("bitmaps/fonts/console", 12, 18); chat::draw(); console()->draw(); -- cgit v1.2.3