/* core/gameinterface.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include #include #include #include "auxiliary/functions.h" #include "core/application.h" #include "core/cvar.h" #include "core/func.h" #include "core/gameinterface.h" #include "core/player.h" #include "core/zone.h" #include "model/model.h" #include "sys/sys.h" namespace core { void func_list_players(std::string const &args) { game()->list_players(); } const float MIN_DELTA = 10e-10; Player GameInterface::game_localplayer; EntityControlable *localcontrol() { if (game()->localplayer()) return game()->localplayer()->control(); else return 0; } Player *localplayer() { return game()->localplayer(); } GameInterface::GameInterface() { clear(); game_localplayer.clear(); if (Cvar::sv_dedicated->value()) { game_localplayer.player_name.assign("Console"); } else { game_localplayer.player_name.assign("Player"); game_localplayer.update_info(); } Func *func = Func::add("list_players", func_list_players); func->set_info("get the local list of connected players"); } GameInterface::~GameInterface() { Func::remove("list_players"); game_localplayer.clear(); clear(); } // clear all game related objects void GameInterface::clear() { //con_debug << "Clearing game data\n"; // remove all entities for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) { delete (*it).second; } Entity::registry().clear(); // remove all zones for (Zone::Registry::iterator it = Zone::registry().begin(); it != Zone::registry().end(); it++) { Zone *zone = (*it).second; delete zone; } Zone::registry().clear(); // remove all game functions for (Func::Registry::iterator it = Func::registry().begin(); it != Func::registry().end();) { if ( ((*it).second->flags() & Func::Game) == Func::Game) { delete (*it).second; Func::registry().erase(it++); } else { ++it; } } // remove all game cvars for (Cvar::Registry::iterator it = Cvar::registry().begin(); it != Cvar::registry().end(); ) { if ( ((*it).second->flags() & Cvar::Game) == Cvar::Game) { delete (*it).second; Cvar::registry().erase(it++); } else { ++it; } } // remove all models model::Model::clear(); // clear player list for (Players::iterator it = game_players.begin(); it != game_players.end(); it++) { Player *player = (*it); if (player != localplayer()) { delete player; } } game_players.clear(); } void GameInterface::reset_clientstate() { // game_previousframetime = prevtimestamp; // game_serverframetime = timestamp; // game_time = timestamp; for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) { Entity *entity = (*it).second; if (entity->state() && !(entity->flags() & Entity::Static)) entity->state()->assign(entity); } // if ( game_clientframetime < game_previousframetime) // game_clientframetime = game_previousframetime; // else if ( game_clientframetime > game_serverframetime) // game_clientframetime = game_serverframetime; } void GameInterface::update_entity_clientstate(Entity *entity) { if (!entity->state()) { entity->entity_clientstate = new ClientState(entity); entity->entity_clientstate->assign(entity); } else entity->state()->assign(entity); } /* if (!(entity->flags() & Entity::Static)) { // clientstate location entity->state()->state_location = entity->state()->previouslocation() + (entity->location() - entity->state()->previouslocation()) * timeoffset(); if (game_clientframetime <= game_serverframetime) { if(Cvar::cl_prediction->value() > 1) { entity->state()->state_axis.assign(entity->state()->previousaxis()); float cosangle; // cosine of an angle float angle; // angle in radians math::Vector3f n; // normal of a plane n.assign(math::crossproduct( entity->state()->axis().forward(), entity->axis().forward())); if (!(n.length() < MIN_DELTA)) { n.normalize(); cosangle = math::dotproduct( entity->state()->axis().forward(), entity->axis().forward()); angle = acos(cosangle) * timeoffset(); // * 180.0f / M_PI; if (angle > MIN_DELTA) entity->state()->state_axis.rotate(n, -angle); } n.assign(math::crossproduct( entity->state()->axis().left(), entity->axis().left())); if (!(n.length() < MIN_DELTA)) { n.normalize(); cosangle = math::dotproduct( entity->state()->axis().left(), entity->axis().left()); angle = acos(cosangle) * timeoffset(); // * 180.0f / M_PI; if (angle > MIN_DELTA) entity->state()->state_axis.rotate(n, -angle); } n.assign(math::crossproduct( entity->state()->axis().up(), entity->axis().up())); if (!(n.length() < MIN_DELTA)) { n.normalize(); cosangle = math::dotproduct( entity->state()->axis().up(), entity->axis().up()); angle = acos(cosangle) * timeoffset(); // * 180.0f / M_PI; if (angle > MIN_DELTA) entity->state()->state_axis.rotate(n, -angle); } } else { entity->state()->state_axis.assign(entity->axis()); } } else { entity->state()->state_axis.assign(entity->axis()); } } else { entity->state()->assign(entity); } } */ void GameInterface::update_clientstate() { for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) { update_entity_clientstate((*it).second); } } void GameInterface::list_players() { using namespace std; stringstream msgstr; int count = 0; for (Players::iterator it = game_players.begin(); it != game_players.end(); it++) { msgstr.str(""); con_print << setw(3) << (*it)->id() << aux::pad_left((*it)->name(), 24) << std::endl; count++; } con_print << count << " connected " << aux::plural("player", count) << std::endl; } }