From a1eb1b4dc4d81df724ee43fc4e895dd22e81760f Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 9 Nov 2008 21:45:18 +0000 Subject: working jumpgates --- src/game/base/Makefile.am | 4 +- src/game/base/base.cc | 770 -------------------------------------------- src/game/base/base.h | 103 ------ src/game/base/game.cc | 774 +++++++++++++++++++++++++++++++++++++++++++++ src/game/base/game.h | 104 ++++++ src/game/base/jumppoint.cc | 84 ++++- src/game/base/jumppoint.h | 30 +- src/game/base/navpoint.cc | 4 +- src/game/base/navpoint.h | 2 +- src/game/base/planet.cc | 4 +- src/game/base/planet.h | 2 +- src/game/base/racetrack.cc | 4 +- src/game/base/racetrack.h | 2 +- src/game/base/ship.cc | 101 +++--- src/game/base/ship.h | 22 +- src/game/base/shipmodel.cc | 2 +- src/game/base/shipmodel.h | 2 +- src/game/base/star.cc | 4 +- src/game/base/star.h | 2 +- src/game/game.cc | 16 +- src/game/game.h | 5 +- 21 files changed, 1083 insertions(+), 958 deletions(-) delete mode 100644 src/game/base/base.cc delete mode 100644 src/game/base/base.h create mode 100644 src/game/base/game.cc create mode 100644 src/game/base/game.h (limited to 'src/game') diff --git a/src/game/base/Makefile.am b/src/game/base/Makefile.am index a8258b2..1b80e72 100644 --- a/src/game/base/Makefile.am +++ b/src/game/base/Makefile.am @@ -2,7 +2,7 @@ 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 \ +libbase_la_SOURCES = game.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 \ +noinst_HEADERS = game.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 deleted file mode 100644 index 58b89a2..0000000 --- a/src/game/base/base.cc +++ /dev/null @@ -1,770 +0,0 @@ -/* - 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 - -#include "auxiliary/functions.h" -#include "core/gameserver.h" -#include "core/parser.h" -#include "core/descriptions.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 -{ - -/* -- class Base static members ----------------------------------- */ - -// game variables -core::Cvar *Base::g_impulsespeed = 0; -core::Cvar *Base::g_impulseacceleration = 0; -core::Cvar *Base::g_strafespeed = 0; -core::Cvar *Base::g_jumppointrange = 0; -core::Cvar *Base::g_devel = 0; - -core::Zone *Base::default_zone = 0; -ShipModel *Base::default_shipmodel = 0; - -// list the ship model registry -void Base::func_list_ship(std::string const &args) -{ - ShipModel::list(); -} - -// a player joins the game -void Base::func_join(core::Player *player, std::string const &args) -{ - if (player->control()) - return; - - Ship *ship = new Ship(player, Base::default_shipmodel); - ship->set_zone(player->zone()); - player->set_control(ship); - - core::Entity *dock = ship->zone()->default_view(); - if (dock) { - ship->entity_location.assign(dock->location() + (dock->axis().forward() * ((ship->radius()+ dock->radius())*2.0f))); - ship->entity_axis.assign(dock->axis()); - ship->set_eventstate(core::Entity::Docked); - player->set_view(dock); - } - - std::string message("^B"); - message.append(player->name()); - message.append("^B joins the game."); - core::server()->broadcast(message); - - player->send("^BYou received " + aux::article(Base::default_shipmodel->name())); - player->sound("game/buy-ship"); - - player->player_dirty = true; -} - -// a player joins the spectators -void Base::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()); - } - - if (!player->zone()) - player->set_zone(Base::default_zone); - - player->set_view(0); -} - -// a player buys a ship -void Base::func_buy(core::Player *player, std::string const &args) -{ - if (!g_devel->value() && !player->view()) { - player->send("Cheats disabled."); - return; - } - - // FIXME verify the base sells this ship - - 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()); - } - - core::Entity *dock = player->view(); - Ship * ship = new Ship(player, shipmodel); - ship->set_zone(player->zone()); - player->set_control(ship); - - if (dock) { - player->control()->location().assign(dock->location()); - player->control()->set_eventstate(core::Entity::Docked); - ship->entity_axis.assign(dock->axis()); - ship->entity_axis.change_direction(180.0f); - player->set_view(dock); - } - - player->send("^BPurchased " + aux::article(shipmodel->name())); - player->sound("game/buy-ship"); - - } else { - player->send("Usage: buy [^B" + helpstr + "^N]"); - } -} - -// a player sends standard hails -void Base::func_hail(core::Player *player, std::string const &args) -{ - if (player->mute()) { - player->send("You have been muted."); - return; - } - - std::string target; - std::istringstream is(args); - if (!(is >> target)) { - player->send("Usage: hail [player]"); - return; - } - - core::Player *targetplayer = core::server()->find_player(target); - if (!targetplayer) { - player->send("Player " + target + "^N not found."); - return; - } - - player->send("^BYou hail " + targetplayer->name() + "^B."); - player->sound("com/hail"); - - targetplayer->send("^B" + player->name() + "^B hails you!"); - targetplayer->sound("com/hail"); -} - -// a player actives the hyperspace jump drive on his ship -void Base::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 Base::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(); -} - -// a player sends a docking request -void Base::func_dock(core::Player *player,core::Entity *entity) -{ - if (!player->control()) - return; - - if (player->control()->zone() != entity->zone()) - return; - - if ((entity->flags() & core::Entity::Dockable) == 0) - return; - - if (player->control()->eventstate() == core::Entity::Docked) - return; - - if (math::distance(entity->location(), player->control()->location()) > 2.0f * (entity->radius() + player->control()->radius())) { - player->send("Target out of range!"); - return; - } - - player->control()->location().assign(entity->location()); - player->control()->set_eventstate(core::Entity::Docked); - player->set_view(entity); - player->send("^BDocking at " + entity->name() + "^B..."); -} - -// launch request -void Base::func_launch(core::Player *player, std::string const &args) -{ - if (!player->control()) - return; - - if (!player->view()) - return; - - if (player->control()->eventstate() != core::Entity::Docked) - return; - - assert(player->view()->zone() == player->control()->zone()); - - core::Entity *dock = player->view(); - player->control()->entity_location.assign(dock->location() + (dock->axis().forward() * (player->control()->radius()+ dock->radius())*2.0f)); - player->control()->entity_axis.assign(dock->axis()); - player->control()->set_eventstate(core::Entity::Normal); - player->set_view(0); -} - -// instantaniously goto a specified entity within the zone -void Base::func_goto(core::Player *player, const std::string &args) -{ - if (!args.size()) - return; - - if (!g_devel->value()) { - player->send("Cheats disabled."); - return; - } - - if (!player->control()) - return; - - std::string label(args); - aux::to_label(label); - - core::Zone *zone = player->control()->zone(); - for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it ++) { - core::Entity *dock = (*it); - std::string str(dock->label()); - aux::to_label(str); - if (str.find(label) != std::string::npos) { - player->control()->entity_location.assign(dock->location() + (dock->axis().forward() * (player->control()->radius()+dock->radius())*2.0f)); - player->control()->entity_axis.assign(dock->axis()); - player->control()->entity_axis.change_direction(180.0f); - player->control()->set_eventstate(core::Entity::Normal); - player->set_view(0); - return; - } - } - player->send("Entity '" + args + "' not found."); -} - -/* -- class Base -------------------------------------------------- */ - -Base::Base() : core::Module("base", "Project::OSiRiON", true) -{ - default_shipmodel = 0; - default_zone = 0; -} - -Base::~Base() -{ -} - -void Base::init() -{ - ShipModel::clear(); - - if (!load_world()) { - abort(); - return; - } - - if (!load_ships()) { - abort(); - return; - } - - // add engine functions - core::Func *func = 0; - - func = core::Func::add("list_ship", Base::func_list_ship); - func->set_info("list ship statistics"); - - func = core::Func::add("join", Base::func_join); - func->set_info("join the game"); - - func = core::Func::add("hail", Base::func_hail); - func->set_info("send a standard hail"); - - func = core::Func::add("spectate", Base::func_spectate); - func->set_info("leave the game and spectate"); - - func = core::Func::add("buy", Base::func_buy); - func->set_info("buy a ship"); - - func = core::Func::add("jump", Base::func_jump); - func->set_info("[string] activate or deactivate hyperspace jump drive"); - - func = core::Func::add("impulse", Base::func_impulse); - func->set_info("activate are deactive kinetic impulse drive"); - - func = core::Func::add("launch", Base::func_launch); - func->set_info("launch to space when docked"); - - func = core::Func::add("goto", Base::func_goto); - func->set_info("[string] goto to an entity within the zone"); - - func = core::Func::add("@dock", Base::func_dock); - func->set_info("dock with target object"); - - // add engine variables - 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.01", 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"); -} - -void Base::shutdown() -{ - g_impulsespeed = 0; - // game functions are automaticly removed - - // remove engine core functions - core::Func::remove("list_ship"); - - ShipModel::clear(); -} - -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; - } - - con_print << "^BLoading world..." << std::endl; - - core::Zone *zone = 0; - std::string label; - - while (worldini.getline()) { - - if (worldini.got_section()) { - - if (worldini.got_section("world")) { - continue; - } else { - worldini.unknown_section(); - } - - } else if (worldini.got_key()) { - - if (worldini.in_section("world")) { - - if (worldini.got_key_string("zone", label)) { - aux::to_label(label); - zone = new core::Zone(label); - core::Zone::add(zone); - } else { - worldini.unkown_key(); - } - } - } - } - - 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::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; - } - - con_print << "^BLoading zone " << zone->label() << "..." << std::endl; - - 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_section()) { - 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->set_flag(core::Entity::Static); - entity->set_zone(zone); - count ++; - - } else { - zoneini.unknown_section(); - } - - } else if (zoneini.got_key()) { - - if (zoneini.in_section("zone")) { - 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 { - zoneini.unkown_key(); - } - - } else if (zoneini.in_section("star")) { - if (core::Parser::got_entity_key(zoneini, star)) { - continue; - } else if (zoneini.got_key_string("texture", star->entity_texture)) { - continue; - } else { - zoneini.unkown_key(); - } - - } else if (zoneini.in_section("navpoint")) { - if (core::Parser::got_entity_key(zoneini, navpoint)) { - continue; - } else { - zoneini.unkown_key(); - } - - } else if (zoneini.in_section("jumppoint")) { - if (core::Parser::got_entity_key(zoneini, jumppoint)) { - continue; - } else if (zoneini.got_key_string("target", jumppoint->jumppoint_targetlabel)) { - continue; - } else { - zoneini.unkown_key(); - } - - } else if (zoneini.in_section("planet")) { - if (core::Parser::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 if (zoneini.got_key_bool("dock", b)) { - if (b) { - planet->set_flag(core::Entity::Dockable); - core::Descriptions::load_entity_menus(planet, "zones/" + zone->label() + "/" + planet->label()); - } else { - planet->unset_flag(core::Entity::Dockable); - } - } else if (zoneini.got_key_bool("default", b)) { - if (b) { - zone->set_default_view(planet); - } - continue; - } else { - zoneini.unkown_key(); - } - - } else if (zoneini.in_section("racetrack")) { - if (core::Parser::got_entity_key(zoneini, racetrack)) { - continue; - } else { - zoneini.unkown_key(); - } - - } else if (zoneini.in_section("checkpoint")) { - if (core::Parser::got_entity_key(zoneini, checkpoint)) { - continue; - } else { - zoneini.unkown_key(); - } - - } else if (zoneini.in_section("entity")) { - if (core::Parser::got_entity_key(zoneini, entity)) { - continue; - } else if (zoneini.got_key_bool("default", b)) { - if (b) { - zone->set_default_view(entity); - } - } else if (zoneini.got_key_bool("dock", b)) { - if (b) { - entity->set_flag(core::Entity::Dockable); - core::Descriptions::load_entity_menus(entity, "zones/" + zone->label() + "/" + entity->label()); - } else { - entity->unset_flag(core::Entity::Dockable); - } - } else { - zoneini.unkown_key(); - } - } - - } - } - 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); - player->set_view(0); // not docked - - 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 deleted file mode 100644 index 926060c..0000000 --- a/src/game/base/base.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - base/base.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/shipmodel.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 contains 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; -const unsigned int jumpgate_enttype = 261; - -/// the base Project::OSiRiON game model -class Base : public core::Module { -public: - Base(); - ~Base(); - - /// 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); - - /* --- game variables -------------------------------------- */ - - /// game variable: speed of the impulse drive - static core::Cvar *g_impulsespeed; - - /// game variable: acceleration of the impulse drive - static core::Cvar *g_impulseacceleration; - - /// game variable strafe speed - static core::Cvar *g_strafespeed; - - /// game variable: jumppoint range - static core::Cvar *g_jumppointrange; - - /// game variable: enable or disable development mode - static core::Cvar *g_devel; - -protected: - /// initialize the game - void init(); - - /// shutdown the game - void shutdown(); - -private: - - bool load_world(); - - bool load_zone(core::Zone *zone); - - bool validate_zone(core::Zone *zone); - - bool load_ships(); - - static core::Zone *default_zone; - static ShipModel *default_shipmodel; - - /* ---- engine functions ----------------------------------- */ - - static void func_list_ship(std::string const &args); - static void func_join(core::Player *player, std::string const &args); - static void func_spectate(core::Player *player, std::string const &args); - static void func_buy(core::Player *player, std::string const &args); - static void func_hail(core::Player *player, std::string const &args); - static void func_jump(core::Player *player, std::string const &args); - static void func_impulse(core::Player *player, std::string const &args); - static void func_dock(core::Player *player,core::Entity *entity); - static void func_launch(core::Player *player, std::string const &args); - static void func_goto(core::Player *player, const std::string &args); -}; - -} - -#endif // __INCLUDED_BASE_H__ - diff --git a/src/game/base/game.cc b/src/game/base/game.cc new file mode 100644 index 0000000..d20dd8c --- /dev/null +++ b/src/game/base/game.cc @@ -0,0 +1,774 @@ +/* + base/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 + +#include "auxiliary/functions.h" +#include "core/gameserver.h" +#include "core/parser.h" +#include "core/descriptions.h" +#include "filesystem/filesystem.h" +#include "filesystem/inifile.h" +#include "base/game.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 game +{ + +/* -- class Base static members ----------------------------------- */ + +// game variables +core::Cvar *Game::g_impulsespeed = 0; +core::Cvar *Game::g_impulseacceleration = 0; +core::Cvar *Game::g_strafespeed = 0; +core::Cvar *Game::g_jumppointrange = 0; +core::Cvar *Game::g_devel = 0; + +core::Zone *Game::default_zone = 0; +ShipModel *Game::default_shipmodel = 0; + +// list the ship model registry +void Game::func_list_ship(std::string const &args) +{ + ShipModel::list(); +} + +// a player joins the game +void Game::func_join(core::Player *player, std::string const &args) +{ + if (player->control()) + return; + + Ship *ship = new Ship(player, Game::default_shipmodel); + ship->set_zone(player->zone()); + player->set_control(ship); + + core::Entity *dock = ship->zone()->default_view(); + if (dock) { + ship->entity_location.assign(dock->location() + (dock->axis().forward() * ((ship->radius()+ dock->radius())*2.0f))); + ship->entity_axis.assign(dock->axis()); + ship->set_eventstate(core::Entity::Docked); + player->set_view(dock); + } + + std::string message("^B"); + message.append(player->name()); + message.append("^B joins the game."); + core::server()->broadcast(message); + + player->send("^BYou received " + aux::article(Game::default_shipmodel->name())); + player->sound("game/buy-ship"); + + player->player_dirty = true; +} + +// a player joins the spectators +void Game::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()); + } + + if (!player->zone()) + player->set_zone(Game::default_zone); + + player->set_view(0); +} + +// a player buys a ship +void Game::func_buy(core::Player *player, std::string const &args) +{ + if (!g_devel->value() && !player->view()) { + player->send("Cheats disabled."); + return; + } + + // FIXME verify the base sells this ship + + 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()); + } + + core::Entity *dock = player->view(); + Ship * ship = new Ship(player, shipmodel); + ship->set_zone(player->zone()); + player->set_control(ship); + + if (dock) { + player->control()->location().assign(dock->location()); + player->control()->set_eventstate(core::Entity::Docked); + ship->entity_axis.assign(dock->axis()); + ship->entity_axis.change_direction(180.0f); + player->set_view(dock); + } + + player->send("^BPurchased " + aux::article(shipmodel->name())); + player->sound("game/buy-ship"); + + } else { + player->send("Usage: buy [^B" + helpstr + "^N]"); + } +} + +// a player sends standard hails +void Game::func_hail(core::Player *player, std::string const &args) +{ + if (player->mute()) { + player->send("^WYou have been muted"); + return; + } + + std::string target; + std::istringstream is(args); + if (!(is >> target)) { + player->send("Usage: hail [player]"); + return; + } + + core::Player *targetplayer = core::server()->find_player(target); + if (!targetplayer) { + player->send("Player " + target + "^N not found"); + return; + } + + player->send("^BYou hail " + targetplayer->name()); + player->sound("com/hail"); + + targetplayer->send("^B" + player->name() + "^B hails you"); + targetplayer->sound("com/hail"); +} + +// a player actives the hyperspace jump drive on his ship +void Game::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->func_jump(args); +} + +// a player actives the kinetic impulse drive on his ship +void Game::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->func_impulse(); +} + +// a player sends a docking request +void Game::func_dock(core::Player *player,core::Entity *entity) +{ + if (!player->control()) + return; + + if (player->control()->zone() != entity->zone()) + return; + + if ((entity->flags() & core::Entity::Dockable) == 0) + return; + + if (player->control()->eventstate() == core::Entity::Docked) + return; + + if (math::distance(entity->location(), player->control()->location()) > 2.0f * (entity->radius()+player->control()->radius())) { + player->send("Target out of range"); + return; + } + + if (entity->moduletype() == jumpgate_enttype) { + JumpGate *jumpgate = static_cast(entity); + if (jumpgate->target()) { + if (jumpgate->activated()) { + player->send("Jumpgate in use"); + return; + } + player->set_view(jumpgate); + Ship * ship = static_cast(player->control()); + ship->initiate_jump(jumpgate); + jumpgate->activate(); + if (jumpgate->target()->moduletype() == jumpgate_enttype) { + static_cast(jumpgate->target())->activate(); + } + } else { + player->send("Jumpgate inactive."); + } + } else { + + player->control()->location().assign(entity->location()); + player->control()->set_eventstate(core::Entity::Docked); + player->set_view(entity); + player->send("^BDocking at " + entity->name()); + } +} + +// launch request +void Game::func_launch(core::Player *player, std::string const &args) +{ + if (!player->control()) + return; + + if (!player->view()) + return; + + if (player->control()->eventstate() != core::Entity::Docked) + return; + + assert(player->view()->zone() == player->control()->zone()); + + core::Entity *dock = player->view(); + player->control()->entity_location.assign(dock->location() + (dock->axis().forward() * (player->control()->radius()+ dock->radius())*2.0f)); + player->control()->entity_axis.assign(dock->axis()); + player->control()->set_eventstate(core::Entity::Normal); + player->set_view(0); + + player->send("^BLaunching from " + dock->name()); +} + +// instantaniously goto a specified entity within the zone +void Game::func_goto(core::Player *player, const std::string &args) +{ + if (!args.size()) + return; + + if (!g_devel->value()) { + player->send("Cheats disabled"); + return; + } + + if (!player->control()) + return; + + core::Entity *dock = 0; + std::string label(args); + aux::to_label(label); + + core::Zone *zone = player->control()->zone(); + for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it ++) { + std::string str((*it)->label()); + aux::to_label(str); + if (str.find(label) != std::string::npos) { + dock = (*it); + } + } + + if (dock) { + player->control()->entity_location.assign(dock->location() + (dock->axis().forward() * (player->control()->radius()+dock->radius())*2.0f)); + player->control()->entity_axis.assign(dock->axis()); + player->control()->entity_axis.change_direction(180.0f); + player->control()->set_eventstate(core::Entity::Normal); + player->set_view(0); + player->send("Going to " + dock->name()); + } else { + player->send("Entity '" + args + "' not found"); + } +} + +/* -- class Base -------------------------------------------------- */ + +Game::Game() : core::Module("base", "Project::OSiRiON", true) +{ + default_shipmodel = 0; + default_zone = 0; +} + +Game::~Game() +{ +} + +void Game::init() +{ + ShipModel::clear(); + + if (!load_world()) { + abort(); + return; + } + + if (!load_ships()) { + abort(); + return; + } + + // add engine functions + core::Func *func = 0; + + func = core::Func::add("list_ship", Game::func_list_ship); + func->set_info("list ship statistics"); + + func = core::Func::add("join", Game::func_join); + func->set_info("join the game"); + + func = core::Func::add("hail", Game::func_hail); + func->set_info("send a standard hail"); + + func = core::Func::add("spectate", Game::func_spectate); + func->set_info("leave the game and spectate"); + + func = core::Func::add("buy", Game::func_buy); + func->set_info("buy a ship"); + + func = core::Func::add("jump", Game::func_jump); + func->set_info("[string] activate or deactivate hyperspace jump drive"); + + func = core::Func::add("impulse", Game::func_impulse); + func->set_info("activate are deactive kinetic impulse drive"); + + func = core::Func::add("launch", Game::func_launch); + func->set_info("launch to space when docked"); + + func = core::Func::add("goto", Game::func_goto); + func->set_info("[string] goto to an entity within the zone"); + + func = core::Func::add("@dock", Game::func_dock); + func->set_info("dock with target object"); + + // add engine variables + 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.01", 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"); +} + +void Game::shutdown() +{ + g_impulsespeed = 0; + // game functions are automaticly removed + + // remove engine core functions + core::Func::remove("list_ship"); + + ShipModel::clear(); +} + +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; + } + + con_print << "^BLoading world..." << std::endl; + + core::Zone *zone = 0; + std::string label; + + while (worldini.getline()) { + + if (worldini.got_section()) { + + if (worldini.got_section("world")) { + continue; + } else { + worldini.unknown_section(); + } + + } else if (worldini.got_key()) { + + if (worldini.in_section("world")) { + + if (worldini.got_key_string("zone", label)) { + aux::to_label(label); + zone = new core::Zone(label); + core::Zone::add(zone); + } else { + worldini.unkown_key(); + } + } + } + } + + 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::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; + } + + con_print << "^BLoading zone " << zone->label() << "..." << std::endl; + + 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_section()) { + 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("jumpgate")) { + jumppoint = new JumpGate(); + jumppoint->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->set_flag(core::Entity::Static); + entity->set_zone(zone); + count ++; + + } else { + zoneini.unknown_section(); + } + + } else if (zoneini.got_key()) { + + if (zoneini.in_section("zone")) { + 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 { + zoneini.unkown_key(); + } + + } else if (zoneini.in_section("star")) { + if (core::Parser::got_entity_key(zoneini, star)) { + continue; + } else if (zoneini.got_key_string("texture", star->entity_texture)) { + continue; + } else { + zoneini.unkown_key(); + } + + } else if (zoneini.in_section("navpoint")) { + if (core::Parser::got_entity_key(zoneini, navpoint)) { + continue; + } else { + zoneini.unkown_key(); + } + + } else if (zoneini.in_section("jumppoint") || zoneini.in_section("jumpgate")) { + if (core::Parser::got_entity_key(zoneini, jumppoint)) { + continue; + } else if (zoneini.got_key_string("target", strval)) { + jumppoint->set_targetlabel(strval); + continue; + } else { + zoneini.unkown_key(); + } + + } else if (zoneini.in_section("planet")) { + if (core::Parser::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 if (zoneini.got_key_bool("dock", b)) { + if (b) { + planet->set_flag(core::Entity::Dockable); + core::Descriptions::load_entity_menus(planet, "zones/" + zone->label() + "/" + planet->label()); + } else { + planet->unset_flag(core::Entity::Dockable); + } + } else if (zoneini.got_key_bool("default", b)) { + if (b) { + zone->set_default_view(planet); + } + continue; + } else { + zoneini.unkown_key(); + } + + } else if (zoneini.in_section("racetrack")) { + if (core::Parser::got_entity_key(zoneini, racetrack)) { + continue; + } else { + zoneini.unkown_key(); + } + + } else if (zoneini.in_section("checkpoint")) { + if (core::Parser::got_entity_key(zoneini, checkpoint)) { + continue; + } else { + zoneini.unkown_key(); + } + + } else if (zoneini.in_section("entity")) { + if (core::Parser::got_entity_key(zoneini, entity)) { + continue; + } else if (zoneini.got_key_bool("default", b)) { + if (b) { + zone->set_default_view(entity); + } + } else if (zoneini.got_key_bool("dock", b)) { + if (b) { + entity->set_flag(core::Entity::Dockable); + core::Descriptions::load_entity_menus(entity, "zones/" + zone->label() + "/" + entity->label()); + } else { + entity->unset_flag(core::Entity::Dockable); + } + } else { + zoneini.unkown_key(); + } + } + + } + } + 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) { + // validate jump points + JumpPoint *jumppoint = static_cast(entity); + jumppoint->validate(); + } else if (entity->entity_moduletypeid == jumpgate_enttype) { + // validate jump gate + JumpGate *jumpgate = static_cast(entity); + jumpgate->validate(); + } + } + + 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); + player->set_view(0); // not docked + + func_spectate(player, args); +} + +void Game::player_disconnect(core::Player *player) +{ + player->remove_asset(player->control()); +} + +} // namespace game + diff --git a/src/game/base/game.h b/src/game/base/game.h new file mode 100644 index 0000000..bc9d1f7 --- /dev/null +++ b/src/game/base/game.h @@ -0,0 +1,104 @@ +/* + base/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/shipmodel.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 contains the game-specific code for Project::OSiRiON + */ +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; +const unsigned int jumpgate_enttype = 261; +const unsigned int station_enttype = 262; + +/// the base Project::OSiRiON game model +class Game : public core::Module { +public: + Game(); + ~Game(); + + /// 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); + + /* --- game variables -------------------------------------- */ + + /// game variable: speed of the impulse drive + static core::Cvar *g_impulsespeed; + + /// game variable: acceleration of the impulse drive + static core::Cvar *g_impulseacceleration; + + /// game variable strafe speed + static core::Cvar *g_strafespeed; + + /// game variable: jumppoint range + static core::Cvar *g_jumppointrange; + + /// game variable: enable or disable development mode + static core::Cvar *g_devel; + +protected: + /// initialize the game + void init(); + + /// shutdown the game + void shutdown(); + +private: + + bool load_world(); + + bool load_zone(core::Zone *zone); + + bool validate_zone(core::Zone *zone); + + bool load_ships(); + + static core::Zone *default_zone; + static ShipModel *default_shipmodel; + + /* ---- engine functions ----------------------------------- */ + + static void func_list_ship(std::string const &args); + static void func_join(core::Player *player, std::string const &args); + static void func_spectate(core::Player *player, std::string const &args); + static void func_buy(core::Player *player, std::string const &args); + static void func_hail(core::Player *player, std::string const &args); + static void func_jump(core::Player *player, std::string const &args); + static void func_impulse(core::Player *player, std::string const &args); + static void func_dock(core::Player *player,core::Entity *entity); + static void func_launch(core::Player *player, std::string const &args); + static void func_goto(core::Player *player, const std::string &args); +}; + +} + +#endif // __INCLUDED_BASE_H__ + diff --git a/src/game/base/jumppoint.cc b/src/game/base/jumppoint.cc index da221cf..fcf20d6 100644 --- a/src/game/base/jumppoint.cc +++ b/src/game/base/jumppoint.cc @@ -4,13 +4,15 @@ the terms and conditions of the GNU General Public License version 2 */ -#include "base/base.h" +#include "base/game.h" #include "base/jumppoint.h" -namespace base +namespace game { -JumpPoint::JumpPoint() : core::Entity(core::Entity::Static | core::Entity::Bright) +/* ---- class JumpPoint -------------------------------------------- */ + +JumpPoint::JumpPoint() : core::EntityDynamic(core::Entity::Static | core::Entity::Bright) { entity_shape = core::Entity::Diamond; entity_color.assign(0.0f, 0.8f, 0.8f, 1.0f); @@ -26,4 +28,80 @@ JumpPoint::~JumpPoint() { } +void JumpPoint::set_targetlabel(const std::string &label) +{ + jumppoint_targetlabel.assign(label); +} + +void JumpPoint::validate() +{ + jumppoint_target = 0; + + if (targetlabel().size() < 3) { + con_warn << " Jumppoint with invalid target label '" << targetlabel() << "'\n"; + return; + } + size_t pos = targetlabel().find(':'); + if ((pos < 1 ) || (pos >= (targetlabel().size()-1))) { + con_warn << " Jumppoint with invalid target label '" << targetlabel() << "'\n"; + return; + } + + std::string zonelabel(targetlabel().substr(0, pos)); + std::string entitylabel(targetlabel().substr(pos+1, targetlabel().size()-pos)); + + core::Zone *targetzone = core::Zone::find(zonelabel); + if (!targetzone) { + con_warn << " Jumppoint with invalid target zone '" << zonelabel << "'\n"; + return; + } + + core::Entity *targetentity = targetzone->find_entity(entitylabel); + if (!targetentity) { + con_warn << " Could not find target jumppoint '" << entitylabel << "'\n"; + return; + } + + if ((targetentity->moduletype() != jumppoint_enttype) && (targetentity->moduletype() != jumpgate_enttype)) { + con_warn << " Jumppoint with invalid target jumppoint '" << entitylabel << "'\n"; + return; + } + + jumppoint_target = static_cast(targetentity); + + //con_debug << " Jumppoint " << zone->label() << ":" << label() << " with target " << targetlabel() << std::endl; +} + +/* ---- class JumpGate --------------------------------------------- */ + +JumpGate::JumpGate() : JumpPoint() +{ + unset_flag(core::Entity::Bright); + entity_radius = 1.0f; + entity_moduletypeid = jumpgate_enttype; + set_flag(core::Entity::Dockable); + + entity_eventstate = core::Entity::NoPower; +} + +JumpGate::~JumpGate() +{ +} + +void JumpGate::activate() +{ + jumpgate_timer = 10.0f; + entity_eventstate = core::Entity::Normal; +} + +void JumpGate::frame(float elapsed) +{ + if (jumpgate_timer > 0) + jumpgate_timer -= elapsed; + + if (jumpgate_timer < 0) { + entity_eventstate = core::Entity::NoPower; + } +} + } diff --git a/src/game/base/jumppoint.h b/src/game/base/jumppoint.h index 4680832..626a4ad 100644 --- a/src/game/base/jumppoint.h +++ b/src/game/base/jumppoint.h @@ -12,28 +12,50 @@ #include -namespace base { +namespace game { -/// a jump point +/// a jumppoint /** * 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 { +class JumpPoint : public core::EntityDynamic { public: JumpPoint(); ~JumpPoint(); inline std::string const & targetlabel() { return jumppoint_targetlabel; } + inline JumpPoint *target() { return jumppoint_target; } - std::string jumppoint_targetlabel; + /// set trget label + void set_targetlabel(const std::string &label); + + /// validate the targetlabel and set target() + void validate(); +private: + std::string jumppoint_targetlabel; JumpPoint *jumppoint_target; }; +/// a jumpgate +class JumpGate : public JumpPoint { +public: + JumpGate(); + virtual ~JumpGate(); + + inline bool activated() const { return (jumpgate_timer > 0); } + + void activate(); + + virtual void frame(float elapsed); +private: + float jumpgate_timer; +}; + } #endif // __INCLUDED_BASE_JUMPPOINT_H__ diff --git a/src/game/base/navpoint.cc b/src/game/base/navpoint.cc index 560962c..a8e44dc 100644 --- a/src/game/base/navpoint.cc +++ b/src/game/base/navpoint.cc @@ -5,9 +5,9 @@ */ #include "base/navpoint.h" -#include "base/base.h" +#include "base/game.h" -namespace base +namespace game { NavPoint::NavPoint() : core::Entity(core::Entity::Static | core::Entity::Bright) diff --git a/src/game/base/navpoint.h b/src/game/base/navpoint.h index 7ea505d..c2fb1d6 100644 --- a/src/game/base/navpoint.h +++ b/src/game/base/navpoint.h @@ -12,7 +12,7 @@ #include -namespace base { +namespace game { /// a navigation point class NavPoint : public core::Entity { diff --git a/src/game/base/planet.cc b/src/game/base/planet.cc index 83f3d65..26ba20f 100644 --- a/src/game/base/planet.cc +++ b/src/game/base/planet.cc @@ -4,11 +4,11 @@ the terms of the GNU General Public License version 2. */ -#include "base/base.h" +#include "base/game.h" #include "base/planet.h" -namespace base { +namespace game { Planet::Planet() : core::EntityGlobe(core::Entity::Static | core::Entity::Solid) { diff --git a/src/game/base/planet.h b/src/game/base/planet.h index 005157d..89b4387 100644 --- a/src/game/base/planet.h +++ b/src/game/base/planet.h @@ -12,7 +12,7 @@ #include -namespace base { +namespace game { /// a planet class Planet : public core::EntityGlobe { diff --git a/src/game/base/racetrack.cc b/src/game/base/racetrack.cc index ee2ecc7..46a7c86 100644 --- a/src/game/base/racetrack.cc +++ b/src/game/base/racetrack.cc @@ -10,7 +10,7 @@ #include "base/racetrack.h" #include "core/gameserver.h" -namespace base { +namespace game { /* ---- class CheckPoint ------------------------------------------- */ @@ -35,7 +35,7 @@ CheckPoint::~CheckPoint() /* ---- class RaceTrack -------------------------------------------- */ -RaceTrack::RaceTrack() +RaceTrack::RaceTrack() : EntityDynamic() { track_player = 0; track_racestart = 0; diff --git a/src/game/base/racetrack.h b/src/game/base/racetrack.h index b5b5dad..1f93bdc 100644 --- a/src/game/base/racetrack.h +++ b/src/game/base/racetrack.h @@ -13,7 +13,7 @@ #include -namespace base { +namespace game { class CheckPoint; diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index c7a5eda..3e4db42 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -10,7 +10,7 @@ #include "auxiliary/functions.h" #include "core/gameserver.h" #include "core/entity.h" -#include "base/base.h" +#include "base/game.h" #include "base/ship.h" #include "math/functions.h" @@ -19,7 +19,7 @@ using math::degrees360f; using math::degrees180f; -namespace base { +namespace game { const float MIN_DELTA = 0.000001f; @@ -40,6 +40,7 @@ Ship::Ship(core::Player *owner, ShipModel *shipmodel) : ship_impulsedrive_timer = 0; ship_jumpdrive_timer = 0; + ship_jumpdepart = 0; reset(); } @@ -57,7 +58,7 @@ void Ship::reset() current_target_strafe = 0.0f; current_target_afterburner = 0.0f; } -void Ship::impulse() +void Ship::func_impulse() { if ((entity_eventstate == core::Entity::Impulse) || (entity_eventstate == core::Entity::ImpulseInitiate)) { entity_eventstate = core::Entity::Normal; @@ -72,7 +73,7 @@ void Ship::impulse() } entity_eventstate = core::Entity::ImpulseInitiate; - if (Base::g_devel->value()) { + if (Game::g_devel->value()) { entity_timer = 0; } else { entity_timer = 3; @@ -84,14 +85,37 @@ void Ship::impulse() entity_dirty = true; } -void Ship::jump(std::string const &args) +void Ship::initiate_jump(JumpPoint *depart) +{ + ship_jumpdepart = 0; + + if (!depart) + return; + + if (!depart->target()) + return; + + ship_jumpdepart = depart; + entity_eventstate = core::Entity::JumpInitiate; + + if (Game::g_devel->value()) { + entity_timer = 0; + } else { + entity_timer = 8; + } + + ship_jumpdrive_timer = core::server()->time(); + entity_dirty = true; +} + +void Ship::func_jump(std::string const &args) { if (entity_eventstate == core::Entity::Docked) { return; } // devel mode provides instant jump access to arbitrary systems - if (Base::g_devel->value() && (args.size())) { + if (Game::g_devel->value() && (args.size())) { core::Zone *jumptargetzone = 0; std::string target; @@ -117,7 +141,7 @@ void Ship::jump(std::string const &args) } if (jumptargetzone == zone()) { - owner()->send("Already in the " + jumptargetzone->name() + '.'); + owner()->send("Already in the " + jumptargetzone->name()); return; } @@ -133,7 +157,7 @@ void Ship::jump(std::string const &args) return; } else { - if (!jumpdrive() && !Base::g_devel->value()) { + if (!jumpdrive() && !Game::g_devel->value()) { owner()->send("This ship is not equiped with a hyperspace drive!"); return; @@ -141,26 +165,14 @@ void Ship::jump(std::string const &args) return; } else if (entity_eventstate == core::Entity::JumpInitiate) { - owner()->send("Jump aborted, hyperspace drive deactivated."); + owner()->send("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::g_devel->value()) { - entity_timer = 0; - } else { - entity_timer = 8; - } - - ship_jumpdrive_timer = core::server()->time(); - entity_dirty = true; + initiate_jump(find_closest_jumppoint()); } } @@ -182,7 +194,7 @@ JumpPoint * Ship::find_closest_jumppoint() } if (jumppoint && jumppoint->target()) { - if (Base::g_jumppointrange->value() < d) { + if (Game::g_jumppointrange->value() < d) { owner()->send("Jumppoint out of range!"); return 0; } else { @@ -236,14 +248,20 @@ void Ship::frame(float seconds) 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()); + if (ship_jumpdepart && ship_jumpdepart->target()) { entity_eventstate = core::Entity::Jump; - entity_location.assign(jumppoint->target()->location() + location() - jumppoint->location()); + set_zone(ship_jumpdepart->target()->zone()); + if (owner() && owner()->control() == (EntityControlable*) this) + owner()->set_zone(ship_jumpdepart->target()->zone()); + + if (ship_jumpdepart->moduletype() == jumpgate_enttype) { + entity_axis.assign(ship_jumpdepart->target()->axis()); + entity_location.assign(ship_jumpdepart->target()->location()); + //entity_location += entity_axis.forward() * radius(); + } else { + entity_location.assign(ship_jumpdepart->target()->location() + location() - ship_jumpdepart->location()); + } + owner()->send("^BJumping to the " + ship_jumpdepart->target()->zone()->name()); } else { entity_eventstate = core::Entity::Normal; } @@ -264,7 +282,7 @@ void Ship::frame(float seconds) target_roll = 0; target_direction = 0; target_afterburner = 0.0f; - target_thrust = 0; + target_thrust = 0.1; } else if (entity_eventstate == core::Entity::Jump) { // control is disabled while the jumpdrive is activated @@ -276,22 +294,25 @@ void Ship::frame(float seconds) target_thrust = 0; // FIXME jump location and axis - math::Axis default_axis; - entity_axis.assign(default_axis); + //math::Axis default_axis; + //entity_axis.assign(default_axis); entity_dirty = true; // FIXME 5 second cooldown - entity_speed = Base::g_impulsespeed->value(); + entity_speed = Game::g_impulsespeed->value(); entity_eventstate = core::Entity::Normal; + if (owner() && owner()->view() && owner()->control() == (EntityControlable*) this) + owner()->set_view(0); + } 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::g_impulsespeed->value(); - actual_acceleration = Base::g_impulseacceleration->value(); + actual_maxspeed = Game::g_impulsespeed->value(); + actual_acceleration = Game::g_impulseacceleration->value(); entity_eventstate = core::Entity::Impulse; entity_timer = 0; entity_dirty = true; @@ -317,8 +338,8 @@ void Ship::frame(float seconds) math::clamp(target_roll, -1.0f, 1.0f); math::clamp(target_direction, -1.0f, 1.0f); target_afterburner = 0.0f; - actual_maxspeed = Base::g_impulsespeed->value(); - actual_acceleration = Base::g_impulseacceleration->value(); + actual_maxspeed = Game::g_impulsespeed->value(); + actual_acceleration = Game::g_impulseacceleration->value(); actual_turnspeed *= 0.5; } else if (entity_eventstate == core::Entity::Normal) { @@ -331,7 +352,7 @@ void Ship::frame(float seconds) math::clamp(target_afterburner, -1.0f, 1.0f); if (speed() > actual_maxspeed * 1.15f) { - actual_acceleration = Base::g_impulseacceleration->value(); + actual_acceleration = Game::g_impulseacceleration->value(); actual_turnspeed *= 0.5; } @@ -459,7 +480,7 @@ void Ship::frame(float seconds) } if (fabs(current_target_strafe) > MIN_DELTA) { - entity_location += entity_axis.left() * (current_target_strafe * Base::g_strafespeed->value()); + entity_location += entity_axis.left() * (current_target_strafe * Game::g_strafespeed->value()); } entity_movement = target_thrust; diff --git a/src/game/base/ship.h b/src/game/base/ship.h index d3c8bbf..bed3d1e 100644 --- a/src/game/base/ship.h +++ b/src/game/base/ship.h @@ -13,7 +13,7 @@ #include "base/jumppoint.h" #include "math/vector3f.h" -namespace base { +namespace game { /// A ship in the game, controled by a player class Ship : public core::EntityControlable @@ -28,16 +28,23 @@ public: /// 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(); + /// Initiate jump, departing from a jump point + /** Initiates a jump even if the ship has no jumpdrive + */ + void initiate_jump(JumpPoint *depart); /// void reset drive controls void reset(); + /// toggle impulse drive activation + void func_impulse(); + + /// toggle jump drive activation + void func_jump(std::string const & args); + private: + JumpPoint *find_closest_jumppoint(); + ShipModel *ship_shipmodel; float current_target_direction; @@ -51,7 +58,8 @@ private: float ship_impulsedrive_timer; - JumpPoint * find_closest_jumppoint(); + + JumpPoint *ship_jumpdepart; }; } diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc index 6018414..66e752e 100644 --- a/src/game/base/shipmodel.cc +++ b/src/game/base/shipmodel.cc @@ -7,7 +7,7 @@ #include "sys/sys.h" #include "base/shipmodel.h" -namespace base { +namespace game { // the ship model registry std::map ShipModel::registry; diff --git a/src/game/base/shipmodel.h b/src/game/base/shipmodel.h index d92b840..277eccd 100644 --- a/src/game/base/shipmodel.h +++ b/src/game/base/shipmodel.h @@ -10,7 +10,7 @@ #include #include -namespace base { +namespace game { /// ship model specifications class ShipModel diff --git a/src/game/base/star.cc b/src/game/base/star.cc index cacd542..ecf403e 100644 --- a/src/game/base/star.cc +++ b/src/game/base/star.cc @@ -4,11 +4,11 @@ the terms of the GNU General Public License version 2. */ -#include "base/base.h" +#include "base/game.h" #include "base/star.h" -namespace base { +namespace game { Star::Star() : core::EntityGlobe(core::Entity::Static | core::Entity::Solid | core::Entity::Bright) { diff --git a/src/game/base/star.h b/src/game/base/star.h index 5a78fc8..5283894 100644 --- a/src/game/base/star.h +++ b/src/game/base/star.h @@ -14,7 +14,7 @@ // C++ headers #include -namespace base { +namespace game { /// a star, that shines so bright class Star : public core::EntityGlobe { diff --git a/src/game/game.cc b/src/game/game.cc index 01a2574..a125eb7 100644 --- a/src/game/game.cc +++ b/src/game/game.cc @@ -4,25 +4,21 @@ the terms of the GNU General Public License version 2 */ -#include "game/game.h" - -#include "base/base.h" -#include "example/example.h" -#include "intro/intro.h" #include "core/core.h" +#include "game/game.h" +#include "game/base/game.h" +#include "game/example/example.h" +#include "game/intro/intro.h" #include "sys/sys.h" -namespace game -{ - /// register game modules void register_modules(bool register_noninteractive_modules) { con_print << "^BRegistering game modules..." << std::endl; // non-interactive modules - core::Module::add(new base::Base()); + core::Module::add(new game::Game()); core::Module::add(new example::Example()); // interactive modules @@ -30,5 +26,3 @@ void register_modules(bool register_noninteractive_modules) core::Module::add(new intro::Intro()); } } - -} diff --git a/src/game/game.h b/src/game/game.h index 236299b..027a125 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -7,10 +7,7 @@ #ifndef __INCLUDED_GAME_H__ #define __INCLUDED_GAME_H__ -namespace game { - - void register_modules(bool register_noninteractive_modules=false); -} +void register_modules(bool register_noninteractive_modules=false); #endif // __INCLUDED_GAME_H__ -- cgit v1.2.3