Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2015-01-25 20:24:40 +0000
committerStijn Buys <ingar@osirion.org>2015-01-25 20:24:40 +0000
commit5bbbdc24293ad1138a0b93628f7d28f8b249b92d (patch)
tree52095645725b7debf6a1a304ffe4e119e1b7ac90
parentcd30cd33b8b78343f0edcc29ac07fa5bd1b844bd (diff)
Added support for default player characters when joining a game.
-rw-r--r--src/game/base/Makefile.am2
-rw-r--r--src/game/base/character.cc75
-rw-r--r--src/game/base/character.h119
-rw-r--r--src/game/base/game.cc332
-rw-r--r--src/game/base/game.h8
-rw-r--r--src/game/base/savegame.cc2
-rw-r--r--src/game/base/shipmodel.cc6
7 files changed, 449 insertions, 95 deletions
diff --git a/src/game/base/Makefile.am b/src/game/base/Makefile.am
index 5ac64c8..80e2bd8 100644
--- a/src/game/base/Makefile.am
+++ b/src/game/base/Makefile.am
@@ -6,6 +6,7 @@ noinst_LTLIBRARIES = libbase.la
noinst_HEADERS = \
cargo.h \
cargopod.h \
+ character.h \
game.h \
faction.h \
jumppoint.h \
@@ -29,6 +30,7 @@ noinst_HEADERS = \
libbase_la_SOURCES = \
cargo.cc \
cargopod.cc \
+ character.cc \
faction.cc \
game.cc \
jumppoint.cc \
diff --git a/src/game/base/character.cc b/src/game/base/character.cc
new file mode 100644
index 0000000..ceb5ff4
--- /dev/null
+++ b/src/game/base/character.cc
@@ -0,0 +1,75 @@
+/*
+ base/character.cc
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "base/character.h"
+
+namespace game
+{
+
+Character::Character() : core::Label()
+{
+ _spawn = 0;
+ _faction = 0;
+ _shipmodel = 0;
+ _cannon = 0;
+ _turret = 0;
+
+ _level = 1;
+ _credits = 0;
+}
+
+Character::Character(const Character & other) : core::Label(other)
+{
+ _spawn = other._spawn;
+ _faction = other._faction;
+ _shipmodel = other._shipmodel;
+ _cannon = other._cannon;
+ _turret = other._turret;
+
+ _level = other._level;
+ _credits = other._credits;
+}
+
+Character::~Character()
+{
+}
+
+void Character::set_spawn(core::Entity *spawn)
+{
+ _spawn = spawn;
+}
+
+void Character::set_faction(const Faction *faction)
+{
+ _faction = faction;
+}
+
+void Character::set_shipmodel(const ShipModel *shipmodel)
+{
+ _shipmodel = shipmodel;
+}
+
+void Character::set_cannon(const Weapon *cannon)
+{
+ _cannon = cannon;
+}
+
+void Character::set_turret(const Weapon *turret)
+{
+ _turret = turret;
+}
+
+void Character::set_level(const core::Level level)
+{
+ _level = level;
+}
+
+void Character::set_credits(const long credits)
+{
+ _credits = credits;
+}
+
+} // namespace game \ No newline at end of file
diff --git a/src/game/base/character.h b/src/game/base/character.h
new file mode 100644
index 0000000..7940c73
--- /dev/null
+++ b/src/game/base/character.h
@@ -0,0 +1,119 @@
+/*
+ base/character.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_CHARACTER_H__
+#define __INCLUDED_BASE_CHARACTER_H__
+
+#include "core/label.h"
+#include "core/level.h"
+
+namespace core
+{
+
+class Entity;
+
+}; // namespace core
+
+namespace game
+{
+
+class Faction;
+class ShipModel;
+class Weapon;
+
+/**
+ * @brief contaisn default settings for new Player or NPC characters.
+ * */
+class Character : public core::Label
+{
+public:
+ /**
+ * @brief default constructor
+ * */
+ Character();
+ /**
+ * @brief copy constructor
+ * */
+ Character(const Character & other);
+ /**
+ * @brief destructor
+ * */
+ ~Character();
+
+ /* --- inspectors ------------------------------------------ */
+
+ inline core::Entity *spawn() const
+ {
+ return _spawn;
+ }
+
+ inline const Faction *faction() const
+ {
+ return _faction;
+ }
+
+ inline const ShipModel *shipmodel() const
+ {
+ return _shipmodel;
+ }
+
+ inline const Weapon *cannon() const
+ {
+ return _cannon;
+ }
+
+ inline const Weapon *turret() const
+ {
+ return _turret;
+ }
+
+ inline const core::Level level() const
+ {
+ return _level;
+ }
+
+ inline const long credits() const
+ {
+ return _credits;
+ }
+
+ /* --- mutators -------------------------------------------- */
+
+ void set_spawn(core::Entity *spawn);
+
+ void set_faction(const Faction *faction);
+
+ void set_shipmodel(const ShipModel *shipmodel);
+
+ void set_cannon(const Weapon *cannon);
+
+ void set_turret(const Weapon *turret);
+
+ void set_level(const core::Level level);
+
+ void set_credits(const long credits);
+
+ /* --- actors ---------------------------------------------- */
+
+private:
+ core::Entity *_spawn;
+
+ const Faction *_faction;
+
+ const ShipModel *_shipmodel;
+ const Weapon *_cannon;
+ const Weapon *_turret;
+
+ core::Level _level;
+
+ long _credits;
+
+}; // class Character
+
+} // namespace game
+
+#endif // __INCLUDED_BASE_CHARACTER_H__
+
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;
}
diff --git a/src/game/base/game.h b/src/game/base/game.h
index 5a93272..25d3cb1 100644
--- a/src/game/base/game.h
+++ b/src/game/base/game.h
@@ -49,6 +49,7 @@ const float jump_timer_delay = 5.0f;
const float jump_cooldown_delay = 2.0f;
const float impulse_timer_delay = 3.0f;
+class Character;
class ShipModel;
class Weapon;
@@ -56,14 +57,21 @@ class Weapon;
class Default
{
public:
+ typedef std::vector<Character *> Characters;
+
static core::Zone *zone;
+
+ /*
static core::Entity *view;
static ShipModel *shipmodel;
static Weapon *cannonmodel;
static Weapon *turretmodel;
static long credits;
+ */
static void clear();
+
+ static Characters characters;
};
/// the base Project::OSiRiON game model
diff --git a/src/game/base/savegame.cc b/src/game/base/savegame.cc
index 28f0ddb..ab2ecc2 100644
--- a/src/game/base/savegame.cc
+++ b/src/game/base/savegame.cc
@@ -286,7 +286,7 @@ void SaveGame::load_game(core::Player *player, filesystem::IniFile & inifile)
ship->set_spawn(zone->default_view());
}
if (!ship->spawn()) {
- ship->set_spawn(Default::view);
+ ship->set_spawn(Default::zone->default_view());
}
if (ship_is_docked) {
diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc
index 275514f..7159c09 100644
--- a/src/game/base/shipmodel.cc
+++ b/src/game/base/shipmodel.cc
@@ -210,12 +210,6 @@ bool ShipModel::init()
// add a new shipmodel
shipmodel = new ShipModel();
- // the first ship model is set as default, game.ini can override this later
- if (!Default::shipmodel)
- {
- Default::shipmodel = shipmodel;
- }
-
shipmodel_count++;
} else if (inifile.got_section())