From fd778219e40c5fbb4d0af1839cbc313caaf10d9d Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 28 Sep 2008 15:05:13 +0000 Subject: move base game module to new subdirectory --- src/core/application.cc | 2 + src/core/gameserver.cc | 5 +- src/core/module.cc | 70 ++++- src/core/module.h | 29 +- src/game/Makefile.am | 10 +- src/game/base/Makefile.am | 8 + src/game/base/base.cc | 661 +++++++++++++++++++++++++++++++++++++++++++++ src/game/base/base.h | 77 ++++++ src/game/base/game.cc | 661 +++++++++++++++++++++++++++++++++++++++++++++ src/game/base/jumppoint.cc | 29 ++ src/game/base/jumppoint.h | 40 +++ src/game/base/navpoint.cc | 27 ++ src/game/base/navpoint.h | 27 ++ src/game/base/planet.cc | 27 ++ src/game/base/planet.h | 27 ++ src/game/base/racetrack.cc | 195 +++++++++++++ src/game/base/racetrack.h | 63 +++++ src/game/base/ship.cc | 464 +++++++++++++++++++++++++++++++ src/game/base/ship.h | 60 ++++ src/game/base/shipmodel.cc | 72 +++++ src/game/base/shipmodel.h | 70 +++++ src/game/base/star.cc | 25 ++ src/game/base/star.h | 29 ++ src/game/game.cc | 653 +------------------------------------------- src/game/game.h | 68 +---- src/game/intro/Makefile.am | 2 + src/game/jumppoint.cc | 29 -- src/game/jumppoint.h | 40 --- src/game/navpoint.cc | 27 -- src/game/navpoint.h | 27 -- src/game/planet.cc | 27 -- src/game/planet.h | 27 -- src/game/racetrack.cc | 195 ------------- src/game/racetrack.h | 63 ----- src/game/ship.cc | 464 ------------------------------- src/game/ship.h | 60 ---- src/game/shipmodel.cc | 72 ----- src/game/shipmodel.h | 70 ----- src/game/star.cc | 25 -- src/game/star.h | 29 -- src/osirion.cc | 7 +- src/osiriond.cc | 5 +- 42 files changed, 2665 insertions(+), 1903 deletions(-) create mode 100644 src/game/base/Makefile.am create mode 100644 src/game/base/base.cc create mode 100644 src/game/base/base.h create mode 100644 src/game/base/game.cc create mode 100644 src/game/base/jumppoint.cc create mode 100644 src/game/base/jumppoint.h create mode 100644 src/game/base/navpoint.cc create mode 100644 src/game/base/navpoint.h create mode 100644 src/game/base/planet.cc create mode 100644 src/game/base/planet.h create mode 100644 src/game/base/racetrack.cc create mode 100644 src/game/base/racetrack.h create mode 100644 src/game/base/ship.cc create mode 100644 src/game/base/ship.h create mode 100644 src/game/base/shipmodel.cc create mode 100644 src/game/base/shipmodel.h create mode 100644 src/game/base/star.cc create mode 100644 src/game/base/star.h create mode 100644 src/game/intro/Makefile.am delete mode 100644 src/game/jumppoint.cc delete mode 100644 src/game/jumppoint.h delete mode 100644 src/game/navpoint.cc delete mode 100644 src/game/navpoint.h delete mode 100644 src/game/planet.cc delete mode 100644 src/game/planet.h delete mode 100644 src/game/racetrack.cc delete mode 100644 src/game/racetrack.h delete mode 100644 src/game/ship.cc delete mode 100644 src/game/ship.h delete mode 100644 src/game/shipmodel.cc delete mode 100644 src/game/shipmodel.h delete mode 100644 src/game/star.cc delete mode 100644 src/game/star.h (limited to 'src') diff --git a/src/core/application.cc b/src/core/application.cc index 6207a0d..f8b9a73 100644 --- a/src/core/application.cc +++ b/src/core/application.cc @@ -251,6 +251,8 @@ void Application::shutdown() save_config(); + Module::clear(); + // remove our engine functions Func::remove("say"); Func::remove("help"); diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index f251b75..e086096 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -114,7 +114,7 @@ GameServer::GameServer() : GameInterface() server_frametime = 0.0f; server_maxplayerid = 1; - server_module = Module::preload(); + server_module = Module::current(); if (!server_module) { con_error << "No module loaded.\n"; abort(); @@ -199,9 +199,6 @@ GameServer::~GameServer() player_disconnect(localplayer()); server_module->shutdown(); - - if (server_module != Module::preload()) - delete server_module; } Func::remove("kick"); diff --git a/src/core/module.cc b/src/core/module.cc index 447e2b3..89bc2fe 100644 --- a/src/core/module.cc +++ b/src/core/module.cc @@ -5,36 +5,82 @@ */ #include "core/module.h" +#include "sys/sys.h" namespace core { +/*-- static functions ----------------------------------------------*/ + Module *Module::module_preload = 0; +Module::Registry Module::module_registry; -Module::Module(const char *name) : - module_name(name) +Module *Module::find(std::string const &name) { - module_running = false; + Registry::iterator it = module_registry.find(name); + if (it == module_registry.end()) + return 0; + else + return (*it).second; } -Module::~Module() +Module *Module::find(const char *name) { - module_running = false; - module_name.clear(); + return(find(std::string(name))); } - -void Module::load(Module *module) +Module *Module::add(const char *name, Module *module) { + Module *m = find(name); + if (m) { + con_warn << "module '" << name << "' already loaded!" << std::endl; + delete module; + return 0; + } + module_registry[std::string(name)] = module; + if (!module_preload) { + module_preload = module; + con_debug << " " << name << " " << module->name() << std::endl; + } + return module; +} + +Module *Module::load(const char *name) +{ + Module *module = find(name); + if (!module) { + con_warn << "could not find module '" << name << "'" << std::endl; + return 0; + } + + con_debug << " " << name << " " << module->name() << std::endl; module_preload = module; + return module; } -void Module::unload() +void Module::clear() { - if (module_preload) { - delete module_preload; - module_preload = 0; + for (Registry::iterator it = module_registry.begin(); it != module_registry.end(); it++) { + Module *module = (*it).second; + delete module; } + + module_registry.clear(); + module_preload = 0; +} + +/*-- instance functions --------------------------------------------*/ + +Module::Module(const char *name) : + module_name(name) +{ + module_running = false; +} + +Module::~Module() +{ + module_running = false; + module_name.clear(); } void Module::abort() diff --git a/src/core/module.h b/src/core/module.h index 61dc0dc..bd99034 100644 --- a/src/core/module.h +++ b/src/core/module.h @@ -49,23 +49,38 @@ public: /*----- static ---------------------------------------------------- */ - /// load a game module - static void load(Module *module); + typedef std::map Registry; - /// unload the preloaded module - static void unload(); + /// find a registered game module + static Module *find(const char *name); + + /// find a registered game module + static Module *find(std::string const &name); - /// the preloaded module - inline static Module *preload() { return module_preload; }; + /// register a game module + static Module *add(const char *name, Module *module); + + /// load a registered game module + static Module *load(const char *name); + + /// unload all modules + static void clear(); + + /// currently loaded module + static inline Module *current() { return module_preload; } protected: /// set the disconnected state void abort(); + bool module_running; private: - static Module *module_preload; std::string module_name; + + static Module *module_preload; + + static Registry module_registry; }; } diff --git a/src/game/Makefile.am b/src/game/Makefile.am index ff591eb..91838e6 100644 --- a/src/game/Makefile.am +++ b/src/game/Makefile.am @@ -1,10 +1,10 @@ -INCLUDES = -I$(top_srcdir)/src +INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/game METASOURCES = AUTO libgame_la_LDFLAGS = -avoid-version -libgame_la_SOURCES = game.cc jumppoint.cc navpoint.cc planet.cc racetrack.cc \ - ship.cc shipmodel.cc star.cc +libgame_la_SOURCES = game.cc noinst_LTLIBRARIES = libgame.la -noinst_HEADERS = game.h navpoint.h planet.h racetrack.h ship.h shipmodel.h \ - star.h jumppoint.h +noinst_HEADERS = game.h +SUBDIRS = base intro +libgame_la_LIBADD = $(top_builddir)/src/game/base/libbase.la diff --git a/src/game/base/Makefile.am b/src/game/base/Makefile.am new file mode 100644 index 0000000..a8258b2 --- /dev/null +++ b/src/game/base/Makefile.am @@ -0,0 +1,8 @@ +INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/game +METASOURCES = AUTO +libbase_la_LDFLAGS = -avoid-version +noinst_LTLIBRARIES = libbase.la +libbase_la_SOURCES = base.cc jumppoint.cc navpoint.cc planet.cc racetrack.cc \ + ship.cc shipmodel.cc star.cc +noinst_HEADERS = base.h jumppoint.h navpoint.h planet.h racetrack.h ship.h \ + shipmodel.h star.h diff --git a/src/game/base/base.cc b/src/game/base/base.cc new file mode 100644 index 0000000..70d9335 --- /dev/null +++ b/src/game/base/base.cc @@ -0,0 +1,661 @@ +/* + base/base.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 "auxiliary/functions.h" +#include "core/gameserver.h" +#include "filesystem/filesystem.h" +#include "filesystem/inifile.h" +#include "base/base.h" +#include "base/navpoint.h" +#include "base/jumppoint.h" +#include "base/planet.h" +#include "base/racetrack.h" +#include "base/ship.h" +#include "base/star.h" +#include "math/mathlib.h" +#include "sys/sys.h" + +namespace base +{ + +ShipModel *default_shipmodel = 0; +core::Zone *default_zone = 0; + +/*----- engine game functions ------------------------------------- */ + +/// list the ship model registry +void func_list_ship(std::string const &args) +{ + ShipModel::list(); +} + +/// a player joins the game +void func_join(core::Player *player, std::string const &args) +{ + if (player->control()) + return; + + player->set_zone(default_zone); + Ship *ship = new Ship(player, default_shipmodel); + ship->set_zone(default_zone); + player->set_control(ship); + + core::server()->send_sound(player, "game/buy-ship"); + + std::string message("^B"); + message.append(player->name()); + message.append("^B joins the game."); + core::server()->broadcast(message); + + player->player_dirty = true; +} + +/// a player joins the spectators +void func_spectate(core::Player *player, std::string const &args) +{ + if (!player->control()) + return; + + std::string message("^B"); + message.append(player->name()); + message.append("^B spectates."); + core::server()->broadcast(message); + + if (player->control()) { + player->remove_asset(player->control()); + } +} + +/// a player buys a ship +void func_buy(core::Player *player, std::string const &args) +{ + + std::string shipname; + std::string helpstr; + std::istringstream is(args); + is >> shipname; + aux::to_lowercase(shipname); + + ShipModel *shipmodel = 0; + for (ShipModel::iterator smit = ShipModel::registry.begin(); smit != ShipModel::registry.end(); smit++) { + if (shipname == (*smit).first) { + shipmodel = (*smit).second; + break; + } + + if (helpstr.size()) + helpstr.append("^N|^B"); + helpstr.append((*smit).second->label()); + } + + if (shipmodel) { + // player has only ship for now + if (player->control()) { + player->remove_asset(player->control()); + } + + Ship * ship = new Ship(player, shipmodel); + if (player->zone()) { + ship->set_zone(player->zone()); + } else { + ship->set_zone(default_zone); + } + player->set_control(ship); + + core::server()->broadcast("^B" + player->name() + " ^Bpurchased " + aux::article(shipmodel->name())); + core::server()->send_sound(player, "game/buy-ship"); + + } else { + core::server()->send(player, "Usage: buy [^B" + helpstr + "^N]"); + } +} + +/// a player sends standard hails +void func_hail(core::Player *player, std::string const &args) +{ + std::string target; + std::istringstream is(args); + if (!(is >> target)) { + core::server()->send(player, "Usage: hail [player]"); + return; + } + + core::Player *targetplayer = core::server()->find_player(target); + if (!targetplayer) { + core::server()->send(player, "^BPlayer " + target + "^B not found."); + return; + } + + core::server()->send(player, "^BYou hail " + targetplayer->name() + "^B."); + core::server()->send_sound(player, "com/hail"); + + core::server()->send(targetplayer, "^B" + player->name() + "^B hails you!"); + core::server()->send_sound(targetplayer, "com/hail"); +} + +/// a player actives the hyperspace jump drive on his ship +void func_jump(core::Player *player, std::string const &args) +{ + if (!player->control()) + return; + if (!player->control()->moduletype() == ship_enttype) + return; + Ship * ship = static_cast(player->control()); + ship->jump(args); +} + +/// a player actives the kinetic impulse drive on his ship +void func_impulse(core::Player *player, std::string const &args) +{ + if (!player->control()) + return; + if (!player->control()->moduletype() == ship_enttype) + return; + Ship * ship = static_cast(player->control()); + ship->impulse(); +} + +/* ---- The Game class --------------------------------------------- */ + +Base *Base::game_instance = 0; + +Base::Base() : core::Module("Project::OSiRiON") +{ + game_instance = this; + g_impulsespeed = 0; +} + +Base::~Base() +{ + game_instance = 0; +} + +void Base::init() +{ + module_running = false; + + ShipModel::clear(); + + if (!load_world()) { + abort(); + return; + } + + if (!load_ships()) { + abort(); + return; + } + + // add engine game functions + core::Func *func = 0; + + func = core::Func::add("join", (core::GameFuncPtr) func_join); + func->set_info("join the game"); + func = core::Func::add("hail", (core::GameFuncPtr) func_hail); + func->set_info("send a standard hail"); + func = core::Func::add("spectate", (core::GameFuncPtr) func_spectate); + func->set_info("leave the game and spectate"); + + func = core::Func::add("buy", (core::GameFuncPtr) func_buy); + func->set_info("buy a ship"); + + func = core::Func::add("jump", (core::GameFuncPtr) func_jump); + func->set_info("[string] activate or deactivate hyperspace jump drive"); + + func = core::Func::add("impulse", (core::GameFuncPtr) func_impulse); + func->set_info("activate are deactive kinetic impulse drive"); + + // add engine core functions + func = core::Func::add("list_ship", (core::FuncPtr) func_list_ship); + func->set_info("list ship statistics"); + + g_impulsespeed = core::Cvar::get("g_impulsespeed", "15", core::Cvar::Game | core::Cvar::Archive); + g_impulsespeed->set_info("[float] speed of the impulse drive"); + + g_impulseacceleration = core::Cvar::get("g_impulseacceleration", "5", core::Cvar::Game | core::Cvar::Archive); + g_impulseacceleration->set_info("[float] acceleration of the impulse drive"); + + g_strafespeed = core::Cvar::get("g_strafespeed", "0.003", core::Cvar::Game | core::Cvar::Archive); + g_strafespeed->set_info("[float] strafe speed"); + + g_jumppointrange = core::Cvar::get("g_jumppointrange", "512", core::Cvar::Game | core::Cvar::Archive); + g_jumppointrange->set_info("[float] jumppoint range"); + + g_devel = core::Cvar::get("g_devel", "0", core::Cvar::Archive); + g_devel->set_info("[bool] enable or disable developer mode"); + + // indicate the module is ready to run frames + module_running = true; +} + +void Base::shutdown() +{ + g_impulsespeed = 0; + // game functions are automaticly removed + + // remove engine core functions + core::Func::remove("list_ship"); + + ShipModel::clear(); + module_running = false; +} + +bool Base::load_world() +{ + std::string inifilename("world"); + + filesystem::IniFile worldini; + worldini.open(inifilename); + + if (!worldini.is_open()) { + con_error << "Could not open " << worldini.name() << std::endl; + return false; + } + + core::Zone *zone = 0; + std::string label; + + while (worldini.getline()) { + + if (worldini.got_section()) { + + if (worldini.got_section("world")) { + continue; + } else { + con_warn << worldini.name() << " unknown section '" << worldini.section() << "' at line " << worldini.line() << std::endl; + } + + } else if (worldini.section().compare("world") == 0 ) { + if (worldini.got_key_string("zone", label)) { + aux::to_label(label); + zone = new core::Zone(label); + core::Zone::add(zone); + } + } + } + worldini.close(); + + if (!core::Zone::registry().size()) { + con_error << "No zones found!" << std::endl; + return false; + } + + con_debug << " " << worldini.name() << " " << core::Zone::registry().size() << " zones" << std::endl; + + for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { + if (!load_zone((*it).second)) { + return false; + } + } + + for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { + if (!validate_zone((*it).second)) { + return false; + } + } + + if (!default_zone) { + con_error << "No default zone found!" << std::endl; + return false; + } + + return true; +} + +bool Base::got_entity_key(filesystem::IniFile &inifile, core::Entity *entity) +{ + std::string shapename; + std::string strval; + float direction; + float pitch; + float roll; + + if (inifile.got_key_string("shape", shapename)) { + + if (shapename.compare("axis") == 0) { + entity->entity_shape = core::Entity::Axis; + return true; + } else if (shapename.compare("cube") == 0) { + entity->entity_shape = core::Entity::Cube; + return true; + } else if (shapename.compare("diamond") == 0) { + entity->entity_shape = core::Entity::Diamond; + return true; + } else if (shapename.compare("sphere") == 0) { + entity->entity_shape = core::Entity::Sphere; + return true; + } else { + con_warn << inifile.name() << " unknown shape '" << shapename << "' at line " << inifile.line() << std::endl; + return false; + } + + } else if (inifile.got_key_string("label", strval)) { + aux::to_label(strval); + entity->entity_label.assign(strval); + return true; + } else if (inifile.got_key_string("name", strval)) { + aux::strip_quotes(strval); + entity->entity_name.assign(strval); + return true; + } else if (inifile.got_key_string("model", entity->entity_modelname)) { + return true; + } else if (inifile.got_key_angle("direction", direction)) { + entity->axis().change_direction(direction); + return true; + } else if (inifile.got_key_angle("pitch", pitch)) { + entity->axis().change_pitch(pitch); + return true; + } else if (inifile.got_key_angle("roll", roll)) { + entity->axis().change_roll(roll); + return true; + } else if (inifile.got_key_angle("radius", entity->entity_radius)) { + return true; + } else if (inifile.got_key_vector3f("location", entity->entity_location)) { + return true; + } else if (inifile.got_key_color("color", entity->entity_color)) { + return true; + } else if (inifile.got_key_color("colorsecond", entity->entity_color_second)) { + return true; + } + + return false; +} + +bool Base::load_zone(core::Zone *zone) +{ + using math::Vector3f; + using math::Color; + + std::string inifilename("zones/"); + inifilename.append(zone->label()); + + filesystem::IniFile zoneini; + zoneini.open(inifilename); + + if (!zoneini.is_open()) { + con_error << "Could not open " << zoneini.name() << std::endl; + return false; + } + + size_t count = 0; + + Planet *planet = 0; + Star *star = 0; + NavPoint *navpoint = 0; + JumpPoint *jumppoint = 0; + RaceTrack *racetrack = 0; + CheckPoint *checkpoint = 0; + core::Entity *entity = 0; + + bool b; + + std::string strval; + + // set th default sky + zone->set_sky("sky"); + + while (zoneini.getline()) { + if (zoneini.got_key()) { + if (zoneini.section().compare("zone") == 0) { + if (zoneini.got_key_string("name", strval)) { + aux::strip_quotes(strval); + zone->set_name(strval); + continue; + } else if (zoneini.got_key_string("sky", strval)) { + zone->set_sky(strval); + continue; + } else if (zoneini.got_key_bool("default", b)) { + if (b) default_zone = zone; + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + } else if (zoneini.section().compare("star") == 0) { + if (got_entity_key(zoneini, star)) { + continue; + } else if (zoneini.got_key_string("texture", star->entity_texture)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + } else if (zoneini.section().compare("navpoint") == 0) { + if (got_entity_key(zoneini, navpoint)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + } else if (zoneini.section().compare("jumppoint") == 0) { + if (got_entity_key(zoneini, jumppoint)) { + continue; + } else if (zoneini.got_key_string("target", jumppoint->jumppoint_targetlabel)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + } else if (zoneini.section().compare("planet") == 0) { + if (got_entity_key(zoneini, planet)) { + continue; + } else if (zoneini.got_key_string("texture", planet->entity_texture)) { + continue; + } else if (zoneini.got_key_float("rotationspeed", planet->entity_rotationspeed)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + + } else if (zoneini.section().compare("racetrack") == 0) { + if (got_entity_key(zoneini, racetrack)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + + } else if (zoneini.section().compare("checkpoint") == 0) { + if (got_entity_key(zoneini, checkpoint)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + + } else if (zoneini.section().compare("entity") == 0) { + if (got_entity_key(zoneini, entity)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + } + } else if (zoneini.got_section("zone")) { + continue; + + } else if (zoneini.got_section("star")) { + star = new Star(); + star->set_zone(zone); + count ++; + + } else if (zoneini.got_section("navpoint")) { + navpoint = new NavPoint(); + navpoint->set_zone(zone); + count ++; + + } else if (zoneini.got_section("jumppoint")) { + jumppoint = new JumpPoint(); + jumppoint->set_zone(zone); + count ++; + + } else if(zoneini.got_section("racetrack")) { + racetrack = new RaceTrack(); + racetrack->set_zone(zone); + + } else if(zoneini.got_section("checkpoint")) { + checkpoint = new CheckPoint(racetrack); + if (!racetrack) { + con_warn << zoneini.name() << " checkpoint without racetrack at line " << zoneini.line() << std::endl; + } + + } else if (zoneini.got_section("planet")) { + planet = new Planet(); + planet->set_zone(zone); + count ++; + + } else if (zoneini.got_section("entity")) { + entity = new core::Entity(); + entity->entity_flags += core::Entity::Static; + entity->set_zone(zone); + count ++; + + } else if (zoneini.got_section()) { + con_warn << zoneini.name() << " unknown section '" << zoneini.section() << "' at line " << zoneini.line() << std::endl; + } + } + zoneini.close(); + + con_debug << " " << zoneini.name() << " " << zone->content().size() << " entities" << std::endl; + + + return true; +} + +bool Base::validate_zone(core::Zone *zone) +{ + con_debug << " validating " << zone->name() << std::endl; + + for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { + core::Entity *entity = (*it); + + if (entity->entity_moduletypeid == jumppoint_enttype) { + JumpPoint *jumppoint = static_cast(entity); + + if (jumppoint->targetlabel().size() < 3) { + con_warn << " Jumppoint with invalid target label '" << jumppoint->targetlabel() << "'\n"; + continue; + } + size_t pos = jumppoint->targetlabel().find(':'); + if ((pos < 1 ) || (pos >= (jumppoint->targetlabel().size()-1))) { + con_warn << " Jumppoint with invalid target label '" << jumppoint->targetlabel() << "'\n"; + continue; + } + + std::string zonelabel(jumppoint->targetlabel().substr(0, pos)); + std::string entitylabel(jumppoint->targetlabel().substr(pos+1, jumppoint->targetlabel().size()-pos)); + + core::Zone *targetzone = core::Zone::find(zonelabel); + if (!targetzone) { + con_warn << " Jumppoint with invalid target zone '" << zonelabel << "'\n"; + continue; + } + + core::Entity *targetentity = targetzone->find_entity(entitylabel); + if (!targetentity) { + con_warn << " Could not find target jumppoint '" << entitylabel << "'\n"; + continue; + } + + if (targetentity->moduletype() != jumppoint_enttype) { + con_warn << " Jumppoint with invalid target jumppoint '" << entitylabel << "'\n"; + continue; + } + + jumppoint->jumppoint_target = static_cast(targetentity); + + //con_debug << " Jumppoint " << zone->label() << ":" << jumppoint->label() << " with target " << jumppoint->targetlabel() << std::endl; + } + } + + return true; +} + +// read ship model specifications +bool Base::load_ships() +{ + using math::Vector3f; + using math::Color; + + default_shipmodel = 0; + + filesystem::IniFile shipsini; + shipsini.open("ships"); + if (!shipsini.is_open()) { + con_error << "Could not open ini/ships.ini!" << std::endl; + return false; + } + + ShipModel *shipmodel = 0; + std::string label; + bool b; + + while (shipsini.getline()) { + if (shipsini.got_key()) { + if (shipsini.section().compare("ship") == 0) { + if (shipsini.got_key_string("label", label)) { + aux::to_label(label); + shipmodel->shipmodel_label.assign(label); + ShipModel::add(shipmodel); + continue; + } else if (shipsini.got_key_string("name",shipmodel->shipmodel_name)) { + continue; + } else if (shipsini.got_key_string("model", shipmodel->shipmodel_modelname)) { + continue; + } else if (shipsini.got_key_bool("default", b)) { + if (b) default_shipmodel = shipmodel; + continue; + } else if (shipsini.got_key_bool("jumpdrive", shipmodel->shipmodel_jumpdrive)) { + continue; + } else if (shipsini.got_key_float("acceleration", shipmodel->shipmodel_acceleration)) { + continue; + } else if (shipsini.got_key_float("maxspeed", shipmodel->shipmodel_maxspeed)) { + continue; + } else if (shipsini.got_key_float("turnspeed", shipmodel->shipmodel_turnspeed)) { + math::clamp(shipmodel->shipmodel_turnspeed, 0.0f, 90.0f); + continue; + } else { + con_warn << shipsini.name() << " unknown key '" << shipsini.key() << "' at line " << shipsini.line() << std::endl; + } + } + } else if (shipsini.got_section("ship")) { + shipmodel = new ShipModel(); + + if (!default_shipmodel) + default_shipmodel = shipmodel; + + } else if (shipsini.got_section()) { + con_warn << shipsini.name() << " unknown section '" << shipsini.section() << "' at line " << shipsini.line() << std::endl; + } + } + shipsini.close(); + + con_debug << " " << shipsini.name() << " " << ShipModel::registry.size() << " ship models" << std::endl; + + if (!default_shipmodel) { + con_error << "No default ship model found!\n"; + return false; + } + + return true; +} + +void Base::frame(float seconds) +{ + if (!running()) + return; +} + +void Base::player_connect(core::Player *player) +{ + std::string args; + player->set_zone(default_zone); + func_spectate(player, args); +} + +void Base::player_disconnect(core::Player *player) +{ + player->remove_asset(player->control()); +} + +} // namespace game + diff --git a/src/game/base/base.h b/src/game/base/base.h new file mode 100644 index 0000000..fea1919 --- /dev/null +++ b/src/game/base/base.h @@ -0,0 +1,77 @@ +/* + game/game.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_BASE_H__ +#define __INCLUDED_BASE_H__ + +#include +#include + +#include "base/ship.h" +#include "base/star.h" +#include "core/core.h" +#include "filesystem/inifile.h" +#include "sys/sys.h" + +/// the base game module +/** the base game module containis the game-specific code for Project::Osirion + */ +namespace base +{ + +// entity type constants +const unsigned int ship_enttype = 256; +const unsigned int star_enttype = 257; +const unsigned int planet_enttype = 258; +const unsigned int navpoint_enttype = 259; +const unsigned int jumppoint_enttype = 260; + +class Base : public core::Module { +public: + Base(); + ~Base(); + + /// initialize the game + void init(); + + /// shutdown the game + void shutdown(); + + /// run one time frame + void frame(float seconds); + + /// is called when a player connects + void player_connect(core::Player *player); + + /// is called when a player disconnects + void player_disconnect(core::Player *player); + + static inline Base *instance() { return game_instance; } + + core::Cvar *g_impulsespeed; + core::Cvar *g_impulseacceleration; + core::Cvar *g_strafespeed; + core::Cvar *g_jumppointrange; + core::Cvar *g_devel; + +private: + bool got_entity_key(filesystem::IniFile &inifile, core::Entity *entity); + + bool load_world(); + + bool load_zone(core::Zone *zone); + + bool validate_zone(core::Zone *zone); + + bool load_ships(); + + static Base *game_instance; +}; + +} + +#endif // __INCLUDED_BASE_H__ + diff --git a/src/game/base/game.cc b/src/game/base/game.cc new file mode 100644 index 0000000..4d66cbe --- /dev/null +++ b/src/game/base/game.cc @@ -0,0 +1,661 @@ +/* + game/game.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 "auxiliary/functions.h" +#include "core/gameserver.h" +#include "filesystem/filesystem.h" +#include "filesystem/inifile.h" +#include "game/game.h" +#include "game/navpoint.h" +#include "game/jumppoint.h" +#include "game/planet.h" +#include "game/racetrack.h" +#include "game/ship.h" +#include "game/star.h" +#include "math/mathlib.h" +#include "sys/sys.h" + +namespace game +{ + +ShipModel *default_shipmodel = 0; +core::Zone *default_zone = 0; + +/*----- engine game functions ------------------------------------- */ + +/// list the ship model registry +void func_list_ship(std::string const &args) +{ + ShipModel::list(); +} + +/// a player joins the game +void func_join(core::Player *player, std::string const &args) +{ + if (player->control()) + return; + + player->set_zone(default_zone); + Ship *ship = new Ship(player, default_shipmodel); + ship->set_zone(default_zone); + player->set_control(ship); + + core::server()->send_sound(player, "game/buy-ship"); + + std::string message("^B"); + message.append(player->name()); + message.append("^B joins the game."); + core::server()->broadcast(message); + + player->player_dirty = true; +} + +/// a player joins the spectators +void func_spectate(core::Player *player, std::string const &args) +{ + if (!player->control()) + return; + + std::string message("^B"); + message.append(player->name()); + message.append("^B spectates."); + core::server()->broadcast(message); + + if (player->control()) { + player->remove_asset(player->control()); + } +} + +/// a player buys a ship +void func_buy(core::Player *player, std::string const &args) +{ + + std::string shipname; + std::string helpstr; + std::istringstream is(args); + is >> shipname; + aux::to_lowercase(shipname); + + ShipModel *shipmodel = 0; + for (ShipModel::iterator smit = ShipModel::registry.begin(); smit != ShipModel::registry.end(); smit++) { + if (shipname == (*smit).first) { + shipmodel = (*smit).second; + break; + } + + if (helpstr.size()) + helpstr.append("^N|^B"); + helpstr.append((*smit).second->label()); + } + + if (shipmodel) { + // player has only ship for now + if (player->control()) { + player->remove_asset(player->control()); + } + + Ship * ship = new Ship(player, shipmodel); + if (player->zone()) { + ship->set_zone(player->zone()); + } else { + ship->set_zone(default_zone); + } + player->set_control(ship); + + core::server()->broadcast("^B" + player->name() + " ^Bpurchased " + aux::article(shipmodel->name())); + core::server()->send_sound(player, "game/buy-ship"); + + } else { + core::server()->send(player, "Usage: buy [^B" + helpstr + "^N]"); + } +} + +/// a player sends standard hails +void func_hail(core::Player *player, std::string const &args) +{ + std::string target; + std::istringstream is(args); + if (!(is >> target)) { + core::server()->send(player, "Usage: hail [player]"); + return; + } + + core::Player *targetplayer = core::server()->find_player(target); + if (!targetplayer) { + core::server()->send(player, "^BPlayer " + target + "^B not found."); + return; + } + + core::server()->send(player, "^BYou hail " + targetplayer->name() + "^B."); + core::server()->send_sound(player, "com/hail"); + + core::server()->send(targetplayer, "^B" + player->name() + "^B hails you!"); + core::server()->send_sound(targetplayer, "com/hail"); +} + +/// a player actives the hyperspace jump drive on his ship +void func_jump(core::Player *player, std::string const &args) +{ + if (!player->control()) + return; + if (!player->control()->moduletype() == ship_enttype) + return; + Ship * ship = static_cast(player->control()); + ship->jump(args); +} + +/// a player actives the kinetic impulse drive on his ship +void func_impulse(core::Player *player, std::string const &args) +{ + if (!player->control()) + return; + if (!player->control()->moduletype() == ship_enttype) + return; + Ship * ship = static_cast(player->control()); + ship->impulse(); +} + +/* ---- The Game class --------------------------------------------- */ + +Game *Game::game_instance = 0; + +Game::Game() : core::Module("Project::OSiRiON") +{ + game_instance = this; + g_impulsespeed = 0; +} + +Game::~Game() +{ + game_instance = 0; +} + +void Game::init() +{ + module_running = false; + + ShipModel::clear(); + + if (!load_world()) { + abort(); + return; + } + + if (!load_ships()) { + abort(); + return; + } + + // add engine game functions + core::Func *func = 0; + + func = core::Func::add("join", (core::GameFuncPtr) func_join); + func->set_info("join the game"); + func = core::Func::add("hail", (core::GameFuncPtr) func_hail); + func->set_info("send a standard hail"); + func = core::Func::add("spectate", (core::GameFuncPtr) func_spectate); + func->set_info("leave the game and spectate"); + + func = core::Func::add("buy", (core::GameFuncPtr) func_buy); + func->set_info("buy a ship"); + + func = core::Func::add("jump", (core::GameFuncPtr) func_jump); + func->set_info("[string] activate or deactivate hyperspace jump drive"); + + func = core::Func::add("impulse", (core::GameFuncPtr) func_impulse); + func->set_info("activate are deactive kinetic impulse drive"); + + // add engine core functions + func = core::Func::add("list_ship", (core::FuncPtr) func_list_ship); + func->set_info("list ship statistics"); + + g_impulsespeed = core::Cvar::get("g_impulsespeed", "15", core::Cvar::Game | core::Cvar::Archive); + g_impulsespeed->set_info("[float] speed of the impulse drive"); + + g_impulseacceleration = core::Cvar::get("g_impulseacceleration", "5", core::Cvar::Game | core::Cvar::Archive); + g_impulseacceleration->set_info("[float] acceleration of the impulse drive"); + + g_strafespeed = core::Cvar::get("g_strafespeed", "0.003", core::Cvar::Game | core::Cvar::Archive); + g_strafespeed->set_info("[float] strafe speed"); + + g_jumppointrange = core::Cvar::get("g_jumppointrange", "512", core::Cvar::Game | core::Cvar::Archive); + g_jumppointrange->set_info("[float] jumppoint range"); + + g_devel = core::Cvar::get("g_devel", "0", core::Cvar::Archive); + g_devel->set_info("[bool] enable or disable developer mode"); + + // indicate the module is ready to run frames + module_running = true; +} + +void Game::shutdown() +{ + g_impulsespeed = 0; + // game functions are automaticly removed + + // remove engine core functions + core::Func::remove("list_ship"); + + ShipModel::clear(); + module_running = false; +} + +bool Game::load_world() +{ + std::string inifilename("world"); + + filesystem::IniFile worldini; + worldini.open(inifilename); + + if (!worldini.is_open()) { + con_error << "Could not open " << worldini.name() << std::endl; + return false; + } + + core::Zone *zone = 0; + std::string label; + + while (worldini.getline()) { + + if (worldini.got_section()) { + + if (worldini.got_section("world")) { + continue; + } else { + con_warn << worldini.name() << " unknown section '" << worldini.section() << "' at line " << worldini.line() << std::endl; + } + + } else if (worldini.section().compare("world") == 0 ) { + if (worldini.got_key_string("zone", label)) { + aux::to_label(label); + zone = new core::Zone(label); + core::Zone::add(zone); + } + } + } + worldini.close(); + + if (!core::Zone::registry().size()) { + con_error << "No zones found!" << std::endl; + return false; + } + + con_debug << " " << worldini.name() << " " << core::Zone::registry().size() << " zones" << std::endl; + + for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { + if (!load_zone((*it).second)) { + return false; + } + } + + for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { + if (!validate_zone((*it).second)) { + return false; + } + } + + if (!default_zone) { + con_error << "No default zone found!" << std::endl; + return false; + } + + return true; +} + +bool Game::got_entity_key(filesystem::IniFile &inifile, core::Entity *entity) +{ + std::string shapename; + std::string strval; + float direction; + float pitch; + float roll; + + if (inifile.got_key_string("shape", shapename)) { + + if (shapename.compare("axis") == 0) { + entity->entity_shape = core::Entity::Axis; + return true; + } else if (shapename.compare("cube") == 0) { + entity->entity_shape = core::Entity::Cube; + return true; + } else if (shapename.compare("diamond") == 0) { + entity->entity_shape = core::Entity::Diamond; + return true; + } else if (shapename.compare("sphere") == 0) { + entity->entity_shape = core::Entity::Sphere; + return true; + } else { + con_warn << inifile.name() << " unknown shape '" << shapename << "' at line " << inifile.line() << std::endl; + return false; + } + + } else if (inifile.got_key_string("label", strval)) { + aux::to_label(strval); + entity->entity_label.assign(strval); + return true; + } else if (inifile.got_key_string("name", strval)) { + aux::strip_quotes(strval); + entity->entity_name.assign(strval); + return true; + } else if (inifile.got_key_string("model", entity->entity_modelname)) { + return true; + } else if (inifile.got_key_angle("direction", direction)) { + entity->axis().change_direction(direction); + return true; + } else if (inifile.got_key_angle("pitch", pitch)) { + entity->axis().change_pitch(pitch); + return true; + } else if (inifile.got_key_angle("roll", roll)) { + entity->axis().change_roll(roll); + return true; + } else if (inifile.got_key_angle("radius", entity->entity_radius)) { + return true; + } else if (inifile.got_key_vector3f("location", entity->entity_location)) { + return true; + } else if (inifile.got_key_color("color", entity->entity_color)) { + return true; + } else if (inifile.got_key_color("colorsecond", entity->entity_color_second)) { + return true; + } + + return false; +} + +bool Game::load_zone(core::Zone *zone) +{ + using math::Vector3f; + using math::Color; + + std::string inifilename("zones/"); + inifilename.append(zone->label()); + + filesystem::IniFile zoneini; + zoneini.open(inifilename); + + if (!zoneini.is_open()) { + con_error << "Could not open " << zoneini.name() << std::endl; + return false; + } + + size_t count = 0; + + Planet *planet = 0; + Star *star = 0; + NavPoint *navpoint = 0; + JumpPoint *jumppoint = 0; + RaceTrack *racetrack = 0; + CheckPoint *checkpoint = 0; + core::Entity *entity = 0; + + bool b; + + std::string strval; + + // set th default sky + zone->set_sky("sky"); + + while (zoneini.getline()) { + if (zoneini.got_key()) { + if (zoneini.section().compare("zone") == 0) { + if (zoneini.got_key_string("name", strval)) { + aux::strip_quotes(strval); + zone->set_name(strval); + continue; + } else if (zoneini.got_key_string("sky", strval)) { + zone->set_sky(strval); + continue; + } else if (zoneini.got_key_bool("default", b)) { + if (b) default_zone = zone; + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + } else if (zoneini.section().compare("star") == 0) { + if (got_entity_key(zoneini, star)) { + continue; + } else if (zoneini.got_key_string("texture", star->entity_texture)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + } else if (zoneini.section().compare("navpoint") == 0) { + if (got_entity_key(zoneini, navpoint)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + } else if (zoneini.section().compare("jumppoint") == 0) { + if (got_entity_key(zoneini, jumppoint)) { + continue; + } else if (zoneini.got_key_string("target", jumppoint->jumppoint_targetlabel)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + } else if (zoneini.section().compare("planet") == 0) { + if (got_entity_key(zoneini, planet)) { + continue; + } else if (zoneini.got_key_string("texture", planet->entity_texture)) { + continue; + } else if (zoneini.got_key_float("rotationspeed", planet->entity_rotationspeed)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + + } else if (zoneini.section().compare("racetrack") == 0) { + if (got_entity_key(zoneini, racetrack)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + + } else if (zoneini.section().compare("checkpoint") == 0) { + if (got_entity_key(zoneini, checkpoint)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + + } else if (zoneini.section().compare("entity") == 0) { + if (got_entity_key(zoneini, entity)) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + } + } else if (zoneini.got_section("zone")) { + continue; + + } else if (zoneini.got_section("star")) { + star = new Star(); + star->set_zone(zone); + count ++; + + } else if (zoneini.got_section("navpoint")) { + navpoint = new NavPoint(); + navpoint->set_zone(zone); + count ++; + + } else if (zoneini.got_section("jumppoint")) { + jumppoint = new JumpPoint(); + jumppoint->set_zone(zone); + count ++; + + } else if(zoneini.got_section("racetrack")) { + racetrack = new RaceTrack(); + racetrack->set_zone(zone); + + } else if(zoneini.got_section("checkpoint")) { + checkpoint = new CheckPoint(racetrack); + if (!racetrack) { + con_warn << zoneini.name() << " checkpoint without racetrack at line " << zoneini.line() << std::endl; + } + + } else if (zoneini.got_section("planet")) { + planet = new Planet(); + planet->set_zone(zone); + count ++; + + } else if (zoneini.got_section("entity")) { + entity = new core::Entity(); + entity->entity_flags += core::Entity::Static; + entity->set_zone(zone); + count ++; + + } else if (zoneini.got_section()) { + con_warn << zoneini.name() << " unknown section '" << zoneini.section() << "' at line " << zoneini.line() << std::endl; + } + } + zoneini.close(); + + con_debug << " " << zoneini.name() << " " << zone->content().size() << " entities" << std::endl; + + + return true; +} + +bool Game::validate_zone(core::Zone *zone) +{ + con_debug << " validating " << zone->name() << std::endl; + + for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { + core::Entity *entity = (*it); + + if (entity->entity_moduletypeid == jumppoint_enttype) { + JumpPoint *jumppoint = static_cast(entity); + + if (jumppoint->targetlabel().size() < 3) { + con_warn << " Jumppoint with invalid target label '" << jumppoint->targetlabel() << "'\n"; + continue; + } + size_t pos = jumppoint->targetlabel().find(':'); + if ((pos < 1 ) || (pos >= (jumppoint->targetlabel().size()-1))) { + con_warn << " Jumppoint with invalid target label '" << jumppoint->targetlabel() << "'\n"; + continue; + } + + std::string zonelabel(jumppoint->targetlabel().substr(0, pos)); + std::string entitylabel(jumppoint->targetlabel().substr(pos+1, jumppoint->targetlabel().size()-pos)); + + core::Zone *targetzone = core::Zone::find(zonelabel); + if (!targetzone) { + con_warn << " Jumppoint with invalid target zone '" << zonelabel << "'\n"; + continue; + } + + core::Entity *targetentity = targetzone->find_entity(entitylabel); + if (!targetentity) { + con_warn << " Could not find target jumppoint '" << entitylabel << "'\n"; + continue; + } + + if (targetentity->moduletype() != jumppoint_enttype) { + con_warn << " Jumppoint with invalid target jumppoint '" << entitylabel << "'\n"; + continue; + } + + jumppoint->jumppoint_target = static_cast(targetentity); + + //con_debug << " Jumppoint " << zone->label() << ":" << jumppoint->label() << " with target " << jumppoint->targetlabel() << std::endl; + } + } + + return true; +} + +// read ship model specifications +bool Game::load_ships() +{ + using math::Vector3f; + using math::Color; + + default_shipmodel = 0; + + filesystem::IniFile shipsini; + shipsini.open("ships"); + if (!shipsini.is_open()) { + con_error << "Could not open ini/ships.ini!" << std::endl; + return false; + } + + ShipModel *shipmodel = 0; + std::string label; + bool b; + + while (shipsini.getline()) { + if (shipsini.got_key()) { + if (shipsini.section().compare("ship") == 0) { + if (shipsini.got_key_string("label", label)) { + aux::to_label(label); + shipmodel->shipmodel_label.assign(label); + ShipModel::add(shipmodel); + continue; + } else if (shipsini.got_key_string("name",shipmodel->shipmodel_name)) { + continue; + } else if (shipsini.got_key_string("model", shipmodel->shipmodel_modelname)) { + continue; + } else if (shipsini.got_key_bool("default", b)) { + if (b) default_shipmodel = shipmodel; + continue; + } else if (shipsini.got_key_bool("jumpdrive", shipmodel->shipmodel_jumpdrive)) { + continue; + } else if (shipsini.got_key_float("acceleration", shipmodel->shipmodel_acceleration)) { + continue; + } else if (shipsini.got_key_float("maxspeed", shipmodel->shipmodel_maxspeed)) { + continue; + } else if (shipsini.got_key_float("turnspeed", shipmodel->shipmodel_turnspeed)) { + math::clamp(shipmodel->shipmodel_turnspeed, 0.0f, 90.0f); + continue; + } else { + con_warn << shipsini.name() << " unknown key '" << shipsini.key() << "' at line " << shipsini.line() << std::endl; + } + } + } else if (shipsini.got_section("ship")) { + shipmodel = new ShipModel(); + + if (!default_shipmodel) + default_shipmodel = shipmodel; + + } else if (shipsini.got_section()) { + con_warn << shipsini.name() << " unknown section '" << shipsini.section() << "' at line " << shipsini.line() << std::endl; + } + } + shipsini.close(); + + con_debug << " " << shipsini.name() << " " << ShipModel::registry.size() << " ship models" << std::endl; + + if (!default_shipmodel) { + con_error << "No default ship model found!\n"; + return false; + } + + return true; +} + +void Game::frame(float seconds) +{ + if (!running()) + return; +} + +void Game::player_connect(core::Player *player) +{ + std::string args; + player->set_zone(default_zone); + func_spectate(player, args); +} + +void Game::player_disconnect(core::Player *player) +{ + player->remove_asset(player->control()); +} + +} // namespace game + diff --git a/src/game/base/jumppoint.cc b/src/game/base/jumppoint.cc new file mode 100644 index 0000000..bcaf8c5 --- /dev/null +++ b/src/game/base/jumppoint.cc @@ -0,0 +1,29 @@ +/* + base/jumppoint.cc + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#include "base/base.h" +#include "base/jumppoint.h" + +namespace base +{ + +JumpPoint::JumpPoint() : core::Entity(core::Entity::Static) +{ + entity_shape = core::Entity::Diamond; + entity_color.assign(0.0f, 0.8f, 0.8f, 1.0f); + entity_color_second.assign(0.6f, 1.0f); + entity_radius = 0.25f; + + entity_moduletypeid = jumppoint_enttype; + jumppoint_target = 0; + entity_serverside = false; +} + +JumpPoint::~JumpPoint() +{ +} + +} diff --git a/src/game/base/jumppoint.h b/src/game/base/jumppoint.h new file mode 100644 index 0000000..4680832 --- /dev/null +++ b/src/game/base/jumppoint.h @@ -0,0 +1,40 @@ +/* + base/jumppoint.h + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_BASE_JUMPPOINT_H__ +#define __INCLUDED_BASE_JUMPPOINT_H__ + +#include "core/entity.h" +#include "math/mathlib.h" + +#include + +namespace base { + +/// a jump point +/** + * jumppoints are used to define hyperspace routes between systems + * when a ship actives the jump drive, a jump point will be opened + * between the current system and the target of the nearest jumppoint. + * + */ +class JumpPoint : public core::Entity { +public: + JumpPoint(); + ~JumpPoint(); + + inline std::string const & targetlabel() { return jumppoint_targetlabel; } + inline JumpPoint *target() { return jumppoint_target; } + + std::string jumppoint_targetlabel; + + JumpPoint *jumppoint_target; +}; + +} + +#endif // __INCLUDED_BASE_JUMPPOINT_H__ + diff --git a/src/game/base/navpoint.cc b/src/game/base/navpoint.cc new file mode 100644 index 0000000..560962c --- /dev/null +++ b/src/game/base/navpoint.cc @@ -0,0 +1,27 @@ +/* + base/navpoint.cc + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#include "base/navpoint.h" +#include "base/base.h" + +namespace base +{ + +NavPoint::NavPoint() : core::Entity(core::Entity::Static | core::Entity::Bright) +{ + entity_shape = core::Entity::Diamond; + entity_color.assign(1.0f, 1.0f); + entity_color_second.assign(0.6f, 1.0f); + entity_radius = 0.25f; + + entity_moduletypeid = navpoint_enttype; +} + +NavPoint::~NavPoint() +{ +} + +} diff --git a/src/game/base/navpoint.h b/src/game/base/navpoint.h new file mode 100644 index 0000000..7ea505d --- /dev/null +++ b/src/game/base/navpoint.h @@ -0,0 +1,27 @@ +/* + base/navpoint.h + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_BASE_NAVPOINT_H__ +#define __INCLUDED_BASE_NAVPOINT_H__ + +#include "core/entity.h" +#include "math/mathlib.h" + +#include + +namespace base { + +/// a navigation point +class NavPoint : public core::Entity { +public: + NavPoint(); + ~NavPoint(); +}; + +} + +#endif // __INCLUDED_BASE_NAVPOINT_H__ + diff --git a/src/game/base/planet.cc b/src/game/base/planet.cc new file mode 100644 index 0000000..83f3d65 --- /dev/null +++ b/src/game/base/planet.cc @@ -0,0 +1,27 @@ +/* + base/planet.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2. +*/ + +#include "base/base.h" +#include "base/planet.h" + + +namespace base { + +Planet::Planet() : core::EntityGlobe(core::Entity::Static | core::Entity::Solid) +{ + entity_color = math::Color(1,1,1,1); // white + entity_radius = 64; // 64 game units + + entity_moduletypeid = planet_enttype; + + entity_rotationspeed = 1.0f; +} + +Planet::~Planet() +{ +} + +} // namespace game diff --git a/src/game/base/planet.h b/src/game/base/planet.h new file mode 100644 index 0000000..005157d --- /dev/null +++ b/src/game/base/planet.h @@ -0,0 +1,27 @@ +/* + base/planet.h + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_BASE_PLANET_H__ +#define __INCLUDED_BASE_PLANET_H__ + +#include "core/entity.h" +#include "math/mathlib.h" + +#include + +namespace base { + +/// a planet +class Planet : public core::EntityGlobe { +public: + Planet(); + ~Planet(); +}; + +} + +#endif // __INCLUDED_BASE_PLANET_H__ + diff --git a/src/game/base/racetrack.cc b/src/game/base/racetrack.cc new file mode 100644 index 0000000..ee2ecc7 --- /dev/null +++ b/src/game/base/racetrack.cc @@ -0,0 +1,195 @@ +/* + base/racetrack.cc + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#include +#include + +#include "base/racetrack.h" +#include "core/gameserver.h" + +namespace base { + +/* ---- class CheckPoint ------------------------------------------- */ + +CheckPoint::CheckPoint(RaceTrack *parent) +{ + entity_eventstate = core::Entity::NoPower; + parent_track = parent; + if (parent) { + entity_color = parent->color(); + entity_color_second = parent->color_second(); + set_zone(parent->zone()); + parent->add_checkpoint(this); + } else { + die(); + } +} + +CheckPoint::~CheckPoint() +{ + +} + +/* ---- class RaceTrack -------------------------------------------- */ + +RaceTrack::RaceTrack() +{ + track_player = 0; + track_racestart = 0; + track_checkpointtime = 0; + + entity_eventstate = core::Entity::NoPower; +} + +RaceTrack::~RaceTrack() +{ + track_checkpoints.clear(); +} + +void RaceTrack::add_checkpoint(CheckPoint *checkpoint) +{ + track_checkpoints.push_back(checkpoint); +} + +void RaceTrack::reset() +{ + if (track_player) { + track_player->set_mission_target(0); + } + track_player = 0; + track_racestart = 0; + track_checkpointtime = 0; + + for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { + (*cpit)->set_eventstate(core::Entity::NoPower); + } + + set_eventstate(core::Entity::NoPower); +} + +void RaceTrack::frame(float seconds) +{ + if (!track_checkpoints.size()) + return; + + if (!track_player) { + + // FIXME this should go through proper collision detection + for (core::GameServer::Players::iterator it = core::server()->players().begin(); it != core::server()->players().end(); ++it) { + if ((*it)->control() && (*it)->control()->zone() == zone()) { + if (math::distance((*it)->control()->location(), location()) <= 1) { + track_player = (*it); + + track_racestart = core::server()->time(); + set_eventstate(core::Entity::Normal); + + for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { + set_eventstate(core::Entity::Normal); + } + + entity_timer = 5.0f; + std::string message("^B"); + message.append(track_player->name()); + message.append(" ^Bactivated the race! Race starts in 5..."); + core::server()->broadcast(message); + track_player->set_mission_target(this); + return; + } + } + } + + return; + } + + // FIXME this should go into a proper general function + // validate current player + core::Player *player = 0; + for (core::GameServer::Players::iterator pit = core::server()->players().begin(); (!player) && (pit != core::server()->players().end()); ++pit) { + if ((*pit) == track_player) { + player = (*pit); + } + } + + if (!player) { + reset(); + return; + } + + if (!player->control() || (player->control()->zone() != zone())) { + reset(); + return; + } + + if (entity_timer) { + + if (math::distance(player->control()->location(), location()) > 1) { + std::string message("^BNo cheating!"); + core::server()->broadcast(message); + reset(); + return; + } + + if (track_racestart + 1.0f <= core::server()->time()) { + entity_timer -= 1.0f; + entity_dirty = true; + + if (entity_timer > 0) { + std::stringstream msgstr; + msgstr << "^B" << entity_timer << "..."; + core::server()->broadcast(msgstr.str()); + track_racestart = core::server()->time(); + } else { + for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { + (*cpit)->set_eventstate(core::Entity::NoPower); + } + std::string message("^BGo!"); + core::server()->broadcast(message); + + track_racestart = core::server()->time(); + track_checkpointtime = core::server()->time() + 15.0f; + track_checkpoint = track_checkpoints.begin(); + (*track_checkpoint)->set_eventstate(core::Entity::Normal); + track_player->set_mission_target((*track_checkpoint)); + } + } + + + } else { + + if (core::server()->time() > track_checkpointtime) { + std::string message("^BToo slow, race lost!"); + core::server()->broadcast(message); + + reset(); + return; + } + + if (math::distance(track_player->control()->location(), (*track_checkpoint)->location()) <= 1) { + CheckPoints::iterator next_checkpoint = track_checkpoint; + next_checkpoint++; + + if (next_checkpoint != track_checkpoints.end()) { + + std::string message("^BCheckpoint!"); + core::server()->broadcast(message); + track_checkpointtime = core::server()->time() + 15.0f; + (*track_checkpoint)->set_eventstate(core::Entity::NoPower); + track_checkpoint++; + (*track_checkpoint)->set_eventstate(core::Entity::Normal); + track_player->set_mission_target((*track_checkpoint)); + + } else { + + std::stringstream msgstr; + msgstr << "^BRace completed in " << core::server()->time() - track_racestart << " seconds!"; + core::server()->broadcast(msgstr.str()); + reset(); + } + } + } +} + +} diff --git a/src/game/base/racetrack.h b/src/game/base/racetrack.h new file mode 100644 index 0000000..b5b5dad --- /dev/null +++ b/src/game/base/racetrack.h @@ -0,0 +1,63 @@ +/* + base/racetrack.h + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_BASE_RACETRACK_H__ +#define __INCLUDED_BASE_RACETRACK_H__ + +#include "core/entity.h" +#include "core/player.h" +#include "math/mathlib.h" + +#include + +namespace base { + +class CheckPoint; + +/* ---- class RaceTrack -------------------------------------------- */ + +class RaceTrack : public core::EntityDynamic { + +public: + typedef std::list CheckPoints ; + + RaceTrack(); + ~RaceTrack(); + + void add_checkpoint(CheckPoint *checkpoint); + + /// reset the race track + void reset(); + + virtual void frame(float seconds); + + inline core::Player *player() { return track_player; } + +private: + CheckPoints track_checkpoints; + core::Player *track_player; + float track_racestart; + float track_checkpointtime; + CheckPoints::iterator track_checkpoint; + +}; + +/* ---- class CheckPoint ------------------------------------------- */ + +class CheckPoint : public core::EntityDynamic { +public: + CheckPoint(RaceTrack *parent); + ~CheckPoint(); + +private: + RaceTrack *parent_track; +}; + + +} + +#endif // __INCLUDED_BASE_NAVPOINT_H__ + diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc new file mode 100644 index 0000000..0fdfd3f --- /dev/null +++ b/src/game/base/ship.cc @@ -0,0 +1,464 @@ +/* + base/ship.cc + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#include +#include + +#include "auxiliary/functions.h" +#include "core/gameserver.h" +#include "core/entity.h" +#include "base/base.h" +#include "base/ship.h" +#include "math/functions.h" + + + +using math::degrees360f; +using math::degrees180f; + +namespace base { + +const float MIN_DELTA = 0.000001f; + +Ship::Ship(core::Player *owner, ShipModel *shipmodel) : + core::EntityControlable(owner, ship_enttype) +{ + entity_modelname = "ships/" + shipmodel->modelname(); + entity_name = shipmodel->name() + ": <^B" + owner->name() + "^N>"; + entity_label = shipmodel->label(); + + entity_moduletypeid = ship_enttype; + + entity_color = owner->color(); + entity_color_second = owner->color_second(); + + ship_shipmodel = shipmodel; + ship_jumpdrive = shipmodel->shipmodel_jumpdrive; + + ship_impulsedrive_timer = 0; + ship_jumpdrive_timer = 0; + + reset(); +} + +Ship::~Ship() +{ + +} + +void Ship::reset() +{ + current_target_direction = 0.0f; + current_target_pitch = 0.0f;; + current_target_roll = 0.0f; + current_target_strafe = 0.0f; + current_target_afterburner = 0.0f; +} +void Ship::impulse() +{ + if (entity_eventstate == core::Entity::Jump) { + return; + + } else if ((entity_eventstate == core::Entity::Impulse) || (entity_eventstate == core::Entity::ImpulseInitiate)) { + entity_eventstate = core::Entity::Normal; + + } else { + + if (entity_eventstate == core::Entity::JumpInitiate) { + ship_jumpdrive_timer = 0; + entity_timer = 0; + } + + entity_eventstate = core::Entity::ImpulseInitiate; + if (Base::instance()->g_devel->value()) { + entity_timer = 0; + } else { + entity_timer = 3; + } + ship_impulsedrive_timer = core::server()->time(); + entity_dirty = true; + } + + entity_dirty = true; +} + +void Ship::jump(std::string const &args) +{ + // devel mode provides instant jump access to arbitrary systems + if (Base::instance()->g_devel->value() && (args.size())) { + + core::Zone *jumptargetzone = 0; + std::string target; + std::istringstream is(args); + if (!(is >> target)) { + std::string helpstr; + for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { + core::Zone *zone = (*it).second; + if (helpstr.size()) + helpstr.append("^N|^B"); + helpstr.append(zone->label()); + } + + core::server()->send(owner(), "Usage: jump [^B" + helpstr + "^N]"); + return; + } + + aux::to_lowercase(target); + jumptargetzone = core::Zone::find_zone(target); + if (!jumptargetzone) { + core::server()->send(owner(), "Unknown system '" + target + '\''); + return; + } + + if (jumptargetzone == zone()) { + core::server()->send(owner(), "Already in the " + jumptargetzone->name() + '.'); + return; + } + + core::server()->send(owner(), "Jumping to the " + jumptargetzone->name()); + set_zone(jumptargetzone); + if (owner()->control() == (EntityControlable*) this) + owner()->set_zone(jumptargetzone); + + ship_jumpdrive_timer = 0; + entity_timer = 0; + entity_eventstate = core::Entity::Jump; + entity_dirty = true; + return; + + } else { + if (!jumpdrive() && !Base::instance()->g_devel->value()) { + core::server()->send(owner(), "This ship is not equiped with a hyperspace drive!"); + return; + + } else if (entity_eventstate == core::Entity::Jump) { + return; + + } else if (entity_eventstate == core::Entity::JumpInitiate) { + core::server()->send(owner(), "Jump aborted, hyperspace drive deactivated."); + ship_jumpdrive_timer = 0; + entity_timer = 0; + entity_eventstate = core::Entity::Normal; + return; + } + + if (!find_closest_jumppoint()) { + return; + } + + entity_eventstate = core::Entity::JumpInitiate; + if (Base::instance()->g_devel->value()) { + entity_timer = 0; + } else { + entity_timer = 8; + } + + ship_jumpdrive_timer = core::server()->time(); + entity_dirty = true; + } +} + +JumpPoint * Ship::find_closest_jumppoint() +{ + // find closest jumppoint + float d = -1; + JumpPoint *jumppoint = 0; + for (core::Zone::Content::iterator it = zone()->content().begin(); it != zone()->content().end(); it++) { + core::Entity *entity = (*it); + if (entity->moduletype() == jumppoint_enttype) { + JumpPoint *te = static_cast(entity); + float d1 = math::distance(location(), te->location()); + if ((d < 0) || (d1 < d)) { + d = d1; + jumppoint = te; + } + } + } + + if (jumppoint && jumppoint->target()) { + if (Base::instance()->g_jumppointrange->value() < d) { + core::server()->send(owner(), "Jumppoint out of range!"); + return 0; + } else { + core::server()->send(owner(), "Jumping to the " + jumppoint->target()->zone()->name()); + return jumppoint; + } + } else { + core::server()->send(owner(), "No jumppoints found!"); + return 0; + } + + return 0; +} + +void Ship::frame(float seconds) +{ + const float direction_change_speed = 2; + float cosangle; // cosine of an angle + float angle; // angle in radians + math::Vector3f n; // normal of a plane + + float actual_maxspeed = ship_shipmodel->maxspeed(); + float actual_turnspeed = ship_shipmodel->turnspeed(); + float actual_acceleration = ship_shipmodel->acceleration(); + + entity_movement = 0; + + // speed might get set to 0 on this update + if (entity_speed != 0.0f) + entity_dirty = true; + + // jumpdrive + // target axis + math::Axis target_axis(entity_axis); + + if (entity_eventstate == core::Entity::JumpInitiate) { + + if (ship_jumpdrive_timer + 1.0f <= core::server()->time()) { + entity_timer -= 1.0f; + + if (entity_timer <= 0) { + JumpPoint *jumppoint = find_closest_jumppoint(); + + if (jumppoint) { + set_zone(jumppoint->target()->zone()); + if (owner()->control() == (EntityControlable*) this) + owner()->set_zone(jumppoint->target()->zone()); + entity_eventstate = core::Entity::Jump; + entity_location.assign(jumppoint->target()->location() + location() - jumppoint->location()); + } else { + entity_eventstate = core::Entity::Normal; + } + ship_jumpdrive_timer = 0; + entity_timer = 0; + + entity_dirty = true; + return; + } else { + ship_jumpdrive_timer = core::server()->time(); + entity_dirty = true; + } + } + + // control is disabled while the jumpdrive is activated + target_thrust = 0; + target_pitch = 0; + target_roll = 0; + target_direction = 0; + target_afterburner = 0.0f; + target_thrust = 0; + + } else if (entity_eventstate == core::Entity::Jump) { + // control is disabled while the jumpdrive is activated + target_thrust = 0; + target_pitch = 0; + target_roll = 0; + target_direction = 0; + target_afterburner = 0.0f; + target_thrust = 0; + + // FIXME jump location and axis + math::Axis default_axis; + entity_axis.assign(default_axis); + entity_dirty = true; + + // FIXME 5 second cooldown + entity_eventstate = core::Entity::Normal; + + } else if (entity_eventstate == core::Entity::ImpulseInitiate) { + + if (ship_impulsedrive_timer + 1.0f <= core::server()->time()) { + entity_timer -= 1.0f; + + if (entity_timer <= 0) { + actual_maxspeed = Base::instance()->g_impulsespeed->value(); + actual_acceleration = Base::instance()->g_impulseacceleration->value(); + entity_eventstate = core::Entity::Impulse; + entity_timer = 0; + entity_dirty = true; + } else { + ship_impulsedrive_timer = core::server()->time(); + entity_dirty = true; + } + } + + // clamp input values + target_thrust = 0.0f; + math::clamp(target_pitch, -1.0f, 1.0f); + math::clamp(target_roll, -1.0f, 1.0f); + math::clamp(target_direction, -1.0f, 1.0f); + math::clamp(target_afterburner, -1.0f, 1.0f); + actual_turnspeed *= 0.5; + + } else if (entity_eventstate == core::Entity::Impulse) { + + // clamp input values + target_thrust = 0.0f; + math::clamp(target_pitch, -1.0f, 1.0f); + math::clamp(target_roll, -1.0f, 1.0f); + math::clamp(target_direction, -1.0f, 1.0f); + target_afterburner = 0.0f; + actual_maxspeed = Base::instance()->g_impulsespeed->value(); + actual_acceleration = Base::instance()->g_impulseacceleration->value(); + actual_turnspeed *= 0.5; + + } else if (entity_eventstate == core::Entity::Normal) { + + // clamp input values + math::clamp(target_thrust, 0.0f, 1.0f); + math::clamp(target_pitch, -1.0f, 1.0f); + math::clamp(target_roll, -1.0f, 1.0f); + math::clamp(target_direction, -1.0f, 1.0f); + math::clamp(target_afterburner, -1.0f, 1.0f); + + if (speed() > actual_maxspeed * 1.15f) { + actual_acceleration = Base::instance()->g_impulseacceleration->value(); + actual_turnspeed *= 0.5; + } + + } + + // update roll + if (current_target_roll < target_roll) { + current_target_roll += direction_change_speed * seconds; + if (current_target_roll > target_roll) + current_target_roll = target_roll; + } else if (current_target_roll > target_roll) { + current_target_roll -= direction_change_speed * seconds; + if (current_target_roll < target_roll) + current_target_roll = target_roll; + } + math::clamp(current_target_roll, -1.0f, 1.0f); + + if (fabs(current_target_roll) > MIN_DELTA) { + float roll_offset = seconds * current_target_roll; + entity_axis.change_roll(actual_turnspeed * roll_offset); + } else { + current_target_roll = 0.0f; + } + + // update target_axis direction + if (current_target_direction < target_direction) { + current_target_direction += direction_change_speed * seconds; + if (current_target_direction > target_direction) { + current_target_direction = target_direction; + } + } else if (current_target_direction > target_direction) { + current_target_direction -= direction_change_speed * seconds; + if (current_target_direction < target_direction) { + current_target_direction = target_direction; + } + } + + if (fabs(current_target_direction) > MIN_DELTA ) { + math::clamp(current_target_direction, -1.0f, 1.0f); + target_axis.change_direction(actual_turnspeed * current_target_direction); + } else { + current_target_direction = 0.0f; + } + + if (current_target_pitch < target_pitch) { + current_target_pitch += direction_change_speed * seconds; + if (current_target_pitch > target_pitch) + current_target_pitch = target_pitch; + } else if (current_target_pitch > target_pitch) { + current_target_pitch -= direction_change_speed * seconds; + if (current_target_pitch < target_pitch) + current_target_pitch = target_pitch; + } + + if (fabs(current_target_pitch) > MIN_DELTA) { + math::clamp(current_target_pitch, -1.0f, 1.0f); + target_axis.change_pitch(actual_turnspeed * current_target_pitch); + } else { + current_target_pitch = 0.0f; + } + + n.assign(math::crossproduct(entity_axis.forward(), target_axis.forward())); + if (!(n.length() < MIN_DELTA)) { + n.normalize(); + cosangle = math::dotproduct(entity_axis.forward(), target_axis.forward()); + angle = acos(cosangle) * seconds; // * 180.0f / M_PI; + if (angle > MIN_DELTA) + entity_axis.rotate(n, -angle); + } + + // update afterburner + if (current_target_afterburner < target_afterburner) { + current_target_afterburner += 2.0f * seconds; + if (current_target_afterburner > target_afterburner) + current_target_afterburner = target_afterburner; + } else if (current_target_afterburner > target_afterburner) { + current_target_afterburner -= 2.0f * seconds; + if (current_target_afterburner < target_afterburner) + current_target_afterburner = target_afterburner; + } + + // update thrust + if (current_target_afterburner < 0.0f) { + target_thrust = 0; + } + + if (entity_thrust < target_thrust) { + entity_thrust += seconds * 0.5f; + if (entity_thrust > target_thrust) + entity_thrust = target_thrust; + } else if (entity_thrust > target_thrust) { + entity_thrust -= seconds * 0.5f; + if (entity_thrust < target_thrust) + entity_thrust = target_thrust; + } + math::clamp(entity_thrust, 0.0f, 1.0f); + float actual_thrust = entity_thrust + current_target_afterburner * 0.15f; + + if ((entity_eventstate == core::Entity::ImpulseInitiate) || (entity_eventstate == core::Entity::Impulse)) { + actual_thrust = 1.0f; + } + + // update speed + if (entity_speed < actual_thrust * actual_maxspeed) { + entity_speed += actual_acceleration * seconds; + if (entity_speed > actual_thrust * actual_maxspeed) { + entity_speed = actual_thrust * actual_maxspeed; + } + } else if(entity_speed > actual_thrust * actual_maxspeed) { + entity_speed -= actual_acceleration * seconds; + if (entity_speed < actual_thrust * actual_maxspeed) { + entity_speed = actual_thrust * actual_maxspeed; + } + } + + // update strafe + if (current_target_strafe < target_strafe) { + current_target_strafe += 2.0f * seconds; + if (current_target_strafe > target_strafe) + current_target_strafe = target_strafe; + } else if (current_target_strafe > target_strafe) { + current_target_strafe -= 2.0f * seconds; + if (current_target_strafe < target_strafe) + current_target_strafe = target_strafe; + } + + if (fabs(current_target_strafe) > MIN_DELTA) { + entity_location += entity_axis.left() * (current_target_strafe * Base::instance()->g_strafespeed->value()); + } + + entity_movement = target_thrust; + entity_movement = math::max(entity_movement, fabs(current_target_pitch)); + entity_movement = math::max(entity_movement, fabs(current_target_direction)); + entity_movement = math::max(entity_movement, fabs(current_target_roll)); + entity_movement = math::max(entity_movement, fabs(current_target_afterburner)); + entity_movement = math::max(entity_movement, fabs(current_target_strafe)); + + if (entity_speed) { + entity_location += entity_axis.forward() * entity_speed * seconds; + entity_dirty = true; + } else if (entity_movement > 0.0f) { + entity_dirty = true; + } +} + +} // namespace game diff --git a/src/game/base/ship.h b/src/game/base/ship.h new file mode 100644 index 0000000..d3c8bbf --- /dev/null +++ b/src/game/base/ship.h @@ -0,0 +1,60 @@ +/* + base/ship.h + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_BASE_SHIP_H__ +#define __INCLUDED_BASE_SHIP_H__ + +#include "core/player.h" +#include "core/entity.h" +#include "base/shipmodel.h" +#include "base/jumppoint.h" +#include "math/vector3f.h" + +namespace base { + +/// A ship in the game, controled by a player +class Ship : public core::EntityControlable +{ +public: + Ship(core::Player *owner, ShipModel *shipmodel); + ~Ship(); + + /// update the ship state + virtual void frame(float seconds); + + /// true if the ship is equiped with a jumpdrive + inline bool jumpdrive() const { return ship_jumpdrive; } + + /// toggle jump drive activation + void jump(std::string const & args); + + /// toggle impulse drive activation + void impulse(); + + /// void reset drive controls + void reset(); + +private: + ShipModel *ship_shipmodel; + + float current_target_direction; + float current_target_pitch; + float current_target_roll; + float current_target_strafe; + float current_target_afterburner; + + bool ship_jumpdrive; + float ship_jumpdrive_timer; + + float ship_impulsedrive_timer; + + JumpPoint * find_closest_jumppoint(); +}; + +} + +#endif // __INCLUDED_BASE_SHIP_H__ + diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc new file mode 100644 index 0000000..6018414 --- /dev/null +++ b/src/game/base/shipmodel.cc @@ -0,0 +1,72 @@ +/* + base/shipmodel.cc + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#include "sys/sys.h" +#include "base/shipmodel.h" + +namespace base { + +// the ship model registry +std::map ShipModel::registry; + +ShipModel::ShipModel() +{ + //default specifications + shipmodel_acceleration = 1.0f; // thruster acceleration in game untits/second^2 + shipmodel_maxspeed = 3.0f; // maximum thruster speed in game units/second + shipmodel_turnspeed = 45.0f; // 45 degrees per second + + shipmodel_jumpdrive = false; +} + +ShipModel::~ShipModel() +{} + + +// clear the ship model registry +void ShipModel::clear() +{ + for (iterator smit = registry.begin(); smit != registry.end(); smit++) { + delete (*smit).second; + } + registry.clear(); +} + +void ShipModel::list() +{ + for (iterator smit = registry.begin(); smit != registry.end(); smit++) { + con_print << + " " << (*smit).second->label() << + " " << (*smit).second->name() << + " accel " << (*smit).second->acceleration() << + " max " << (*smit).second->maxspeed() << + " turn " << (*smit).second->turnspeed() << "\n"; + } + con_print << registry.size() << " registered ship models\n"; +} + +ShipModel *ShipModel::find(const std::string label) +{ + std::map::iterator it = registry.find(label); + if (it == registry.end()) + return 0; + else + return (*it).second; +} + +// add a new ship model +void ShipModel::add(ShipModel *shipmodel) +{ + ShipModel *m = find(shipmodel->label()); + if (m) { + con_warn << "Duplicate ship model " << shipmodel->label() << "!\n"; + delete m; + } + + registry[shipmodel->label()] = shipmodel; +} + +} diff --git a/src/game/base/shipmodel.h b/src/game/base/shipmodel.h new file mode 100644 index 0000000..d92b840 --- /dev/null +++ b/src/game/base/shipmodel.h @@ -0,0 +1,70 @@ +/* + base/shipmodel.h + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_BASE_SHIPMODEL_H__ +#define __INCLUDED_BASE_SHIPMODEL_H__ + +#include +#include + +namespace base { + +/// ship model specifications +class ShipModel +{ +public: + ShipModel(); + ~ShipModel(); + + /// acceleration + inline float acceleration() const { return shipmodel_acceleration; } + + /// maximum speed + inline float maxspeed() const { return shipmodel_maxspeed; } + + /// turn speed in rotations per second + inline float turnspeed() const { return shipmodel_turnspeed; } + + /// label of the ship model + inline std::string const &label() const { return shipmodel_label; } + + /// name of the ship model + inline std::string const & name() const { return shipmodel_name; } + + /// name of the model of the ship + inline std::string const & modelname() const { return shipmodel_modelname; } + + float shipmodel_acceleration; + float shipmodel_maxspeed; + float shipmodel_turnspeed; + std::string shipmodel_label; + std::string shipmodel_name; + std::string shipmodel_modelname; + + /// indicates of this model can be equiped with a jump drive + bool shipmodel_jumpdrive; + + static ShipModel *find(const std::string label); + + /// the ship model registry + static std::map registry; + + typedef std::map::iterator iterator; + + /// clear the ship model registry + static void clear(); + + /// list the ship model registry + static void list(); + + /// add a new ship model + static void add(ShipModel *shipmodel); +}; + +} + +#endif // __INCLUDED_BASE_SHIPMODEL_H__ + diff --git a/src/game/base/star.cc b/src/game/base/star.cc new file mode 100644 index 0000000..cacd542 --- /dev/null +++ b/src/game/base/star.cc @@ -0,0 +1,25 @@ +/* + base/star.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2. +*/ + +#include "base/base.h" +#include "base/star.h" + + +namespace base { + +Star::Star() : core::EntityGlobe(core::Entity::Static | core::Entity::Solid | core::Entity::Bright) +{ + entity_color = math::Color(1,1,1,1); // white + entity_radius = 96; // 96 game units + + entity_moduletypeid = star_enttype; +} + +Star::~Star() +{ +} + +} // namespace game diff --git a/src/game/base/star.h b/src/game/base/star.h new file mode 100644 index 0000000..5a78fc8 --- /dev/null +++ b/src/game/base/star.h @@ -0,0 +1,29 @@ +/* + base/star.h + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_BASE_STAR_H__ +#define __INCLUDED_BASE_STAR_H__ + +// project headers +#include "core/entity.h" +#include "math/mathlib.h" + +// C++ headers +#include + +namespace base { + +/// a star, that shines so bright +class Star : public core::EntityGlobe { +public: + Star(); + ~Star(); +}; + +} + +#endif // __INCLUDED_BASE_STAR_H__ + diff --git a/src/game/game.cc b/src/game/game.cc index 4d66cbe..0b7e0f2 100644 --- a/src/game/game.cc +++ b/src/game/game.cc @@ -4,658 +4,19 @@ the terms of the GNU General Public License version 2 */ -#include -#include - -#include "auxiliary/functions.h" -#include "core/gameserver.h" -#include "filesystem/filesystem.h" -#include "filesystem/inifile.h" #include "game/game.h" -#include "game/navpoint.h" -#include "game/jumppoint.h" -#include "game/planet.h" -#include "game/racetrack.h" -#include "game/ship.h" -#include "game/star.h" -#include "math/mathlib.h" +#include "base/base.h" +#include "core/core.h" #include "sys/sys.h" -namespace game -{ - -ShipModel *default_shipmodel = 0; -core::Zone *default_zone = 0; - -/*----- engine game functions ------------------------------------- */ - -/// list the ship model registry -void func_list_ship(std::string const &args) -{ - ShipModel::list(); -} - -/// a player joins the game -void func_join(core::Player *player, std::string const &args) -{ - if (player->control()) - return; - - player->set_zone(default_zone); - Ship *ship = new Ship(player, default_shipmodel); - ship->set_zone(default_zone); - player->set_control(ship); - - core::server()->send_sound(player, "game/buy-ship"); - - std::string message("^B"); - message.append(player->name()); - message.append("^B joins the game."); - core::server()->broadcast(message); - - player->player_dirty = true; -} - -/// a player joins the spectators -void func_spectate(core::Player *player, std::string const &args) -{ - if (!player->control()) - return; - - std::string message("^B"); - message.append(player->name()); - message.append("^B spectates."); - core::server()->broadcast(message); - - if (player->control()) { - player->remove_asset(player->control()); - } -} - -/// a player buys a ship -void func_buy(core::Player *player, std::string const &args) -{ - - std::string shipname; - std::string helpstr; - std::istringstream is(args); - is >> shipname; - aux::to_lowercase(shipname); - - ShipModel *shipmodel = 0; - for (ShipModel::iterator smit = ShipModel::registry.begin(); smit != ShipModel::registry.end(); smit++) { - if (shipname == (*smit).first) { - shipmodel = (*smit).second; - break; - } - - if (helpstr.size()) - helpstr.append("^N|^B"); - helpstr.append((*smit).second->label()); - } - - if (shipmodel) { - // player has only ship for now - if (player->control()) { - player->remove_asset(player->control()); - } - - Ship * ship = new Ship(player, shipmodel); - if (player->zone()) { - ship->set_zone(player->zone()); - } else { - ship->set_zone(default_zone); - } - player->set_control(ship); - - core::server()->broadcast("^B" + player->name() + " ^Bpurchased " + aux::article(shipmodel->name())); - core::server()->send_sound(player, "game/buy-ship"); - - } else { - core::server()->send(player, "Usage: buy [^B" + helpstr + "^N]"); - } -} - -/// a player sends standard hails -void func_hail(core::Player *player, std::string const &args) -{ - std::string target; - std::istringstream is(args); - if (!(is >> target)) { - core::server()->send(player, "Usage: hail [player]"); - return; - } - - core::Player *targetplayer = core::server()->find_player(target); - if (!targetplayer) { - core::server()->send(player, "^BPlayer " + target + "^B not found."); - return; - } - - core::server()->send(player, "^BYou hail " + targetplayer->name() + "^B."); - core::server()->send_sound(player, "com/hail"); - - core::server()->send(targetplayer, "^B" + player->name() + "^B hails you!"); - core::server()->send_sound(targetplayer, "com/hail"); -} - -/// a player actives the hyperspace jump drive on his ship -void func_jump(core::Player *player, std::string const &args) -{ - if (!player->control()) - return; - if (!player->control()->moduletype() == ship_enttype) - return; - Ship * ship = static_cast(player->control()); - ship->jump(args); -} - -/// a player actives the kinetic impulse drive on his ship -void func_impulse(core::Player *player, std::string const &args) -{ - if (!player->control()) - return; - if (!player->control()->moduletype() == ship_enttype) - return; - Ship * ship = static_cast(player->control()); - ship->impulse(); -} - -/* ---- The Game class --------------------------------------------- */ - -Game *Game::game_instance = 0; - -Game::Game() : core::Module("Project::OSiRiON") -{ - game_instance = this; - g_impulsespeed = 0; -} - -Game::~Game() -{ - game_instance = 0; -} - -void Game::init() -{ - module_running = false; - - ShipModel::clear(); - - if (!load_world()) { - abort(); - return; - } - - if (!load_ships()) { - abort(); - return; - } - - // add engine game functions - core::Func *func = 0; - - func = core::Func::add("join", (core::GameFuncPtr) func_join); - func->set_info("join the game"); - func = core::Func::add("hail", (core::GameFuncPtr) func_hail); - func->set_info("send a standard hail"); - func = core::Func::add("spectate", (core::GameFuncPtr) func_spectate); - func->set_info("leave the game and spectate"); - - func = core::Func::add("buy", (core::GameFuncPtr) func_buy); - func->set_info("buy a ship"); - - func = core::Func::add("jump", (core::GameFuncPtr) func_jump); - func->set_info("[string] activate or deactivate hyperspace jump drive"); - - func = core::Func::add("impulse", (core::GameFuncPtr) func_impulse); - func->set_info("activate are deactive kinetic impulse drive"); - - // add engine core functions - func = core::Func::add("list_ship", (core::FuncPtr) func_list_ship); - func->set_info("list ship statistics"); - - g_impulsespeed = core::Cvar::get("g_impulsespeed", "15", core::Cvar::Game | core::Cvar::Archive); - g_impulsespeed->set_info("[float] speed of the impulse drive"); - - g_impulseacceleration = core::Cvar::get("g_impulseacceleration", "5", core::Cvar::Game | core::Cvar::Archive); - g_impulseacceleration->set_info("[float] acceleration of the impulse drive"); - - g_strafespeed = core::Cvar::get("g_strafespeed", "0.003", core::Cvar::Game | core::Cvar::Archive); - g_strafespeed->set_info("[float] strafe speed"); - - g_jumppointrange = core::Cvar::get("g_jumppointrange", "512", core::Cvar::Game | core::Cvar::Archive); - g_jumppointrange->set_info("[float] jumppoint range"); - - g_devel = core::Cvar::get("g_devel", "0", core::Cvar::Archive); - g_devel->set_info("[bool] enable or disable developer mode"); - - // indicate the module is ready to run frames - module_running = true; -} - -void Game::shutdown() -{ - g_impulsespeed = 0; - // game functions are automaticly removed - - // remove engine core functions - core::Func::remove("list_ship"); - - ShipModel::clear(); - module_running = false; -} - -bool Game::load_world() -{ - std::string inifilename("world"); - - filesystem::IniFile worldini; - worldini.open(inifilename); - - if (!worldini.is_open()) { - con_error << "Could not open " << worldini.name() << std::endl; - return false; - } - - core::Zone *zone = 0; - std::string label; - - while (worldini.getline()) { - - if (worldini.got_section()) { - - if (worldini.got_section("world")) { - continue; - } else { - con_warn << worldini.name() << " unknown section '" << worldini.section() << "' at line " << worldini.line() << std::endl; - } - - } else if (worldini.section().compare("world") == 0 ) { - if (worldini.got_key_string("zone", label)) { - aux::to_label(label); - zone = new core::Zone(label); - core::Zone::add(zone); - } - } - } - worldini.close(); - - if (!core::Zone::registry().size()) { - con_error << "No zones found!" << std::endl; - return false; - } - - con_debug << " " << worldini.name() << " " << core::Zone::registry().size() << " zones" << std::endl; - - for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { - if (!load_zone((*it).second)) { - return false; - } - } - - for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { - if (!validate_zone((*it).second)) { - return false; - } - } - - if (!default_zone) { - con_error << "No default zone found!" << std::endl; - return false; - } - - return true; -} - -bool Game::got_entity_key(filesystem::IniFile &inifile, core::Entity *entity) -{ - std::string shapename; - std::string strval; - float direction; - float pitch; - float roll; - - if (inifile.got_key_string("shape", shapename)) { - - if (shapename.compare("axis") == 0) { - entity->entity_shape = core::Entity::Axis; - return true; - } else if (shapename.compare("cube") == 0) { - entity->entity_shape = core::Entity::Cube; - return true; - } else if (shapename.compare("diamond") == 0) { - entity->entity_shape = core::Entity::Diamond; - return true; - } else if (shapename.compare("sphere") == 0) { - entity->entity_shape = core::Entity::Sphere; - return true; - } else { - con_warn << inifile.name() << " unknown shape '" << shapename << "' at line " << inifile.line() << std::endl; - return false; - } - - } else if (inifile.got_key_string("label", strval)) { - aux::to_label(strval); - entity->entity_label.assign(strval); - return true; - } else if (inifile.got_key_string("name", strval)) { - aux::strip_quotes(strval); - entity->entity_name.assign(strval); - return true; - } else if (inifile.got_key_string("model", entity->entity_modelname)) { - return true; - } else if (inifile.got_key_angle("direction", direction)) { - entity->axis().change_direction(direction); - return true; - } else if (inifile.got_key_angle("pitch", pitch)) { - entity->axis().change_pitch(pitch); - return true; - } else if (inifile.got_key_angle("roll", roll)) { - entity->axis().change_roll(roll); - return true; - } else if (inifile.got_key_angle("radius", entity->entity_radius)) { - return true; - } else if (inifile.got_key_vector3f("location", entity->entity_location)) { - return true; - } else if (inifile.got_key_color("color", entity->entity_color)) { - return true; - } else if (inifile.got_key_color("colorsecond", entity->entity_color_second)) { - return true; - } - - return false; -} - -bool Game::load_zone(core::Zone *zone) -{ - using math::Vector3f; - using math::Color; - - std::string inifilename("zones/"); - inifilename.append(zone->label()); - - filesystem::IniFile zoneini; - zoneini.open(inifilename); - - if (!zoneini.is_open()) { - con_error << "Could not open " << zoneini.name() << std::endl; - return false; - } - - size_t count = 0; - - Planet *planet = 0; - Star *star = 0; - NavPoint *navpoint = 0; - JumpPoint *jumppoint = 0; - RaceTrack *racetrack = 0; - CheckPoint *checkpoint = 0; - core::Entity *entity = 0; - - bool b; - - std::string strval; - - // set th default sky - zone->set_sky("sky"); - - while (zoneini.getline()) { - if (zoneini.got_key()) { - if (zoneini.section().compare("zone") == 0) { - if (zoneini.got_key_string("name", strval)) { - aux::strip_quotes(strval); - zone->set_name(strval); - continue; - } else if (zoneini.got_key_string("sky", strval)) { - zone->set_sky(strval); - continue; - } else if (zoneini.got_key_bool("default", b)) { - if (b) default_zone = zone; - continue; - } else { - con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; - } - } else if (zoneini.section().compare("star") == 0) { - if (got_entity_key(zoneini, star)) { - continue; - } else if (zoneini.got_key_string("texture", star->entity_texture)) { - continue; - } else { - con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; - } - } else if (zoneini.section().compare("navpoint") == 0) { - if (got_entity_key(zoneini, navpoint)) { - continue; - } else { - con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; - } - } else if (zoneini.section().compare("jumppoint") == 0) { - if (got_entity_key(zoneini, jumppoint)) { - continue; - } else if (zoneini.got_key_string("target", jumppoint->jumppoint_targetlabel)) { - continue; - } else { - con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; - } - } else if (zoneini.section().compare("planet") == 0) { - if (got_entity_key(zoneini, planet)) { - continue; - } else if (zoneini.got_key_string("texture", planet->entity_texture)) { - continue; - } else if (zoneini.got_key_float("rotationspeed", planet->entity_rotationspeed)) { - continue; - } else { - con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; - } - - } else if (zoneini.section().compare("racetrack") == 0) { - if (got_entity_key(zoneini, racetrack)) { - continue; - } else { - con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; - } - - } else if (zoneini.section().compare("checkpoint") == 0) { - if (got_entity_key(zoneini, checkpoint)) { - continue; - } else { - con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; - } - - } else if (zoneini.section().compare("entity") == 0) { - if (got_entity_key(zoneini, entity)) { - continue; - } else { - con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; - } - } - } else if (zoneini.got_section("zone")) { - continue; - - } else if (zoneini.got_section("star")) { - star = new Star(); - star->set_zone(zone); - count ++; - - } else if (zoneini.got_section("navpoint")) { - navpoint = new NavPoint(); - navpoint->set_zone(zone); - count ++; - - } else if (zoneini.got_section("jumppoint")) { - jumppoint = new JumpPoint(); - jumppoint->set_zone(zone); - count ++; - - } else if(zoneini.got_section("racetrack")) { - racetrack = new RaceTrack(); - racetrack->set_zone(zone); - - } else if(zoneini.got_section("checkpoint")) { - checkpoint = new CheckPoint(racetrack); - if (!racetrack) { - con_warn << zoneini.name() << " checkpoint without racetrack at line " << zoneini.line() << std::endl; - } - - } else if (zoneini.got_section("planet")) { - planet = new Planet(); - planet->set_zone(zone); - count ++; - - } else if (zoneini.got_section("entity")) { - entity = new core::Entity(); - entity->entity_flags += core::Entity::Static; - entity->set_zone(zone); - count ++; - - } else if (zoneini.got_section()) { - con_warn << zoneini.name() << " unknown section '" << zoneini.section() << "' at line " << zoneini.line() << std::endl; - } - } - zoneini.close(); - - con_debug << " " << zoneini.name() << " " << zone->content().size() << " entities" << std::endl; - - - return true; -} - -bool Game::validate_zone(core::Zone *zone) -{ - con_debug << " validating " << zone->name() << std::endl; - - for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { - core::Entity *entity = (*it); - - if (entity->entity_moduletypeid == jumppoint_enttype) { - JumpPoint *jumppoint = static_cast(entity); - - if (jumppoint->targetlabel().size() < 3) { - con_warn << " Jumppoint with invalid target label '" << jumppoint->targetlabel() << "'\n"; - continue; - } - size_t pos = jumppoint->targetlabel().find(':'); - if ((pos < 1 ) || (pos >= (jumppoint->targetlabel().size()-1))) { - con_warn << " Jumppoint with invalid target label '" << jumppoint->targetlabel() << "'\n"; - continue; - } - - std::string zonelabel(jumppoint->targetlabel().substr(0, pos)); - std::string entitylabel(jumppoint->targetlabel().substr(pos+1, jumppoint->targetlabel().size()-pos)); - - core::Zone *targetzone = core::Zone::find(zonelabel); - if (!targetzone) { - con_warn << " Jumppoint with invalid target zone '" << zonelabel << "'\n"; - continue; - } - - core::Entity *targetentity = targetzone->find_entity(entitylabel); - if (!targetentity) { - con_warn << " Could not find target jumppoint '" << entitylabel << "'\n"; - continue; - } - - if (targetentity->moduletype() != jumppoint_enttype) { - con_warn << " Jumppoint with invalid target jumppoint '" << entitylabel << "'\n"; - continue; - } - - jumppoint->jumppoint_target = static_cast(targetentity); - - //con_debug << " Jumppoint " << zone->label() << ":" << jumppoint->label() << " with target " << jumppoint->targetlabel() << std::endl; - } - } - - return true; -} - -// read ship model specifications -bool Game::load_ships() -{ - using math::Vector3f; - using math::Color; - - default_shipmodel = 0; - - filesystem::IniFile shipsini; - shipsini.open("ships"); - if (!shipsini.is_open()) { - con_error << "Could not open ini/ships.ini!" << std::endl; - return false; - } - - ShipModel *shipmodel = 0; - std::string label; - bool b; - - while (shipsini.getline()) { - if (shipsini.got_key()) { - if (shipsini.section().compare("ship") == 0) { - if (shipsini.got_key_string("label", label)) { - aux::to_label(label); - shipmodel->shipmodel_label.assign(label); - ShipModel::add(shipmodel); - continue; - } else if (shipsini.got_key_string("name",shipmodel->shipmodel_name)) { - continue; - } else if (shipsini.got_key_string("model", shipmodel->shipmodel_modelname)) { - continue; - } else if (shipsini.got_key_bool("default", b)) { - if (b) default_shipmodel = shipmodel; - continue; - } else if (shipsini.got_key_bool("jumpdrive", shipmodel->shipmodel_jumpdrive)) { - continue; - } else if (shipsini.got_key_float("acceleration", shipmodel->shipmodel_acceleration)) { - continue; - } else if (shipsini.got_key_float("maxspeed", shipmodel->shipmodel_maxspeed)) { - continue; - } else if (shipsini.got_key_float("turnspeed", shipmodel->shipmodel_turnspeed)) { - math::clamp(shipmodel->shipmodel_turnspeed, 0.0f, 90.0f); - continue; - } else { - con_warn << shipsini.name() << " unknown key '" << shipsini.key() << "' at line " << shipsini.line() << std::endl; - } - } - } else if (shipsini.got_section("ship")) { - shipmodel = new ShipModel(); - - if (!default_shipmodel) - default_shipmodel = shipmodel; - - } else if (shipsini.got_section()) { - con_warn << shipsini.name() << " unknown section '" << shipsini.section() << "' at line " << shipsini.line() << std::endl; - } - } - shipsini.close(); - - con_debug << " " << shipsini.name() << " " << ShipModel::registry.size() << " ship models" << std::endl; - - if (!default_shipmodel) { - con_error << "No default ship model found!\n"; - return false; - } - - return true; -} - -void Game::frame(float seconds) +namespace game { - if (!running()) - return; -} -void Game::player_connect(core::Player *player) +void register_modules(bool register_client_modules) { - std::string args; - player->set_zone(default_zone); - func_spectate(player, args); -} + con_print << "^BRegistering game modules..." << std::endl; + core::Module::add("base", new base::Base()); -void Game::player_disconnect(core::Player *player) -{ - player->remove_asset(player->control()); } -} // namespace game - +} \ No newline at end of file diff --git a/src/game/game.h b/src/game/game.h index 3b65da1..544f26b 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -7,71 +7,9 @@ #ifndef __INCLUDED_GAME_H__ #define __INCLUDED_GAME_H__ -#include -#include - -#include "filesystem/inifile.h" -#include "game/ship.h" -#include "game/star.h" -#include "core/core.h" -#include "sys/sys.h" - -/// the game-specific engine -/** The main game functions. - */ -namespace game -{ - -// entity type constants -const unsigned int ship_enttype = 256; -const unsigned int star_enttype = 257; -const unsigned int planet_enttype = 258; -const unsigned int navpoint_enttype = 259; -const unsigned int jumppoint_enttype = 260; - -class Game : public core::Module { -public: - Game(); - ~Game(); - - /// initialize the game - void init(); - - /// shutdown the game - void shutdown(); - - /// run one time frame - void frame(float seconds); - - /// is called when a player connects - void player_connect(core::Player *player); - - /// is called when a player disconnects - void player_disconnect(core::Player *player); - - static inline Game *instance() { return game_instance; } - - core::Cvar *g_impulsespeed; - core::Cvar *g_impulseacceleration; - core::Cvar *g_strafespeed; - core::Cvar *g_jumppointrange; - - core::Cvar *g_devel; - -private: - bool got_entity_key(filesystem::IniFile &inifile, core::Entity *entity); - - bool load_world(); - - bool load_zone(core::Zone *zone); - - bool validate_zone(core::Zone *zone); - - bool load_ships(); - - static Game *game_instance; -}; - +namespace game { + + void register_modules(bool register_client_modules=false); } #endif // __INCLUDED_GAME_H__ diff --git a/src/game/intro/Makefile.am b/src/game/intro/Makefile.am new file mode 100644 index 0000000..66ea90d --- /dev/null +++ b/src/game/intro/Makefile.am @@ -0,0 +1,2 @@ +INCLUDES = -I$(top_srcdir)/src +METASOURCES = AUTO diff --git a/src/game/jumppoint.cc b/src/game/jumppoint.cc deleted file mode 100644 index d2c6bc1..0000000 --- a/src/game/jumppoint.cc +++ /dev/null @@ -1,29 +0,0 @@ -/* - game/jumppoint.cc - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#include "game/jumppoint.h" -#include "game/game.h" - -namespace game -{ - -JumpPoint::JumpPoint() : core::Entity(core::Entity::Static) -{ - entity_shape = core::Entity::Diamond; - entity_color.assign(0.0f, 0.8f, 0.8f, 1.0f); - entity_color_second.assign(0.6f, 1.0f); - entity_radius = 0.25f; - - entity_moduletypeid = jumppoint_enttype; - jumppoint_target = 0; - entity_serverside = false; -} - -JumpPoint::~JumpPoint() -{ -} - -} diff --git a/src/game/jumppoint.h b/src/game/jumppoint.h deleted file mode 100644 index 59ec69c..0000000 --- a/src/game/jumppoint.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - game/jumppoint.h - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#ifndef __INCLUDED_GAME_JUMPPOINT_H__ -#define __INCLUDED_GAME_JUMPPOINT_H__ - -#include "core/entity.h" -#include "math/mathlib.h" - -#include - -namespace game { - -/// a jump point -/** - * jumppoints are used to define hyperspace routes between systems - * when a ship actives the jump drive, a jump point will be opened - * between the current system and the target of the nearest jumppoint. - * - */ -class JumpPoint : public core::Entity { -public: - JumpPoint(); - ~JumpPoint(); - - inline std::string const & targetlabel() { return jumppoint_targetlabel; } - inline JumpPoint *target() { return jumppoint_target; } - - std::string jumppoint_targetlabel; - - JumpPoint *jumppoint_target; -}; - -} - -#endif // __INCLUDED_GAME_JUMPPOINT_H__ - diff --git a/src/game/navpoint.cc b/src/game/navpoint.cc deleted file mode 100644 index 24e87ca..0000000 --- a/src/game/navpoint.cc +++ /dev/null @@ -1,27 +0,0 @@ -/* - game/navpoint.cc - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#include "game/navpoint.h" -#include "game/game.h" - -namespace game -{ - -NavPoint::NavPoint() : core::Entity(core::Entity::Static | core::Entity::Bright) -{ - entity_shape = core::Entity::Diamond; - entity_color.assign(1.0f, 1.0f); - entity_color_second.assign(0.6f, 1.0f); - entity_radius = 0.25f; - - entity_moduletypeid = navpoint_enttype; -} - -NavPoint::~NavPoint() -{ -} - -} diff --git a/src/game/navpoint.h b/src/game/navpoint.h deleted file mode 100644 index ef60267..0000000 --- a/src/game/navpoint.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - game/navpoint.h - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#ifndef __INCLUDED_GAME_NAVPOINT_H__ -#define __INCLUDED_GAME_NAVPOINT_H__ - -#include "core/entity.h" -#include "math/mathlib.h" - -#include - -namespace game { - -/// a navigation point -class NavPoint : public core::Entity { -public: - NavPoint(); - ~NavPoint(); -}; - -} - -#endif // __INCLUDED_GAME_NAVPOINT_H__ - diff --git a/src/game/planet.cc b/src/game/planet.cc deleted file mode 100644 index 80e4922..0000000 --- a/src/game/planet.cc +++ /dev/null @@ -1,27 +0,0 @@ -/* - game/planet.cc - This file is part of the Osirion project and is distributed under - the terms of the GNU General Public License version 2. -*/ - -#include "game/game.h" -#include "game/planet.h" - - -namespace game { - -Planet::Planet() : core::EntityGlobe(core::Entity::Static | core::Entity::Solid) -{ - entity_color = math::Color(1,1,1,1); // white - entity_radius = 64; // 64 game units - - entity_moduletypeid = planet_enttype; - - entity_rotationspeed = 1.0f; -} - -Planet::~Planet() -{ -} - -} // namespace game diff --git a/src/game/planet.h b/src/game/planet.h deleted file mode 100644 index cc258c9..0000000 --- a/src/game/planet.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - game/planet.h - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#ifndef __INCLUDED_GAME_PLANET_H__ -#define __INCLUDED_GAME_PLANET_H__ - -#include "core/entity.h" -#include "math/mathlib.h" - -#include - -namespace game { - -/// a planet -class Planet : public core::EntityGlobe { -public: - Planet(); - ~Planet(); -}; - -} - -#endif // __INCLUDED_GAME_PLANET_H__ - diff --git a/src/game/racetrack.cc b/src/game/racetrack.cc deleted file mode 100644 index cfacb82..0000000 --- a/src/game/racetrack.cc +++ /dev/null @@ -1,195 +0,0 @@ -/* - game/racetrack.cc - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#include -#include - -#include "game/racetrack.h" -#include "core/gameserver.h" - -namespace game { - -/* ---- class CheckPoint ------------------------------------------- */ - -CheckPoint::CheckPoint(RaceTrack *parent) -{ - entity_eventstate = core::Entity::NoPower; - parent_track = parent; - if (parent) { - entity_color = parent->color(); - entity_color_second = parent->color_second(); - set_zone(parent->zone()); - parent->add_checkpoint(this); - } else { - die(); - } -} - -CheckPoint::~CheckPoint() -{ - -} - -/* ---- class RaceTrack -------------------------------------------- */ - -RaceTrack::RaceTrack() -{ - track_player = 0; - track_racestart = 0; - track_checkpointtime = 0; - - entity_eventstate = core::Entity::NoPower; -} - -RaceTrack::~RaceTrack() -{ - track_checkpoints.clear(); -} - -void RaceTrack::add_checkpoint(CheckPoint *checkpoint) -{ - track_checkpoints.push_back(checkpoint); -} - -void RaceTrack::reset() -{ - if (track_player) { - track_player->set_mission_target(0); - } - track_player = 0; - track_racestart = 0; - track_checkpointtime = 0; - - for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { - (*cpit)->set_eventstate(core::Entity::NoPower); - } - - set_eventstate(core::Entity::NoPower); -} - -void RaceTrack::frame(float seconds) -{ - if (!track_checkpoints.size()) - return; - - if (!track_player) { - - // FIXME this should go through proper collision detection - for (core::GameServer::Players::iterator it = core::server()->players().begin(); it != core::server()->players().end(); ++it) { - if ((*it)->control() && (*it)->control()->zone() == zone()) { - if (math::distance((*it)->control()->location(), location()) <= 1) { - track_player = (*it); - - track_racestart = core::server()->time(); - set_eventstate(core::Entity::Normal); - - for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { - set_eventstate(core::Entity::Normal); - } - - entity_timer = 5.0f; - std::string message("^B"); - message.append(track_player->name()); - message.append(" ^Bactivated the race! Race starts in 5..."); - core::server()->broadcast(message); - track_player->set_mission_target(this); - return; - } - } - } - - return; - } - - // FIXME this should go into a proper general function - // validate current player - core::Player *player = 0; - for (core::GameServer::Players::iterator pit = core::server()->players().begin(); (!player) && (pit != core::server()->players().end()); ++pit) { - if ((*pit) == track_player) { - player = (*pit); - } - } - - if (!player) { - reset(); - return; - } - - if (!player->control() || (player->control()->zone() != zone())) { - reset(); - return; - } - - if (entity_timer) { - - if (math::distance(player->control()->location(), location()) > 1) { - std::string message("^BNo cheating!"); - core::server()->broadcast(message); - reset(); - return; - } - - if (track_racestart + 1.0f <= core::server()->time()) { - entity_timer -= 1.0f; - entity_dirty = true; - - if (entity_timer > 0) { - std::stringstream msgstr; - msgstr << "^B" << entity_timer << "..."; - core::server()->broadcast(msgstr.str()); - track_racestart = core::server()->time(); - } else { - for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { - (*cpit)->set_eventstate(core::Entity::NoPower); - } - std::string message("^BGo!"); - core::server()->broadcast(message); - - track_racestart = core::server()->time(); - track_checkpointtime = core::server()->time() + 15.0f; - track_checkpoint = track_checkpoints.begin(); - (*track_checkpoint)->set_eventstate(core::Entity::Normal); - track_player->set_mission_target((*track_checkpoint)); - } - } - - - } else { - - if (core::server()->time() > track_checkpointtime) { - std::string message("^BToo slow, race lost!"); - core::server()->broadcast(message); - - reset(); - return; - } - - if (math::distance(track_player->control()->location(), (*track_checkpoint)->location()) <= 1) { - CheckPoints::iterator next_checkpoint = track_checkpoint; - next_checkpoint++; - - if (next_checkpoint != track_checkpoints.end()) { - - std::string message("^BCheckpoint!"); - core::server()->broadcast(message); - track_checkpointtime = core::server()->time() + 15.0f; - (*track_checkpoint)->set_eventstate(core::Entity::NoPower); - track_checkpoint++; - (*track_checkpoint)->set_eventstate(core::Entity::Normal); - track_player->set_mission_target((*track_checkpoint)); - - } else { - - std::stringstream msgstr; - msgstr << "^BRace completed in " << core::server()->time() - track_racestart << " seconds!"; - core::server()->broadcast(msgstr.str()); - reset(); - } - } - } -} - -} diff --git a/src/game/racetrack.h b/src/game/racetrack.h deleted file mode 100644 index 733051a..0000000 --- a/src/game/racetrack.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - game/racetrack.h - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#ifndef __INCLUDED_GAME_RACETRACK_H__ -#define __INCLUDED_GAME_RACETRACK_H__ - -#include "core/entity.h" -#include "core/player.h" -#include "math/mathlib.h" - -#include - -namespace game { - -class CheckPoint; - -/* ---- class RaceTrack -------------------------------------------- */ - -class RaceTrack : public core::EntityDynamic { - -public: - typedef std::list CheckPoints ; - - RaceTrack(); - ~RaceTrack(); - - void add_checkpoint(CheckPoint *checkpoint); - - /// reset the race track - void reset(); - - virtual void frame(float seconds); - - inline core::Player *player() { return track_player; } - -private: - CheckPoints track_checkpoints; - core::Player *track_player; - float track_racestart; - float track_checkpointtime; - CheckPoints::iterator track_checkpoint; - -}; - -/* ---- class CheckPoint ------------------------------------------- */ - -class CheckPoint : public core::EntityDynamic { -public: - CheckPoint(RaceTrack *parent); - ~CheckPoint(); - -private: - RaceTrack *parent_track; -}; - - -} - -#endif // __INCLUDED_GAME_NAVPOINT_H__ - diff --git a/src/game/ship.cc b/src/game/ship.cc deleted file mode 100644 index 1828172..0000000 --- a/src/game/ship.cc +++ /dev/null @@ -1,464 +0,0 @@ -/* - game/ship.cc - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#include -#include - -#include "auxiliary/functions.h" -#include "core/gameserver.h" -#include "core/entity.h" -#include "game/game.h" -#include "game/ship.h" -#include "math/functions.h" - - - -using math::degrees360f; -using math::degrees180f; - -namespace game { - -const float MIN_DELTA = 0.000001f; - -Ship::Ship(core::Player *owner, ShipModel *shipmodel) : - core::EntityControlable(owner, ship_enttype) -{ - entity_modelname = "ships/" + shipmodel->modelname(); - entity_name = shipmodel->name() + ": <^B" + owner->name() + "^N>"; - entity_label = shipmodel->label(); - - entity_moduletypeid = ship_enttype; - - entity_color = owner->color(); - entity_color_second = owner->color_second(); - - ship_shipmodel = shipmodel; - ship_jumpdrive = shipmodel->shipmodel_jumpdrive; - - ship_impulsedrive_timer = 0; - ship_jumpdrive_timer = 0; - - reset(); -} - -Ship::~Ship() -{ - -} - -void Ship::reset() -{ - current_target_direction = 0.0f; - current_target_pitch = 0.0f;; - current_target_roll = 0.0f; - current_target_strafe = 0.0f; - current_target_afterburner = 0.0f; -} -void Ship::impulse() -{ - if (entity_eventstate == core::Entity::Jump) { - return; - - } else if ((entity_eventstate == core::Entity::Impulse) || (entity_eventstate == core::Entity::ImpulseInitiate)) { - entity_eventstate = core::Entity::Normal; - - } else { - - if (entity_eventstate == core::Entity::JumpInitiate) { - ship_jumpdrive_timer = 0; - entity_timer = 0; - } - - entity_eventstate = core::Entity::ImpulseInitiate; - if (Game::instance()->g_devel->value()) { - entity_timer = 0; - } else { - entity_timer = 3; - } - ship_impulsedrive_timer = core::server()->time(); - entity_dirty = true; - } - - entity_dirty = true; -} - -void Ship::jump(std::string const &args) -{ - // devel mode provides instant jump access to arbitrary systems - if (Game::instance()->g_devel->value() && (args.size())) { - - core::Zone *jumptargetzone = 0; - std::string target; - std::istringstream is(args); - if (!(is >> target)) { - std::string helpstr; - for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { - core::Zone *zone = (*it).second; - if (helpstr.size()) - helpstr.append("^N|^B"); - helpstr.append(zone->label()); - } - - core::server()->send(owner(), "Usage: jump [^B" + helpstr + "^N]"); - return; - } - - aux::to_lowercase(target); - jumptargetzone = core::Zone::find_zone(target); - if (!jumptargetzone) { - core::server()->send(owner(), "Unknown system '" + target + '\''); - return; - } - - if (jumptargetzone == zone()) { - core::server()->send(owner(), "Already in the " + jumptargetzone->name() + '.'); - return; - } - - core::server()->send(owner(), "Jumping to the " + jumptargetzone->name()); - set_zone(jumptargetzone); - if (owner()->control() == (EntityControlable*) this) - owner()->set_zone(jumptargetzone); - - ship_jumpdrive_timer = 0; - entity_timer = 0; - entity_eventstate = core::Entity::Jump; - entity_dirty = true; - return; - - } else { - if (!jumpdrive() && !Game::instance()->g_devel->value()) { - core::server()->send(owner(), "This ship is not equiped with a hyperspace drive!"); - return; - - } else if (entity_eventstate == core::Entity::Jump) { - return; - - } else if (entity_eventstate == core::Entity::JumpInitiate) { - core::server()->send(owner(), "Jump aborted, hyperspace drive deactivated."); - ship_jumpdrive_timer = 0; - entity_timer = 0; - entity_eventstate = core::Entity::Normal; - return; - } - - if (!find_closest_jumppoint()) { - return; - } - - entity_eventstate = core::Entity::JumpInitiate; - if (Game::instance()->g_devel->value()) { - entity_timer = 0; - } else { - entity_timer = 8; - } - - ship_jumpdrive_timer = core::server()->time(); - entity_dirty = true; - } -} - -JumpPoint * Ship::find_closest_jumppoint() -{ - // find closest jumppoint - float d = -1; - JumpPoint *jumppoint = 0; - for (core::Zone::Content::iterator it = zone()->content().begin(); it != zone()->content().end(); it++) { - core::Entity *entity = (*it); - if (entity->moduletype() == jumppoint_enttype) { - JumpPoint *te = static_cast(entity); - float d1 = math::distance(location(), te->location()); - if ((d < 0) || (d1 < d)) { - d = d1; - jumppoint = te; - } - } - } - - if (jumppoint && jumppoint->target()) { - if (Game::instance()->g_jumppointrange->value() < d) { - core::server()->send(owner(), "Jumppoint out of range!"); - return 0; - } else { - core::server()->send(owner(), "Jumping to the " + jumppoint->target()->zone()->name()); - return jumppoint; - } - } else { - core::server()->send(owner(), "No jumppoints found!"); - return 0; - } - - return 0; -} - -void Ship::frame(float seconds) -{ - const float direction_change_speed = 2; - float cosangle; // cosine of an angle - float angle; // angle in radians - math::Vector3f n; // normal of a plane - - float actual_maxspeed = ship_shipmodel->maxspeed(); - float actual_turnspeed = ship_shipmodel->turnspeed(); - float actual_acceleration = ship_shipmodel->acceleration(); - - entity_movement = 0; - - // speed might get set to 0 on this update - if (entity_speed != 0.0f) - entity_dirty = true; - - // jumpdrive - // target axis - math::Axis target_axis(entity_axis); - - if (entity_eventstate == core::Entity::JumpInitiate) { - - if (ship_jumpdrive_timer + 1.0f <= core::server()->time()) { - entity_timer -= 1.0f; - - if (entity_timer <= 0) { - JumpPoint *jumppoint = find_closest_jumppoint(); - - if (jumppoint) { - set_zone(jumppoint->target()->zone()); - if (owner()->control() == (EntityControlable*) this) - owner()->set_zone(jumppoint->target()->zone()); - entity_eventstate = core::Entity::Jump; - entity_location.assign(jumppoint->target()->location() + location() - jumppoint->location()); - } else { - entity_eventstate = core::Entity::Normal; - } - ship_jumpdrive_timer = 0; - entity_timer = 0; - - entity_dirty = true; - return; - } else { - ship_jumpdrive_timer = core::server()->time(); - entity_dirty = true; - } - } - - // control is disabled while the jumpdrive is activated - target_thrust = 0; - target_pitch = 0; - target_roll = 0; - target_direction = 0; - target_afterburner = 0.0f; - target_thrust = 0; - - } else if (entity_eventstate == core::Entity::Jump) { - // control is disabled while the jumpdrive is activated - target_thrust = 0; - target_pitch = 0; - target_roll = 0; - target_direction = 0; - target_afterburner = 0.0f; - target_thrust = 0; - - // FIXME jump location and axis - math::Axis default_axis; - entity_axis.assign(default_axis); - entity_dirty = true; - - // FIXME 5 second cooldown - entity_eventstate = core::Entity::Normal; - - } else if (entity_eventstate == core::Entity::ImpulseInitiate) { - - if (ship_impulsedrive_timer + 1.0f <= core::server()->time()) { - entity_timer -= 1.0f; - - if (entity_timer <= 0) { - actual_maxspeed = Game::instance()->g_impulsespeed->value(); - actual_acceleration = Game::instance()->g_impulseacceleration->value(); - entity_eventstate = core::Entity::Impulse; - entity_timer = 0; - entity_dirty = true; - } else { - ship_impulsedrive_timer = core::server()->time(); - entity_dirty = true; - } - } - - // clamp input values - target_thrust = 0.0f; - math::clamp(target_pitch, -1.0f, 1.0f); - math::clamp(target_roll, -1.0f, 1.0f); - math::clamp(target_direction, -1.0f, 1.0f); - math::clamp(target_afterburner, -1.0f, 1.0f); - actual_turnspeed *= 0.5; - - } else if (entity_eventstate == core::Entity::Impulse) { - - // clamp input values - target_thrust = 0.0f; - math::clamp(target_pitch, -1.0f, 1.0f); - math::clamp(target_roll, -1.0f, 1.0f); - math::clamp(target_direction, -1.0f, 1.0f); - target_afterburner = 0.0f; - actual_maxspeed = Game::instance()->g_impulsespeed->value(); - actual_acceleration = Game::instance()->g_impulseacceleration->value(); - actual_turnspeed *= 0.5; - - } else if (entity_eventstate == core::Entity::Normal) { - - // clamp input values - math::clamp(target_thrust, 0.0f, 1.0f); - math::clamp(target_pitch, -1.0f, 1.0f); - math::clamp(target_roll, -1.0f, 1.0f); - math::clamp(target_direction, -1.0f, 1.0f); - math::clamp(target_afterburner, -1.0f, 1.0f); - - if (speed() > actual_maxspeed * 1.15f) { - actual_acceleration = Game::instance()->g_impulseacceleration->value(); - actual_turnspeed *= 0.5; - } - - } - - // update roll - if (current_target_roll < target_roll) { - current_target_roll += direction_change_speed * seconds; - if (current_target_roll > target_roll) - current_target_roll = target_roll; - } else if (current_target_roll > target_roll) { - current_target_roll -= direction_change_speed * seconds; - if (current_target_roll < target_roll) - current_target_roll = target_roll; - } - math::clamp(current_target_roll, -1.0f, 1.0f); - - if (fabs(current_target_roll) > MIN_DELTA) { - float roll_offset = seconds * current_target_roll; - entity_axis.change_roll(actual_turnspeed * roll_offset); - } else { - current_target_roll = 0.0f; - } - - // update target_axis direction - if (current_target_direction < target_direction) { - current_target_direction += direction_change_speed * seconds; - if (current_target_direction > target_direction) { - current_target_direction = target_direction; - } - } else if (current_target_direction > target_direction) { - current_target_direction -= direction_change_speed * seconds; - if (current_target_direction < target_direction) { - current_target_direction = target_direction; - } - } - - if (fabs(current_target_direction) > MIN_DELTA ) { - math::clamp(current_target_direction, -1.0f, 1.0f); - target_axis.change_direction(actual_turnspeed * current_target_direction); - } else { - current_target_direction = 0.0f; - } - - if (current_target_pitch < target_pitch) { - current_target_pitch += direction_change_speed * seconds; - if (current_target_pitch > target_pitch) - current_target_pitch = target_pitch; - } else if (current_target_pitch > target_pitch) { - current_target_pitch -= direction_change_speed * seconds; - if (current_target_pitch < target_pitch) - current_target_pitch = target_pitch; - } - - if (fabs(current_target_pitch) > MIN_DELTA) { - math::clamp(current_target_pitch, -1.0f, 1.0f); - target_axis.change_pitch(actual_turnspeed * current_target_pitch); - } else { - current_target_pitch = 0.0f; - } - - n.assign(math::crossproduct(entity_axis.forward(), target_axis.forward())); - if (!(n.length() < MIN_DELTA)) { - n.normalize(); - cosangle = math::dotproduct(entity_axis.forward(), target_axis.forward()); - angle = acos(cosangle) * seconds; // * 180.0f / M_PI; - if (angle > MIN_DELTA) - entity_axis.rotate(n, -angle); - } - - // update afterburner - if (current_target_afterburner < target_afterburner) { - current_target_afterburner += 2.0f * seconds; - if (current_target_afterburner > target_afterburner) - current_target_afterburner = target_afterburner; - } else if (current_target_afterburner > target_afterburner) { - current_target_afterburner -= 2.0f * seconds; - if (current_target_afterburner < target_afterburner) - current_target_afterburner = target_afterburner; - } - - // update thrust - if (current_target_afterburner < 0.0f) { - target_thrust = 0; - } - - if (entity_thrust < target_thrust) { - entity_thrust += seconds * 0.5f; - if (entity_thrust > target_thrust) - entity_thrust = target_thrust; - } else if (entity_thrust > target_thrust) { - entity_thrust -= seconds * 0.5f; - if (entity_thrust < target_thrust) - entity_thrust = target_thrust; - } - math::clamp(entity_thrust, 0.0f, 1.0f); - float actual_thrust = entity_thrust + current_target_afterburner * 0.15f; - - if ((entity_eventstate == core::Entity::ImpulseInitiate) || (entity_eventstate == core::Entity::Impulse)) { - actual_thrust = 1.0f; - } - - // update speed - if (entity_speed < actual_thrust * actual_maxspeed) { - entity_speed += actual_acceleration * seconds; - if (entity_speed > actual_thrust * actual_maxspeed) { - entity_speed = actual_thrust * actual_maxspeed; - } - } else if(entity_speed > actual_thrust * actual_maxspeed) { - entity_speed -= actual_acceleration * seconds; - if (entity_speed < actual_thrust * actual_maxspeed) { - entity_speed = actual_thrust * actual_maxspeed; - } - } - - // update strafe - if (current_target_strafe < target_strafe) { - current_target_strafe += 2.0f * seconds; - if (current_target_strafe > target_strafe) - current_target_strafe = target_strafe; - } else if (current_target_strafe > target_strafe) { - current_target_strafe -= 2.0f * seconds; - if (current_target_strafe < target_strafe) - current_target_strafe = target_strafe; - } - - if (fabs(current_target_strafe) > MIN_DELTA) { - entity_location += entity_axis.left() * (current_target_strafe * Game::instance()->g_strafespeed->value()); - } - - entity_movement = target_thrust; - entity_movement = math::max(entity_movement, fabs(current_target_pitch)); - entity_movement = math::max(entity_movement, fabs(current_target_direction)); - entity_movement = math::max(entity_movement, fabs(current_target_roll)); - entity_movement = math::max(entity_movement, fabs(current_target_afterburner)); - entity_movement = math::max(entity_movement, fabs(current_target_strafe)); - - if (entity_speed) { - entity_location += entity_axis.forward() * entity_speed * seconds; - entity_dirty = true; - } else if (entity_movement > 0.0f) { - entity_dirty = true; - } -} - -} // namespace game diff --git a/src/game/ship.h b/src/game/ship.h deleted file mode 100644 index 3a62a9d..0000000 --- a/src/game/ship.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - game/ship.h - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#ifndef __INCLUDED_GAME_SHIP_H__ -#define __INCLUDED_GAME_SHIP_H__ - -#include "core/player.h" -#include "core/entity.h" -#include "game/shipmodel.h" -#include "game/jumppoint.h" -#include "math/vector3f.h" - -namespace game { - -/// A ship in the game, controled by a player -class Ship : public core::EntityControlable -{ -public: - Ship(core::Player *owner, ShipModel *shipmodel); - ~Ship(); - - /// update the ship state - virtual void frame(float seconds); - - /// true if the ship is equiped with a jumpdrive - inline bool jumpdrive() const { return ship_jumpdrive; } - - /// toggle jump drive activation - void jump(std::string const & args); - - /// toggle impulse drive activation - void impulse(); - - /// void reset drive controls - void reset(); - -private: - ShipModel *ship_shipmodel; - - float current_target_direction; - float current_target_pitch; - float current_target_roll; - float current_target_strafe; - float current_target_afterburner; - - bool ship_jumpdrive; - float ship_jumpdrive_timer; - - float ship_impulsedrive_timer; - - JumpPoint * find_closest_jumppoint(); -}; - -} - -#endif // __INCLUDED_GAME_SHIP_H__ - diff --git a/src/game/shipmodel.cc b/src/game/shipmodel.cc deleted file mode 100644 index 8ff182f..0000000 --- a/src/game/shipmodel.cc +++ /dev/null @@ -1,72 +0,0 @@ -/* - game/shipmodel.cc - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#include "sys/sys.h" -#include "game/shipmodel.h" - -namespace game { - -// the ship model registry -std::map ShipModel::registry; - -ShipModel::ShipModel() -{ - //default specifications - shipmodel_acceleration = 1.0f; // thruster acceleration in game untits/second^2 - shipmodel_maxspeed = 3.0f; // maximum thruster speed in game units/second - shipmodel_turnspeed = 45.0f; // 45 degrees per second - - shipmodel_jumpdrive = false; -} - -ShipModel::~ShipModel() -{} - - -// clear the ship model registry -void ShipModel::clear() -{ - for (iterator smit = registry.begin(); smit != registry.end(); smit++) { - delete (*smit).second; - } - registry.clear(); -} - -void ShipModel::list() -{ - for (iterator smit = registry.begin(); smit != registry.end(); smit++) { - con_print << - " " << (*smit).second->label() << - " " << (*smit).second->name() << - " accel " << (*smit).second->acceleration() << - " max " << (*smit).second->maxspeed() << - " turn " << (*smit).second->turnspeed() << "\n"; - } - con_print << registry.size() << " registered ship models\n"; -} - -ShipModel *ShipModel::find(const std::string label) -{ - std::map::iterator it = registry.find(label); - if (it == registry.end()) - return 0; - else - return (*it).second; -} - -// add a new ship model -void ShipModel::add(ShipModel *shipmodel) -{ - ShipModel *m = find(shipmodel->label()); - if (m) { - con_warn << "Duplicate ship model " << shipmodel->label() << "!\n"; - delete m; - } - - registry[shipmodel->label()] = shipmodel; -} - -} diff --git a/src/game/shipmodel.h b/src/game/shipmodel.h deleted file mode 100644 index a29f860..0000000 --- a/src/game/shipmodel.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - game/shipmodel.h - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#ifndef __INCLUDED_GAME_SHIPMODEL_H__ -#define __INCLUDED_GAME_SHIPMODEL_H__ - -#include -#include - -namespace game { - -/// ship model specifications -class ShipModel -{ -public: - ShipModel(); - ~ShipModel(); - - /// acceleration - inline float acceleration() const { return shipmodel_acceleration; } - - /// maximum speed - inline float maxspeed() const { return shipmodel_maxspeed; } - - /// turn speed in rotations per second - inline float turnspeed() const { return shipmodel_turnspeed; } - - /// label of the ship model - inline std::string const &label() const { return shipmodel_label; } - - /// name of the ship model - inline std::string const & name() const { return shipmodel_name; } - - /// name of the model of the ship - inline std::string const & modelname() const { return shipmodel_modelname; } - - float shipmodel_acceleration; - float shipmodel_maxspeed; - float shipmodel_turnspeed; - std::string shipmodel_label; - std::string shipmodel_name; - std::string shipmodel_modelname; - - /// indicates of this model can be equiped with a jump drive - bool shipmodel_jumpdrive; - - static ShipModel *find(const std::string label); - - /// the ship model registry - static std::map registry; - - typedef std::map::iterator iterator; - - /// clear the ship model registry - static void clear(); - - /// list the ship model registry - static void list(); - - /// add a new ship model - static void add(ShipModel *shipmodel); -}; - -} - -#endif // __INCLUDED_GAME_SHIPMODEL_H__ - diff --git a/src/game/star.cc b/src/game/star.cc deleted file mode 100644 index fd0c57b..0000000 --- a/src/game/star.cc +++ /dev/null @@ -1,25 +0,0 @@ -/* - game/star.cc - This file is part of the Osirion project and is distributed under - the terms of the GNU General Public License version 2. -*/ - -#include "game/game.h" -#include "game/star.h" - - -namespace game { - -Star::Star() : core::EntityGlobe(core::Entity::Static | core::Entity::Solid | core::Entity::Bright) -{ - entity_color = math::Color(1,1,1,1); // white - entity_radius = 96; // 96 game units - - entity_moduletypeid = star_enttype; -} - -Star::~Star() -{ -} - -} // namespace game diff --git a/src/game/star.h b/src/game/star.h deleted file mode 100644 index ecc7ade..0000000 --- a/src/game/star.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - game/star.h - This file is part of the Osirion project and is distributed under - the terms and conditions of the GNU General Public License version 2 -*/ - -#ifndef __INCLUDED_GAME_STAR_H__ -#define __INCLUDED_GAME_STAR_H__ - -// project headers -#include "core/entity.h" -#include "math/mathlib.h" - -// C++ headers -#include - -namespace game { - -/// a star, that shines so bright -class Star : public core::EntityGlobe { -public: - Star(); - ~Star(); -}; - -} - -#endif // __INCLUDED_GAME_STAR_H__ - diff --git a/src/osirion.cc b/src/osirion.cc index 2f0a5eb..71bd1ec 100644 --- a/src/osirion.cc +++ b/src/osirion.cc @@ -9,14 +9,11 @@ int main(int count, char **arguments) { - // preload the game module - core::Module::load(new game::Game()); + // load the game modules + game::register_modules(true); client::client_main(count, arguments); - // unload the game module - core::Module::unload(); - return 0; } diff --git a/src/osiriond.cc b/src/osiriond.cc index 0e8f6f7..bd88df0 100644 --- a/src/osiriond.cc +++ b/src/osiriond.cc @@ -10,12 +10,9 @@ int main(int count, char **arguments) { // preload the game module - core::Module::load(new game::Game()); + game::register_modules(false); server::main(count, arguments); - // unload the game module - core::Module::unload(); - return 0; } -- cgit v1.2.3