From d389a31f9816b55d8c7685ec24b9ab814252d693 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Mon, 28 Jul 2008 19:37:31 +0000 Subject: zone support --- src/game/game.cc | 372 +++++++++++++++++++++++++++++++++++--------------- src/game/game.h | 7 + src/game/ship.cc | 12 +- src/game/ship.h | 5 + src/game/shipmodel.cc | 1 + src/game/shipmodel.h | 3 + 6 files changed, 288 insertions(+), 112 deletions(-) (limited to 'src/game') diff --git a/src/game/game.cc b/src/game/game.cc index 2d21be8..efca1be 100644 --- a/src/game/game.cc +++ b/src/game/game.cc @@ -20,7 +20,11 @@ namespace game { -ShipModel *default_shipmodel; +Game *this_game = 0; + +ShipModel *default_shipmodel = 0; +core::Zone *default_zone = 0; + /*----- engine game functions ------------------------------------- */ /// list the ship model registry @@ -35,8 +39,11 @@ void func_join(core::Player *player, std::string const &args) if (player->control()) return; - player->player_control = new Ship(player, default_shipmodel); - player->control()->entity_color = player->color(); + 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"); @@ -50,7 +57,7 @@ void func_join(core::Player *player, std::string const &args) /// a player joins the spectators void func_spectate(core::Player *player, std::string const &args) { - if (!player->player_control) + if (!player->control()) return; std::string message("^B"); @@ -59,12 +66,8 @@ void func_spectate(core::Player *player, std::string const &args) core::server()->broadcast(message); if (player->control()) { - // player has only ship for now - player->player_control->die(); - player->player_control = 0; + player->remove_asset(player->control()); } - - player->player_dirty = true; } /// a player buys a ship @@ -92,17 +95,16 @@ void func_buy(core::Player *player, std::string const &args) if (shipmodel) { // player has only ship for now if (player->control()) { - player->player_control->die(); - player->player_control = 0; + player->remove_asset(player->control()); } - player->player_control = new Ship(player, shipmodel); - player->control()->entity_color = player->color(); - player->control()->entity_color_second = player->color_second(); - + Ship * ship = new Ship(player, shipmodel); + 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"); - player->player_dirty = true; + } else { core::server()->send(player, "Usage: buy [^B" + helpstr + "^N]"); } @@ -131,10 +133,49 @@ void func_hail(core::Player *player, std::string const &args) core::server()->send_sound(targetplayer, "com/hail"); } +/// a player actives the jumpdrive 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()); + + if (!ship->jumpdrive()) { + core::server()->send(player, "Your ship is not equiped with a jumpdrive"); + return; + } + + std::string target; + std::istringstream is(args); + if (!(is >> target)) { + core::server()->send(player, "Usage: jump [system]"); + return; + } + + core::Zone *zone = core::Zone::find_zone(target); + if (!zone) { + core::server()->send(player, "Unknown system '" + target + '\''); + return; + } + + if (zone == player->control()->zone()) + return; + + core::server()->send(player, "Jumping to '" + zone->name() + '\''); + + player->control()->set_zone(zone); + player->set_zone(zone); +} + /*----- Game ------------------------------------------------------ */ Game::Game() : core::Module("Project::OSiRiON") { + this_game = this; } Game::~Game() @@ -143,23 +184,130 @@ Game::~Game() void Game::init() { - using math::Vector3f; - using math::Color; - module_running = false; ShipModel::clear(); - // setup the game world + if (!load_world()) { + abort(); + return; + } + + if (!load_ships()) { + abort(); + return; + } + + // add engine game functions + core::Func *func = 0; + 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("make a hyperspace jump"); + 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"); + + // add engine core functions + func = core::Func::add("list_ship", (core::FuncPtr) func_list_ship); + func->set_info("list ship statistics"); + + // set game variables + core::Cvar::set("g_impulsespeed", "10.0f", core::Cvar::Game); + + // indicate the module is ready to run frames + module_running = true; +} + +void Game::shutdown() +{ + // 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("world"); + worldini.open(inifilename); if (!worldini.is_open()) { - con_error << "Could not open ini/world.ini!" << std::endl; - abort(); - return; + 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::trim(label); + aux::lowercase(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; + } + } + + 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; } + size_t count = 0; + Planet *planet = 0; Star *star = 0; core::Entity *entity = 0; @@ -168,41 +316,61 @@ void Game::init() float pitch; float roll; - while (worldini.getline()) { - if (worldini.got_key()) { - if (worldini.section().compare("star") == 0) { - if (worldini.got_key_string("label", star->entity_label)) + 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)) { + 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 if (worldini.got_key_string("name", star->entity_name)) + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } + } else if (zoneini.section().compare("star") == 0) { + if (zoneini.got_key_string("label", star->entity_label)) continue; - else if (worldini.got_key_vector3f("location", star->entity_location )) + else if (zoneini.got_key_string("name", star->entity_name)) continue; - else if (worldini.got_key_color("color", star->entity_color)) + else if (zoneini.got_key_vector3f("location", star->entity_location )) continue; - else if (worldini.got_key_angle("radius", star->entity_radius)) + else if (zoneini.got_key_color("color", star->entity_color)) + continue; + else if (zoneini.got_key_angle("radius", star->entity_radius)) continue; else - con_warn << worldini.name() << " unknown key '" << worldini.key() << "' at line " << worldini.line() << std::endl; + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; - } else if (worldini.section().compare("planet") == 0) { - if (worldini.got_key_string("label", planet->entity_label)) + } else if (zoneini.section().compare("planet") == 0) { + if (zoneini.got_key_string("label", planet->entity_label)) continue; - else if (worldini.got_key_string("name", planet->entity_name)) + else if (zoneini.got_key_string("name", planet->entity_name)) continue; - else if (worldini.got_key_string("texture", planet->entity_texture)) + else if (zoneini.got_key_string("texture", planet->entity_texture)) continue; - else if (worldini.got_key_vector3f("location", planet->entity_location )) + else if (zoneini.got_key_vector3f("location", planet->entity_location )) continue; - else if (worldini.got_key_color("color", planet->entity_color)) + else if (zoneini.got_key_color("color", planet->entity_color)) continue; - else if (worldini.got_key_angle("radius", planet->entity_radius)) + else if (zoneini.got_key_angle("radius", planet->entity_radius)) continue; else - con_warn << worldini.name() << " unknown key '" << worldini.key() << "' at line " << worldini.line() << std::endl; + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; - } else if (worldini.section().compare("entity") == 0) { + } else if (zoneini.section().compare("entity") == 0) { std::string shapename; - if (worldini.got_key_string("shape", shapename)) { + if (zoneini.got_key_string("shape", shapename)) { if (shapename.compare("axis") == 0) { entity->entity_shape = core::Entity::Axis; } else if (shapename.compare("cube") == 0) { @@ -212,65 +380,83 @@ void Game::init() } else if (shapename.compare("sphere") == 0) { entity->entity_shape = core::Entity::Sphere; } else { - con_warn << worldini.name() << " unknown shape '" << shapename << "' at line " << worldini.line() << std::endl; + con_warn << zoneini.name() << " unknown shape '" << shapename << "' at line " << zoneini.line() << std::endl; } continue; - } else if (worldini.got_key_string("label", entity->entity_label)) { + } else if (zoneini.got_key_string("label", entity->entity_label)) { continue; - } else if (worldini.got_key_string("name", entity->entity_name)) { + } else if (zoneini.got_key_string("name", entity->entity_name)) { continue; - } else if (worldini.got_key_string("model", entity->entity_modelname)) { + } else if (zoneini.got_key_string("model", entity->entity_modelname)) { continue; - } else if (worldini.got_key_angle("direction", direction)) { + } else if (zoneini.got_key_angle("direction", direction)) { entity->axis().change_direction(direction); continue; - } else if (worldini.got_key_angle("pitch", pitch)) { + } else if (zoneini.got_key_angle("pitch", pitch)) { entity->axis().change_pitch(pitch); continue; - } else if (worldini.got_key_angle("roll", roll)) { + } else if (zoneini.got_key_angle("roll", roll)) { entity->axis().change_roll(roll); continue; - } else if (worldini.got_key_angle("radius", entity->entity_radius)) { + } else if (zoneini.got_key_angle("radius", entity->entity_radius)) { continue; - } else if (worldini.got_key_vector3f("location", entity->entity_location)) { + } else if (zoneini.got_key_vector3f("location", entity->entity_location)) { continue; - } else if (worldini.got_key_color("color", entity->entity_color)) { + } else if (zoneini.got_key_color("color", entity->entity_color)) { continue; - } else if (worldini.got_key_color("colorsecond", entity->entity_color_second)) { + } else if (zoneini.got_key_color("colorsecond", entity->entity_color_second)) { continue; } else { - con_warn << worldini.name() << " unknown key '" << worldini.key() << "' at line " << worldini.line() << std::endl; + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; } } - } else if (worldini.got_section("star")) { + } else if (zoneini.got_section("zone")) { + continue; + + } else if (zoneini.got_section("star")) { star = new Star(); + star->set_zone(zone); + count ++; - } else if (worldini.got_section("planet")) { + } else if (zoneini.got_section("planet")) { planet = new Planet(); + planet->set_zone(zone); + count ++; - } else if (worldini.got_section("entity")) { + } else if (zoneini.got_section("entity")) { entity = new core::Entity(); entity->entity_flags += core::Entity::Static; + entity->set_zone(zone); + count ++; - } else if (worldini.got_section()) { - con_warn << worldini.name() << " unknown section '" << worldini.section() << "' at line " << worldini.line() << std::endl; + } else if (zoneini.got_section()) { + con_warn << zoneini.name() << " unknown section '" << zoneini.section() << "' at line " << zoneini.line() << std::endl; } } - worldini.close(); + zoneini.close(); + + con_debug << " " << zoneini.name() << " " << zone->content().size() << " entities" << std::endl; + + return true; +} + +// read ship model specifications +bool Game::load_ships() +{ + using math::Vector3f; + using math::Color; + + default_shipmodel = 0; - // read ship model specifications - // note: - // do not reuse the previous IniFile instance, some gcc versions do not like it filesystem::IniFile shipsini; shipsini.open("ships"); if (!shipsini.is_open()) { con_error << "Could not open ini/ships.ini!" << std::endl; - abort(); - return; + return false; } ShipModel *shipmodel = 0; - default_shipmodel = 0; + bool b; while (shipsini.getline()) { if (shipsini.got_key()) { @@ -282,8 +468,10 @@ void Game::init() continue; } else if (shipsini.got_key_string("model", shipmodel->shipmodel_modelname)) { continue; - } else if (shipsini.got_key("default")) { - default_shipmodel = shipmodel; + } 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; @@ -307,43 +495,14 @@ void Game::init() } shipsini.close(); + con_debug << " " << shipsini.name() << " " << ShipModel::registry.size() << " ship models" << std::endl; + if (!default_shipmodel) { - con_error << "No default ship model in ini/ships.ini!\n"; - abort(); - return; + con_error << "No default ship model found!\n"; + return false; } - // add engine game functions - core::Func *func = 0; - func = core::Func::add("buy", (core::GameFuncPtr) func_buy); - func->set_info("buy a ship"); - 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"); - - // add engine core functions - func = core::Func::add("list_ship", (core::FuncPtr) func_list_ship); - func->set_info("list ship statistics"); - - // set game variables - core::Cvar::set("g_impulsespeed", "10.0f", core::Cvar::Game); - - // indicate the module is ready to run frames - module_running = true; -} - -void Game::shutdown() -{ - // game functions are automaticly removed - - // remove engine core functions - core::Func::remove("list_ship"); - - ShipModel::clear(); - module_running = false; + return true; } void Game::frame(float seconds) @@ -355,16 +514,13 @@ void Game::frame(float seconds) 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) { - if (player->control()) { - // player has only one ship for now - player->control()->die(); - player->player_control = 0; - } + player->remove_asset(player->control()); } } // namespace game diff --git a/src/game/game.h b/src/game/game.h index 89889a0..a715edd 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -47,6 +47,13 @@ public: /// is called when a player disconnects void player_disconnect(core::Player *player); + +private: + bool load_world(); + + bool load_zone(core::Zone *zone); + + bool load_ships(); }; } diff --git a/src/game/ship.cc b/src/game/ship.cc index 66d8b52..f61c9bd 100644 --- a/src/game/ship.cc +++ b/src/game/ship.cc @@ -23,19 +23,23 @@ Ship::Ship(core::Player *owner, ShipModel *shipmodel) : entity_modelname = "ships/" + shipmodel->modelname(); entity_name = shipmodel->name() + ": <^B" + owner->name() + "^N>"; entity_label = shipmodel->label(); - ship_shipmodel = shipmodel; entity_moduletypeid = ship_enttype; current_target_direction = 0.0f; current_target_pitch = 0.0f;; - current_target_roll = 0.0f;; + current_target_roll = 0.0f; + + entity_color = owner->color(); + entity_color_second = owner->color_second(); + + ship_shipmodel = shipmodel; + ship_jumpdrive = shipmodel->shipmodel_jumpdrive; } Ship::~Ship() { - if (entity_owner) - entity_owner->remove_asset(this); + } void Ship::frame(float seconds) diff --git a/src/game/ship.h b/src/game/ship.h index 9e978bb..bca0857 100644 --- a/src/game/ship.h +++ b/src/game/ship.h @@ -24,12 +24,17 @@ public: /// 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; } + private: ShipModel *ship_shipmodel; float current_target_direction; float current_target_pitch; float current_target_roll; + + bool ship_jumpdrive; }; } diff --git a/src/game/shipmodel.cc b/src/game/shipmodel.cc index aa0c2c9..6a226f4 100644 --- a/src/game/shipmodel.cc +++ b/src/game/shipmodel.cc @@ -19,6 +19,7 @@ ShipModel::ShipModel() shipmodel_maxspeed = 3.0f; shipmodel_turnspeed = 0.1f; + shipmodel_jumpdrive = false; } ShipModel::~ShipModel() diff --git a/src/game/shipmodel.h b/src/game/shipmodel.h index 686d736..a29f860 100644 --- a/src/game/shipmodel.h +++ b/src/game/shipmodel.h @@ -44,6 +44,9 @@ public: 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 -- cgit v1.2.3