Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/base/game.cc')
-rw-r--r--src/game/base/game.cc332
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;
}