From 03d5bc014c0e815c6aaeec16d81e225e08732ab0 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Mon, 10 Nov 2008 18:02:13 +0000 Subject: adds jumpgate, station, ship dealer --- src/game/base/Makefile.am | 4 +- src/game/base/game.cc | 204 +++++++++++++++++++++++++++++--------------- src/game/base/game.h | 9 +- src/game/base/jumppoint.h | 2 +- src/game/base/planet.cc | 12 +++ src/game/base/planet.h | 11 ++- src/game/base/racetrack.h | 4 +- src/game/base/ship.cc | 6 +- src/game/base/shipdealer.cc | 145 +++++++++++++++++++++++++++++++ src/game/base/shipdealer.h | 43 ++++++++++ src/game/base/shipmodel.cc | 10 +++ src/game/base/shipmodel.h | 1 + src/game/base/station.cc | 35 ++++++++ src/game/base/station.h | 32 +++++++ 14 files changed, 434 insertions(+), 84 deletions(-) create mode 100644 src/game/base/shipdealer.cc create mode 100644 src/game/base/shipdealer.h create mode 100644 src/game/base/station.cc create mode 100644 src/game/base/station.h (limited to 'src/game') diff --git a/src/game/base/Makefile.am b/src/game/base/Makefile.am index 1b80e72..21e1717 100644 --- a/src/game/base/Makefile.am +++ b/src/game/base/Makefile.am @@ -3,6 +3,6 @@ METASOURCES = AUTO libbase_la_LDFLAGS = -avoid-version noinst_LTLIBRARIES = libbase.la libbase_la_SOURCES = game.cc jumppoint.cc navpoint.cc planet.cc racetrack.cc \ - ship.cc shipmodel.cc star.cc + ship.cc shipdealer.cc shipmodel.cc star.cc station.cc noinst_HEADERS = game.h jumppoint.h navpoint.h planet.h racetrack.h ship.h \ - shipmodel.h star.h + shipdealer.h shipmodel.h star.h station.h diff --git a/src/game/base/game.cc b/src/game/base/game.cc index d20dd8c..7dcf300 100644 --- a/src/game/base/game.cc +++ b/src/game/base/game.cc @@ -18,6 +18,7 @@ #include "base/navpoint.h" #include "base/jumppoint.h" #include "base/planet.h" +#include "base/station.h" #include "base/racetrack.h" #include "base/ship.h" #include "base/star.h" @@ -95,61 +96,6 @@ void Game::func_spectate(core::Player *player, std::string const &args) 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) { @@ -308,7 +254,7 @@ void Game::func_goto(core::Player *player, const std::string &args) } } -/* -- class Base -------------------------------------------------- */ +/* -- class Game -------------------------------------------------- */ Game::Game() : core::Module("base", "Project::OSiRiON", true) { @@ -324,16 +270,16 @@ void Game::init() { ShipModel::clear(); - if (!load_world()) { + if (!load_ships()) { abort(); return; } - - if (!load_ships()) { + + if (!load_world()) { abort(); return; } - + // add engine functions core::Func *func = 0; @@ -349,7 +295,7 @@ void Game::init() 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 = core::Func::add("buy", ShipDealer::func_buy); func->set_info("buy a ship"); func = core::Func::add("jump", Game::func_jump); @@ -486,6 +432,7 @@ bool Game::load_zone(core::Zone *zone) size_t count = 0; + Station *station = 0; Planet *planet = 0; Star *star = 0; NavPoint *navpoint = 0; @@ -541,6 +488,11 @@ bool Game::load_zone(core::Zone *zone) planet = new Planet(); planet->set_zone(zone); count ++; + + } else if (zoneini.got_section("station")) { + station = new Station(); + station->set_zone(zone); + count ++; } else if (zoneini.got_section("entity")) { entity = new core::Entity(); @@ -605,7 +557,6 @@ bool Game::load_zone(core::Zone *zone) } 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); } @@ -617,6 +568,17 @@ bool Game::load_zone(core::Zone *zone) } else { zoneini.unkown_key(); } + + } else if (zoneini.in_section("station")) { + if (core::Parser::got_entity_key(zoneini, station)) { + continue; + } else if (zoneini.got_key_bool("default", b)) { + if (b) { + zone->set_default_view(station); + } + } else { + zoneini.unkown_key(); + } } else if (zoneini.in_section("racetrack")) { if (core::Parser::got_entity_key(zoneini, racetrack)) { @@ -639,13 +601,6 @@ bool Game::load_zone(core::Zone *zone) 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(); } @@ -663,7 +618,7 @@ bool Game::load_zone(core::Zone *zone) bool Game::validate_zone(core::Zone *zone) { - con_debug << " validating " << zone->name() << std::endl; + con_print << "^BValidating zone " << zone->label() << "..." << std::endl; for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { core::Entity *entity = (*it); @@ -675,9 +630,113 @@ bool Game::validate_zone(core::Zone *zone) // validate jump gate JumpGate *jumpgate = static_cast(entity); jumpgate->validate(); + } else { + if ((entity->flags() & core::Entity::Dockable) == core::Entity::Dockable) + load_menus(entity, "zones/" + zone->label() + "/" + entity->label()); + } + } + + return true; +} + +bool Game::load_menus(core::Entity *entity, const std::string &menufilename) +{ + using core::MenuDescription; + using core::ButtonDescription; + + if ((entity->moduletype() != planet_enttype) && (entity->moduletype() != station_enttype)) { + return false; + } + + filesystem::IniFile inifile; + + std::string strval; + MenuDescription *menu_dealer = 0; + ButtonDescription *button = 0; + ShipDealer *shipdealer = 0; + + inifile.open(menufilename); + + if (inifile.is_open()) { + while (inifile.getline()) { + + if (inifile.got_section()) { + if (inifile.got_section("dealer")) { + // dealer menu + if (!menu_dealer) { + menu_dealer = new MenuDescription(); + menu_dealer->set_label("dealer"); + menu_dealer->set_text("Ship dealer"); + + shipdealer = new ShipDealer(); + if (entity->moduletype() == planet_enttype) { + static_cast(entity)->set_shipdealer(shipdealer); + } else if (entity->moduletype() == station_enttype) { + static_cast(entity)->set_shipdealer(shipdealer); + } + } + } else { + inifile.unknown_section(); + } + + } else if (inifile.got_key()) { + + if (inifile.in_section("dealer")) { + + if (inifile.got_key_string("ship", strval)) { + aux::to_label(strval); + ShipModel *model = shipdealer->add(strval); + if (model) { + button = new ButtonDescription(); + button->set_text("buy " + model->name()); + button->set_command("buy " + model->label()); + button->set_modelname("ships/" + model->modelname()); + button->set_alignment(ButtonDescription::Left); + menu_dealer->add_button(button); + } + } else { + inifile.unkown_key(); + } + + } + } } + + } + + MenuDescription *menu_main = new MenuDescription(); + menu_main->set_label("main"); + menu_main->set_text("Launch area"); + entity->add_menu(menu_main); + + if (menu_dealer) { + button = new ButtonDescription(); + button->set_text("Return"); + button->set_command("menu view main"); + button->set_alignment(ButtonDescription::Center); + menu_dealer->add_button(button); + + entity->add_menu(menu_dealer); + + button = new ButtonDescription(); + button->set_text("Ship dealer"); + button->set_command("menu view dealer"); + button->set_alignment(ButtonDescription::Center); + menu_main->add_button(button); } + button = new ButtonDescription(); + button->set_text("Launch"); + button->set_command("launch"); + button->set_alignment(ButtonDescription::Center); + menu_main->add_button(button); + + if (inifile.is_open()) { + size_t n = entity->menus().size(); + con_debug << " " << inifile.name() << " " << n << " " << aux::plural("menu", n) << std::endl; + inifile.close(); + } + return true; } @@ -729,8 +788,8 @@ bool Game::load_ships() } } } else if (shipsini.got_section("ship")) { + if (shipmodel && !ShipModel::find(shipmodel)) delete shipmodel; shipmodel = new ShipModel(); - if (!default_shipmodel) default_shipmodel = shipmodel; @@ -740,6 +799,8 @@ bool Game::load_ships() } shipsini.close(); + if (shipmodel && !ShipModel::find(shipmodel)) delete shipmodel; + con_debug << " " << shipsini.name() << " " << ShipModel::registry.size() << " ship models" << std::endl; if (!default_shipmodel) { @@ -772,3 +833,4 @@ void Game::player_disconnect(core::Player *player) } // namespace game + diff --git a/src/game/base/game.h b/src/game/base/game.h index bc9d1f7..d4f0743 100644 --- a/src/game/base/game.h +++ b/src/game/base/game.h @@ -36,7 +36,7 @@ const unsigned int station_enttype = 262; class Game : public core::Module { public: Game(); - ~Game(); + virtual ~Game(); /// run one time frame void frame(float seconds); @@ -66,10 +66,10 @@ public: protected: /// initialize the game - void init(); + virtual void init(); /// shutdown the game - void shutdown(); + virtual void shutdown(); private: @@ -79,6 +79,8 @@ private: bool validate_zone(core::Zone *zone); + bool load_menus(core::Entity *entity, const std::string &menufilename); + bool load_ships(); static core::Zone *default_zone; @@ -89,7 +91,6 @@ private: 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); diff --git a/src/game/base/jumppoint.h b/src/game/base/jumppoint.h index 626a4ad..4bab7db 100644 --- a/src/game/base/jumppoint.h +++ b/src/game/base/jumppoint.h @@ -24,7 +24,7 @@ namespace game { class JumpPoint : public core::EntityDynamic { public: JumpPoint(); - ~JumpPoint(); + virtual ~JumpPoint(); inline std::string const & targetlabel() { return jumppoint_targetlabel; } diff --git a/src/game/base/planet.cc b/src/game/base/planet.cc index 26ba20f..684b9dc 100644 --- a/src/game/base/planet.cc +++ b/src/game/base/planet.cc @@ -18,10 +18,22 @@ Planet::Planet() : core::EntityGlobe(core::Entity::Static | core::Entity::Solid) entity_moduletypeid = planet_enttype; entity_rotationspeed = 1.0f; + + planet_shipdealer = 0; } Planet::~Planet() { + if (planet_shipdealer) + delete planet_shipdealer; +} + +void Planet::set_shipdealer(ShipDealer *shipdealer) +{ + if (planet_shipdealer) + delete planet_shipdealer; + + planet_shipdealer = shipdealer; } } // namespace game diff --git a/src/game/base/planet.h b/src/game/base/planet.h index 89b4387..e6fa41a 100644 --- a/src/game/base/planet.h +++ b/src/game/base/planet.h @@ -7,6 +7,7 @@ #ifndef __INCLUDED_BASE_PLANET_H__ #define __INCLUDED_BASE_PLANET_H__ +#include "base/shipdealer.h" #include "core/entity.h" #include "math/mathlib.h" @@ -18,7 +19,15 @@ namespace game { class Planet : public core::EntityGlobe { public: Planet(); - ~Planet(); + virtual ~Planet(); + + inline ShipDealer *shipdealer() { return planet_shipdealer; } + + void set_shipdealer(ShipDealer *shipdealer); + +private: + ShipDealer *planet_shipdealer; + }; } diff --git a/src/game/base/racetrack.h b/src/game/base/racetrack.h index 1f93bdc..922a94f 100644 --- a/src/game/base/racetrack.h +++ b/src/game/base/racetrack.h @@ -25,14 +25,14 @@ public: typedef std::list CheckPoints ; RaceTrack(); - ~RaceTrack(); + virtual ~RaceTrack(); void add_checkpoint(CheckPoint *checkpoint); /// reset the race track void reset(); - virtual void frame(float seconds); + virtual void frame(float elapsed); inline core::Player *player() { return track_player; } diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index 3e4db42..214d234 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -157,6 +157,7 @@ void Ship::func_jump(std::string const &args) return; } else { + if (!jumpdrive() && !Game::g_devel->value()) { owner()->send("This ship is not equiped with a hyperspace drive!"); return; @@ -171,19 +172,18 @@ void Ship::func_jump(std::string const &args) entity_eventstate = core::Entity::Normal; return; } - initiate_jump(find_closest_jumppoint()); } } JumpPoint * Ship::find_closest_jumppoint() { - // find closest jumppoint + // find closest jumpgate or 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) { + if ((entity->moduletype() == jumppoint_enttype) || (entity->moduletype() == jumpgate_enttype)) { JumpPoint *te = static_cast(entity); float d1 = math::distance(location(), te->location()); if ((d < 0) || (d1 < d)) { diff --git a/src/game/base/shipdealer.cc b/src/game/base/shipdealer.cc new file mode 100644 index 0000000..1a827ec --- /dev/null +++ b/src/game/base/shipdealer.cc @@ -0,0 +1,145 @@ +/* + base/shipdealer.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 "auxiliary/functions.h" +#include "base/game.h" +#include "base/planet.h" +#include "base/shipdealer.h" +#include "base/station.h" +#include "sys/sys.h" + +namespace game { + +ShipDealer::ShipDealer() +{ +} + +ShipDealer::~ShipDealer() +{ + dealer_models.clear(); +} + +ShipModel *ShipDealer::add(const std::string &modelname) +{ + ShipModel *model = ShipModel::find(modelname); + + if (!model) { + con_warn << "Ship model '" + modelname + "' not found" << std::endl; + return 0; + } + + for (Models::iterator it = dealer_models.begin(); it != dealer_models.end(); it++) { + if ((*it) == model) { + con_warn << "Ship dealer already has " + model->name() << std::endl; + return 0; + } + } + dealer_models.push_back(model); + return model; +} + +ShipModel *ShipDealer::find(const std::string &modelname) const +{ + for (Models::const_iterator it = dealer_models.begin(); it != dealer_models.end(); it++) { + if ((*it)->label().compare(modelname) == 0) { + return (*it); + } + } + + return 0; +} + +ShipModel *ShipDealer::find(ShipModel *shipmodel) const +{ + for (Models::const_iterator it = dealer_models.begin(); it != dealer_models.end(); it++) { + if ((*it) == shipmodel) { + return (*it); + } + } + + return 0; +} + +// a player buys a ship +void ShipDealer::func_buy(core::Player *player, const std::string &args) +{ + core::Entity *dock = player->view(); + ShipModel *shipmodel = 0; + ShipDealer *shipdealer = 0; + + // find the ship model + std::string shipname; + std::string helpstr; + std::istringstream is(args); + is >> shipname; + aux::to_label(shipname); + + if (shipname.size()) { + 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->send("Usage: buy [^B" + helpstr + "^N]"); + return; + } + + /// find the ship dealer we're buying the ship from + if (player->view()) { + if (player->view()->moduletype() == station_enttype) { + shipdealer = static_cast(player->view())->shipdealer(); + } else if (player->view()->moduletype() == planet_enttype) { + shipdealer = static_cast(player->view())->shipdealer(); + } + } + + if (!Game::g_devel->value()) { + if (!shipdealer) { + player->send("No ship dealer available"); + return; + } + + if (!shipdealer->find(shipmodel)) { + player->send("Ship dealer does not sell the " + shipmodel->name()); + return; + } + } + + // player has only ship for now + if (player->control()) { + player->remove_asset(player->control()); + } + + Ship * ship = new Ship(player, shipmodel); + if (dock) { + ship->set_zone(dock->zone()); + ship->location().assign(dock->location()); + ship->set_eventstate(core::Entity::Docked); + ship->entity_axis.assign(dock->axis()); + ship->entity_axis.change_direction(180.0f); + player->set_control(ship); + player->set_view(dock); + } else { + ship->set_zone(player->zone()); + player->set_control(ship); + } + + player->send("^BPurchased " + aux::article(shipmodel->name())); + player->sound("game/buy-ship"); + + +} + + +} diff --git a/src/game/base/shipdealer.h b/src/game/base/shipdealer.h new file mode 100644 index 0000000..48f9835 --- /dev/null +++ b/src/game/base/shipdealer.h @@ -0,0 +1,43 @@ +/* + base/shipdealer.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_SHIPDEALER_H__ +#define __INCLUDED_BASE_SHIPDEALER_H__ + +#include + +#include "base/shipmodel.h" +#include "core/entity.h" + +namespace game { + +class ShipDealer +{ +public: + typedef std::list Models; + + ShipDealer(); + ~ShipDealer(); + + /// add a ship model to the dealer list + ShipModel *add(const std::string &modelname); + + /// find a ship model in the dealer list + ShipModel *find(const std::string &modelname) const; + + /// find a ship model in the dealer list + ShipModel *find(ShipModel *shipmodel) const; + + static void func_buy(core::Player *player, const std::string &args); + +private: + Models dealer_models; +}; + +} + +#endif // __INCLUDED_BASE_SHIPDEALER_H__ + diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc index 66e752e..b4b60f4 100644 --- a/src/game/base/shipmodel.cc +++ b/src/game/base/shipmodel.cc @@ -48,6 +48,16 @@ void ShipModel::list() con_print << registry.size() << " registered ship models\n"; } +ShipModel *ShipModel::find(ShipModel *shipmodel) +{ + for (iterator smit = registry.begin(); smit != registry.end(); smit++) { + if ((*smit).second == shipmodel) + return shipmodel; + } + + return 0; +} + ShipModel *ShipModel::find(const std::string label) { std::map::iterator it = registry.find(label); diff --git a/src/game/base/shipmodel.h b/src/game/base/shipmodel.h index 277eccd..6452b8d 100644 --- a/src/game/base/shipmodel.h +++ b/src/game/base/shipmodel.h @@ -47,6 +47,7 @@ public: /// indicates of this model can be equiped with a jump drive bool shipmodel_jumpdrive; + static ShipModel *find(ShipModel *shipmodel); static ShipModel *find(const std::string label); /// the ship model registry diff --git a/src/game/base/station.cc b/src/game/base/station.cc new file mode 100644 index 0000000..4efd662 --- /dev/null +++ b/src/game/base/station.cc @@ -0,0 +1,35 @@ +/* + base/station.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/game.h" +#include "base/station.h" +#include "sys/sys.h" + +namespace game { + +Station::Station() : Entity() +{ + entity_moduletypeid = station_enttype; + set_flag(core::Entity::Dockable); + station_shipdealer = 0; +} + +Station::~Station() +{ + if (station_shipdealer) + delete station_shipdealer; +} + +void Station::set_shipdealer(ShipDealer *shipdealer) +{ + if (station_shipdealer) + delete station_shipdealer; + + station_shipdealer = shipdealer; +} + +} + diff --git a/src/game/base/station.h b/src/game/base/station.h new file mode 100644 index 0000000..0495ee6 --- /dev/null +++ b/src/game/base/station.h @@ -0,0 +1,32 @@ +/* + base/station.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_STATION_H__ +#define __INCLUDED_BASE_STATION_H__ + +#include "base/shipdealer.h" + +namespace game { + +class Station : public core::Entity +{ +public: + Station(); + virtual ~Station(); + + inline ShipDealer *shipdealer() { return station_shipdealer; } + + void set_shipdealer(ShipDealer *shipdealer); + +private: + ShipDealer *station_shipdealer; + +}; + +} + +#endif // __INCLUDED_BASE_SHIPDEALER_H__ + -- cgit v1.2.3