diff options
Diffstat (limited to 'src/game/base/game.cc')
-rw-r--r-- | src/game/base/game.cc | 332 |
1 files changed, 244 insertions, 88 deletions
diff --git a/src/game/base/game.cc b/src/game/base/game.cc index 531d4b1..77917f6 100644 --- a/src/game/base/game.cc +++ b/src/game/base/game.cc @@ -21,6 +21,7 @@ #include "base/game.h" #include "base/cargo.h" #include "base/cargopod.h" +#include "base/character.h" #include "base/faction.h" #include "base/navpoint.h" #include "base/jumppoint.h" @@ -41,22 +42,31 @@ namespace game /* -- class Default ----------------------------------------------- */ + // default player settings core::Zone *Default::zone = 0; +/* core::Entity *Default::view = 0; ShipModel *Default::shipmodel = 0; Weapon *Default::cannonmodel = 0; Weapon *Default::turretmodel = 0; long Default::credits = 0; +*/ + +Default::Characters Default::characters; void Default::clear() { - zone = 0; - view = 0; - shipmodel = 0; - cannonmodel = 0; - turretmodel = 0; - credits = 0; + for (Characters::iterator it = characters.begin(); it != characters.end(); ++it) + { + Character *character = (*it); + if (character) + { + delete character; + (*it) = 0; + } + } + characters.clear(); } /* -- class Game static members ----------------------------------- */ @@ -78,7 +88,10 @@ core::Module *factory() void Game::func_join(core::Player *player, std::string const &args) { if (player->control()) + { + // already joined return; + } std::string message("^B"); message.append(player->name()); @@ -87,69 +100,137 @@ void Game::func_join(core::Player *player, std::string const &args) // load existing player data core::server()->module()->player_load(player); + if (player->control()) + { + // player data loaded from savegame + player->set_dirty(); + return; + } - if (!player->control()) { - player->set_credits(Default::credits); - Ship *ship = new Ship(player, Default::shipmodel); - ship->set_zone(player->zone()); - player->set_control(ship); - - // load weapons - for (core::Slots::iterator it = ship->slots()->begin(); it != ship->slots()->end(); ++it) + // find requested character + std::string character_label; + std::istringstream is(args); + if (!(is >> character_label)) + { + character_label.assign("default"); + } + else + { + aux::to_label(character_label); + } + + const Character *character = 0; + + for (Default::Characters::const_iterator it = Default::characters.begin(); it != Default::characters.end();) + { + if (character_label.compare((*it)->label()) == 0) { - core::Slot *slot = (*it); - Weapon *weapon = 0; - - if (slot->type() == model::Slot::Cannon) - { - weapon = Default::cannonmodel; - } - else if (slot->type() == model::Slot::Turret) - { - weapon = Default::turretmodel; - } - - if (weapon && (weapon->volume() <= ship->inventory()->capacity_available())) - { - // add weapon to inventory - core::Item *item = new core::Item(weapon); - item->set_flag(core::Item::Unique); - item->set_flag(core::Item::Mountable); - item->set_flag(core::Item::Unrestricted); - item->set_amount(1); - - ship->inventory()->add(item); - - // mount weapon - slot->set_item(item); - slot->set_flag(core::Slot::Active); - slot->set_flag(core::Slot::Mounted); - item->set_flag(core::Item::Mounted); - } + character = *it; + it = Default::characters.end(); } - ship->inventory()->set_dirty(); - - // dock ship at default base - core::Entity *dock = ship->zone()->default_view(); - if (dock) + else { - ship->set_dock(dock); - player->set_view(dock); + ++it; } + + } - ship->reset(); + if (!character) + { + std::ostringstream strmsg; + strmsg << "^WPlayer character definition '" << character_label << "' not found!"; + player->send(strmsg.str()); - player->send("^BYou received " + aux::article(Default::shipmodel->name())); - player->sound("game/buy-ship"); + con_print << strmsg.str() << std::endl; + return; + } + + // set player credits + player->set_credits(character->credits()); + + // set player zone + player->set_zone(character->spawn()->zone()); + + // add a new ship + Ship *ship = new Ship(player, character->shipmodel()); + ship->set_zone(character->spawn()->zone()); + + player->set_control(ship); + + // dock ship at spawn + if (character->spawn()) + { + if (character->spawn()->has_flag(core::Entity::Dockable)) + { + ship->set_dock(character->spawn()); + player->set_view(character->spawn()); + } + else + { + ship->set_location(character->spawn()->location()); + ship->set_axis(character->spawn()->axis()); + ship->nudge(); + player->set_view(0); + } + } + ship->reset(); + + // load default weapons + for (core::Slots::iterator it = ship->slots()->begin(); it != ship->slots()->end(); ++it) + { + core::Slot *slot = (*it); + const Weapon *weapon = 0; - player->reputation().clear(); - Faction::apply_default(player->reputation()); + if (slot->type() == model::Slot::Cannon) + { + weapon = character->cannon(); + } + else if (slot->type() == model::Slot::Turret) + { + weapon = character->turret(); + } + + if (weapon && (weapon->volume() <= ship->inventory()->capacity_available())) + { + // add weapon to inventory + core::Item *item = new core::Item(weapon); + item->set_flag(core::Item::Unique); + item->set_flag(core::Item::Mountable); + item->set_flag(core::Item::Unrestricted); + item->set_amount(1); + ship->inventory()->add(item); + + // mount weapon + slot->set_item(item); + slot->set_flag(core::Slot::Active); + slot->set_flag(core::Slot::Mounted); + item->set_flag(core::Item::Mounted); + } + } + ship->inventory()->set_dirty(); + + player->send("^BYou received " + aux::article(character->shipmodel()->name())); + player->sound("game/buy-ship"); + + player->reputation().clear(); + + // TODO - applay character faction reputation + Faction::apply_default(player->reputation()); + + if (character->faction()) + { + // override default reputation with faction reputation + for (core::Reputation::FactionReps::const_iterator rip = character->faction()->reputation().factionreps().begin(); rip != character->faction()->reputation().factionreps().end(); ++rip) { + player->reputation().set_reputation((*rip)->faction(), (*rip)->reputation()); + } - // reset player timestamps - player->set_time_wasted(0); - player->set_time_joined(); + player->reputation().set_reputation(character->faction(), 100.0f); } - + + // reset player timestamps + player->set_time_wasted(0); + player->set_time_joined(); + player->set_dirty(); } @@ -2910,18 +2991,22 @@ bool Game::load_settings() } long l; - std::string strval; + std::string str; + Character *character = 0; while (inifile.getline()) { if (inifile.got_section()) { - if (inifile.got_section("player")) + if (inifile.got_section("world")) { + character = 0; continue; } - else if (inifile.got_section("cargo")) + else if (inifile.got_section("character")) { + character = new Character(); + Default::characters.push_back(character); continue; } else @@ -2931,54 +3016,111 @@ bool Game::load_settings() } else if (inifile.got_key()) { - if (inifile.in_section("player")) + if (inifile.in_section("world")) { - if (inifile.got_key_long("credits", l)) + if (inifile.got_key_label("zone", str)) { - Default::credits = l; + Default::zone = core::Zone::find(str); } - else if (inifile.got_key_label("zone", strval)) + else { - Default::zone = core::Zone::find(strval); - + inifile.unknown_key(); } - else if (inifile.got_key_label("ship", strval)) + } + else if (inifile.in_section("character")) + { + if (inifile.got_key_label("label", str)) { - Default::shipmodel = ShipModel::find(strval); + character->set_label(str); } - else if (inifile.got_key_label("cannon", strval)) + else if (inifile.got_key_string("name", str)) { - Weapon *cannon = Weapon::find(strval); + aux::strip_quotes(str); + character->set_name(str); + } + else if (inifile.got_key_long("credits", l)) + { + character->set_credits(l); + } + else if (inifile.got_key_label("ship", str)) + { + character->set_shipmodel(ShipModel::find(str)); + } + else if (inifile.got_key_label("faction", str)) + { + character->set_faction(Faction::find(str)); + } + else if (inifile.got_key_label("cannon", str)) + { + Weapon *cannon = Weapon::find(str); if (!cannon) { - inifile.unknown_error("unknown weapon type '" + strval + "'"); + inifile.unknown_error("unknown weapon type '" + str + "'"); } else if (cannon->subtype() != Weapon::Cannon) { - inifile.unknown_error("weapon type '" + strval + "' is not a cannon"); + inifile.unknown_error("weapon type '" + str + "' is not a cannon"); } else { - Default::cannonmodel = cannon; + character->set_cannon(cannon); } } - else if (inifile.got_key_label("turret", strval)) + else if (inifile.got_key_label("turret", str)) { - Weapon *turret = Weapon::find(strval); + Weapon *turret = Weapon::find(str); if (!turret) { - inifile.unknown_error("unknown weapon type '" + strval + "'"); + inifile.unknown_error("unknown weapon type '" + str + "'"); } else if (turret->subtype() != Weapon::Turret) { - inifile.unknown_error("weapon type '" + strval + "' is not a turret"); + inifile.unknown_error("weapon type '" + str + "' is not a turret"); } else { - Default::turretmodel = turret; + character->set_turret(turret); } } + else if (inifile.got_key_string("spawn", str)) + { + if (!str.size()) { + continue; + } else if (str.size() < 3) { + inifile.unknown_error("spawn with invalid label '" + str + "'"); + continue; + } + size_t pos = str.find(':'); + if ((pos == std::string::npos) || (pos < 1) || (pos >= (str.size() - 1))) { + inifile.unknown_error("spawn with invalid label '" + str + "'"); + continue; + } + std::string zonelabel(str.substr(0, pos)); + std::string entitylabel(str.substr(pos + 1, str.size() - pos)); + + aux::to_label(zonelabel); + aux::to_label(entitylabel); + + core::Zone *spawn_zone = core::Zone::find(zonelabel); + if (!spawn_zone) { + inifile.unknown_error("spawn with invalid zone'" + zonelabel + "'"); + continue; + } + + core::Entity *spawn_entity = spawn_zone->find_entity(entitylabel); + if (!spawn_entity) { + inifile.unknown_error("spawn with invalid entity'" + str + "'"); + continue; + } + + if (!spawn_entity->has_flag(core::Entity::Dockable)) { + inifile.unknown_error("spawn '" + str + "' is not dockable"); + continue; + } + + character->set_spawn(spawn_entity); + } else { inifile.unknown_key(); @@ -2988,6 +3130,28 @@ bool Game::load_settings() } inifile.close(); + + // validate character entries + for (Default::Characters::const_iterator it = Default::characters.begin(); it != Default::characters.end(); ++it) + { + const Character *character = (*it); + + if (!character->label().size()) + { + con_error << "Character definition without label!\n"; + return false; + } + else if (!character->spawn()) + { + con_error << "Character definition '" + character->label() + "' without spawn!\n"; + return false; + } + else if (!character->shipmodel()) + { + con_error << "Character definition '" + character->label() + "' without shipmodel!\n"; + return false; + } + } if (!Default::zone) { @@ -3001,14 +3165,6 @@ bool Game::load_settings() return false; } - Default::view = Default::zone->default_view(); - - if (!Default::shipmodel) - { - con_error << "No default ship model found!\n"; - return false; - } - return true; } |