diff options
m--------- | common | 0 | ||||
-rw-r--r-- | game.cpp | 19 | ||||
-rw-r--r-- | game.h | 1 | ||||
-rw-r--r-- | player.cpp | 92 | ||||
-rw-r--r-- | player.h | 38 | ||||
-rw-r--r-- | scene.cpp | 28 | ||||
-rw-r--r-- | scene.h | 7 | ||||
-rw-r--r-- | textures/placeholder.png | bin | 0 -> 35301 bytes |
8 files changed, 184 insertions, 1 deletions
diff --git a/common b/common -Subproject 042055b251bba4d8a59e16ca47721543cae346c +Subproject 1f97ccdac792c0b5b07972e7d4b2f28416046ea @@ -74,6 +74,9 @@ void Game::handle_type(const boost::system::error_code& error, std::size_t bytes case message::MSG_TYPE_MSG: handle_message(); break; + case message::MSG_TYPE_PLAYER: + handle_player(); + break; default: std::cout << "unknown type: " << (int)*type << std::endl; } @@ -116,6 +119,22 @@ void Game::handle_message() { scene->chat->add_line(s); } +void Game::handle_player() { + message::Player m; + + m.read(socket); + uint32_t id = m.get_id(); + Vector3 pos(m.get_pos()); + m.get_len(); + + // fetching string + m.read(socket); + + std::string name = m.get_str(); + + scene->players.push_back(Player::p(new Player(id, pos, name))); +} + Game& Game::get_instance() { if(!game) game = new Game(); @@ -26,6 +26,7 @@ class Game { void handle_type(const boost::system::error_code& error, std::size_t bytes_transferred, uint8_t *type); void handle_chunk(); void handle_message(); + void handle_player(); static Game& get_instance(); }; diff --git a/player.cpp b/player.cpp new file mode 100644 index 0000000..a65e8fa --- /dev/null +++ b/player.cpp @@ -0,0 +1,92 @@ +#include "player.h" + +#include <cmath> + +Player::Player(uint32_t id, Vector3& pos, std::string name) { + this->id = id; + this->pos = pos; + this->name = name; + + t = 0.0; +} + +uint32_t Player::get_id() { + return id; +} + +std::string Player::get_name() { + return name; +} + +Vector3 Player::get_pos() { + return pos; +} + +void Player::set_pos(Vector3& pos) { + this->pos = pos; +} + +// TODO: find a sane way to do this +void Player::render(FTFont *font, unsigned int steps, GLuint texture) { + glPushMatrix(); + glTranslatef(pos.x, pos.y, pos.z); + + // billboarding setup + float modelview[16]; + glGetFloatv(GL_MODELVIEW_MATRIX, modelview); + for(int i = 0; i < 3; i++) + for(int j = 0; j < 3; j++) + modelview[i*4+j] = i == j ? 1 : 0; + glLoadMatrixf(modelview); + + // text rendering + glPushMatrix(); + // probably not the best way to do calculate the text position, but it's accurate enough + FTBBox box = font->BBox(name.c_str()); + FTPoint l = box.Lower(); + FTPoint u = box.Upper(); + float len = (Vector3(l.Xf(), l.Yf(), l.Zf()) - Vector3(u.Xf(), u.Yf(), u.Zf())).length(); + // simplified from -len/72/2 + len/72/8 + glTranslatef(-len/192, 2.1, 0); + glScalef(.01, .01, .01); + + // make the text visible through terrain + glDisable(GL_DEPTH_TEST); + font->Render(name.c_str()); + glEnable(GL_DEPTH_TEST); + glPopMatrix(); + + // GL_COLOR_BUFFER_BIT saves blending function + glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT); + glBlendFunc(GL_ONE, GL_ONE); + glEnable(GL_BLEND); + t -= 0.0002 * steps; + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texture); + + // quad with scrolling texture + glBegin(GL_QUADS); + glTexCoord2f(fmodf(t, 1) + .16, 1); + glVertex3f(-1, 0, 0); + + glTexCoord2f(fmodf(t, 1), 1); + glVertex3f(1, 0, 0); + + glTexCoord2f(fmodf(t, 1), 0); + glVertex3f(1, 2, 0); + + glTexCoord2f(fmodf(t, 1) + .16, 0); + glVertex3f(-1, 2, 0); + glEnd(); + + glPopAttrib(); + + glBegin(GL_LINE_LOOP); + glVertex3f(-1, 0, .01); + glVertex3f(1, 0, .01); + glVertex3f(1, 2, .01); + glVertex3f(-1, 2, .01); + glEnd(); + + glPopMatrix(); // position translate +} diff --git a/player.h b/player.h new file mode 100644 index 0000000..c5f558d --- /dev/null +++ b/player.h @@ -0,0 +1,38 @@ +#ifndef PLAYER_H +#define PLAYER_H + +#include "gl.h" +#include "vector.h" + +#include <boost/shared_ptr.hpp> +#include <boost/cstdint.hpp> + +#include <FTGL/ftgl.h> + +#include <list> + +class Player { + private: + uint32_t id; + std::string name; + Vector3 pos; + + float t; + + public: + typedef boost::shared_ptr<Player> p; + + Player(uint32_t id, Vector3& pos, const std::string name); + + uint32_t get_id(); + std::string get_name(); + Vector3 get_pos(); + + void set_pos(Vector3& pos); + + void render(FTFont *font, unsigned int steps, GLuint texture); +}; + +typedef std::list<Player::p> PlayerList; + +#endif @@ -52,6 +52,7 @@ Scene::Scene() { soil_texture = load_texture("textures/zooboing-469-sand-modified.jpg"); water_texture = load_texture("textures/zooboing-688-water.jpg"); marker_texture = load_texture("textures/cross.png"); + placeholder_texture = load_texture("textures/placeholder.png"); /* init terrain */ terrain = new Terrain(); @@ -142,6 +143,12 @@ bool Scene::select(int x, int y, float& px, float& py, float& pz) { void Scene::update() { terrain->update(pos.x, pos.z); + + // sort players once a second + if(SDL_GetTicks() - last_sort > 1000) { + sort_players(); + last_sort = SDL_GetTicks(); + } } void Scene::events() { @@ -521,8 +528,21 @@ void Scene::render() { glEnd(); glPopMatrix(); + // player rendering + glPushMatrix(); + glTranslatef(-pos.x, -pos.y, -pos.z); + glColor3f(1, 1, 1); + + font->FaceSize(30); + for(PlayerList::iterator it = players.begin(); it != players.end(); it++) { + (*it)->render(font, steps, placeholder_texture); + } + + glPopMatrix(); + // HUD video::ortho(); + font->FaceSize(10); float height = font->LineHeight(); glColor3f(1, 1, 1); glTranslatef(0, video::height-height, 0); @@ -577,3 +597,11 @@ GLuint Scene::load_texture(const char *filename) { return texture; } + +static bool playerlist_sort(Vector3 pos, Player::p a, Player::p b) { + return (a->get_pos() - pos).length() > (b->get_pos() - pos).length(); +} + +void Scene::sort_players() { + players.sort(boost::bind(&playerlist_sort, pos, _1, _2)); +} @@ -8,6 +8,7 @@ #include "gui.h" #include "tool.h" #include "scripting.h" +#include "player.h" #include <FTGL/ftgl.h> @@ -23,6 +24,7 @@ class Scene { ConsoleWindow *console; ChatWindow *chat; Lua *lua; + PlayerList players; bool running; bool grid; @@ -36,6 +38,7 @@ class Scene { Terrain::Node *last_node; unsigned int last_time; + unsigned int last_sort; Vector3 selected; bool do_select, show_selection; @@ -44,7 +47,7 @@ class Scene { GLShaderProgram terrain_program; GLShaderProgram water_program; - GLuint grass_texture, rock_texture, soil_texture, water_texture, marker_texture; + GLuint grass_texture, rock_texture, soil_texture, water_texture, marker_texture, placeholder_texture; Scene(); ~Scene(); @@ -56,6 +59,8 @@ class Scene { void events(); void render(); GLuint load_texture(const char *filename); + + void sort_players(); }; #endif diff --git a/textures/placeholder.png b/textures/placeholder.png Binary files differnew file mode 100644 index 0000000..b443a5e --- /dev/null +++ b/textures/placeholder.png |