Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game/base/Makefile.am2
-rw-r--r--src/game/base/game.cc81
-rw-r--r--src/game/base/npctype.cc71
-rw-r--r--src/game/base/npctype.h122
-rw-r--r--src/game/base/patrol.cc114
-rw-r--r--src/game/base/patrol.h9
-rw-r--r--src/game/base/shipmodel.cc3
-rw-r--r--src/game/base/shipmodel.h21
8 files changed, 354 insertions, 69 deletions
diff --git a/src/game/base/Makefile.am b/src/game/base/Makefile.am
index 634a571..7289545 100644
--- a/src/game/base/Makefile.am
+++ b/src/game/base/Makefile.am
@@ -11,6 +11,7 @@ noinst_HEADERS = \
jumppoint.h \
navpoint.h \
npc.h \
+ npctype.h \
patrol.h \
planet.h \
racetrack.h \
@@ -31,6 +32,7 @@ libbase_la_SOURCES = \
jumppoint.cc \
navpoint.cc \
npc.cc \
+ npctype.cc \
patrol.cc \
planet.cc \
racetrack.cc \
diff --git a/src/game/base/game.cc b/src/game/base/game.cc
index f2db00c..46151f9 100644
--- a/src/game/base/game.cc
+++ b/src/game/base/game.cc
@@ -1833,6 +1833,7 @@ bool Game::load_zone(core::Zone *zone)
Patrol *patrol = 0;
Patrol::WayPoint *patrol_waypoint = 0;
+ NPCType *patrol_npctype = 0;
bool b;
long l;
@@ -1897,18 +1898,31 @@ bool Game::load_zone(core::Zone *zone)
patrol->set_zone(zone);
patrol_waypoint = 0;
+ patrol_npctype = 0;
} else if (zoneini.got_section("waypoint")) {
patrol_waypoint = 0;
+ patrol_npctype = 0;
- if (!entity || !patrol) {
+ if (!entity || !patrol || (patrol != entity)) {
zoneini.unknown_error("waypoint definition without patrol");
} else if ((entity->moduletype() != patrol_enttype)) {
zoneini.unknown_error("waypoint definition for invalid entity type");
} else {
patrol_waypoint = patrol->add_waypoint();
}
-
+ } else if (zoneini.got_section("npc")) {
+ patrol_waypoint = 0;
+ patrol_npctype = 0;
+
+ if (!entity || !patrol || (patrol != entity)) {
+ zoneini.unknown_error("npc definition without patrol");
+ } else if ((entity->moduletype() != patrol_enttype)) {
+ zoneini.unknown_error("npc definition for invalid entity type");
+ } else {
+ patrol_npctype = patrol->add_npctype();
+ }
+
} else if (zoneini.got_section("planet")) {
planet = new Planet();
entity = planet;
@@ -1951,7 +1965,7 @@ bool Game::load_zone(core::Zone *zone)
if (!entity) {
zoneini.unknown_error("ship definition without entity");
- } else if ((entity->moduletype() != planet_enttype) && (entity->moduletype() != station_enttype) && (entity->moduletype() != patrol_enttype)) {
+ } else if ((entity->moduletype() != planet_enttype) && (entity->moduletype() != station_enttype)) {
zoneini.unknown_error("ship definition for invalid entity type");
} else {
inventory = entity->inventory();
@@ -2104,7 +2118,7 @@ bool Game::load_zone(core::Zone *zone)
}
} else if (zoneini.in_section("waypoint")) {
- if (!patrol_waypoint) {
+ if (!patrol || (patrol != entity) || !patrol_waypoint ) {
continue;
} else if (zoneini.got_key_string("target", strval)) {
patrol_waypoint->set_target_label(strval);
@@ -2122,6 +2136,52 @@ bool Game::load_zone(core::Zone *zone)
} else {
zoneini.unknown_key();
}
+
+ } else if (zoneini.in_section("npc")) {
+ if (!patrol || (patrol != entity) || !patrol_npctype) {
+ continue;
+ } else if (zoneini.got_key_string("name", strval)) {
+ aux::strip_quotes(strval);
+ patrol_npctype->set_name(strval);
+ } else if (zoneini.got_key_long("amount", l)) {
+ patrol_npctype->set_amount(l);
+ } else if (zoneini.got_key_bool("merchant", b)) {
+ patrol_npctype->set_merchant(b);
+ } else if (zoneini.got_key_label("ship", strval)) {
+ ShipModel *shipmodel = ShipModel::find(strval);
+ if (!shipmodel) {
+ zoneini.unknown_error("unknown ship type '" + strval + "'");
+ } else {
+ patrol_npctype->set_shipmodel(shipmodel);
+ }
+ } else if (zoneini.got_key_label("faction", strval)) {
+ Faction *faction = Faction::find(strval);
+ if (!faction) {
+ zoneini.unknown_error("unknown faction '" + strval + "'");
+ } else {
+ patrol_npctype->set_faction(faction);
+ }
+ } else if (zoneini.got_key_label("cannon", strval)) {
+ Weapon *cannon = Weapon::find(strval);
+ if (!cannon) {
+ zoneini.unknown_error("unknown weapon type '" + strval + "'");
+ } else if (cannon->subtype() != Weapon::Cannon) {
+ zoneini.unknown_error("weapon type '" + strval + "' is not a cannon");
+ } else {
+ patrol_npctype->set_cannon(cannon);
+ }
+ } else if (zoneini.got_key_label("turret", strval)) {
+ Weapon *turret = Weapon::find(strval);
+ if (!turret) {
+ zoneini.unknown_error("unknown weapon type '" + strval + "'");
+ } else if (turret->subtype() != Weapon::Turret) {
+ zoneini.unknown_error("weapon type '" + strval + "' is not a turret");
+ } else {
+ patrol_npctype->set_turret(turret);
+ }
+ } else {
+ zoneini.unknown_key();
+ }
} else if (zoneini.in_section("planet")) {
if (core::Parser::got_entity_key(zoneini, planet)) {
@@ -2333,21 +2393,14 @@ bool Game::load_zone(core::Zone *zone)
if (!item) {
item = new core::Item(shipmodel);
- if ((entity->moduletype() == patrol_enttype)) {
- item->set_amount(1);
- } else {
- item->set_amount(-1);
- }
+ item->set_amount(-1);
item->set_price(shipmodel->price());
inventory->add(item);
}
} else {
zoneini.unknown_error("unknown ship type '" + strval + "'");
}
- } else if ((entity->moduletype() == patrol_enttype) && zoneini.got_key_long("amount", l)) {
- if (item) {
- item->set_amount(l);
- }
+
} else if (zoneini.got_key_long("price", l)) {
if (item) {
item->set_price(l);
@@ -2446,7 +2499,7 @@ bool Game::generate_entity_menus(core::Entity *entity)
size_t nbweapon = 0;
size_t nbships = 0;
- for (core::Inventory::Items::const_iterator it = entity->inventory()->items().begin(); it != entity->inventory()->items().end(); it++) {
+ for (core::Inventory::Items::const_iterator it = entity->inventory()->items().begin(); it != entity->inventory()->items().end(); ++it) {
core::Item *item = (*it);
if (item->info()->type() == Cargo::infotype()) {
diff --git a/src/game/base/npctype.cc b/src/game/base/npctype.cc
new file mode 100644
index 0000000..f44cc1f
--- /dev/null
+++ b/src/game/base/npctype.cc
@@ -0,0 +1,71 @@
+/*
+ base/npctype.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
+*/
+
+#include "base/npctype.h"
+
+namespace game
+{
+
+NPCType::NPCType() :
+ npctype_name()
+{
+ npctype_amount = 1;
+ npctype_merchant = false;
+
+ npctype_faction = 0;
+ npctype_shipmodel = 0;
+
+ npctype_cannon = 0;
+ npctype_turret = 0;
+}
+
+
+NPCType::~NPCType()
+{
+ // clear pointers
+ npctype_faction = 0;
+ npctype_shipmodel = 0;
+
+ npctype_cannon = 0;
+ npctype_turret = 0;
+}
+
+void NPCType::set_name(const std::string &name)
+{
+ npctype_name.assign(name);
+}
+
+void NPCType::set_amount(const long amount)
+{
+ npctype_amount = amount;
+}
+
+void NPCType::set_merchant(const bool is_merchant)
+{
+ npctype_merchant = is_merchant;
+}
+
+void NPCType::set_faction(const Faction *faction)
+{
+ npctype_faction = faction;
+}
+
+void NPCType::set_shipmodel(const ShipModel *shipmodel)
+{
+ npctype_shipmodel = shipmodel;
+}
+
+void NPCType::set_cannon(const Weapon *cannon)
+{
+ npctype_cannon = cannon;
+}
+
+void NPCType::set_turret(const Weapon *turret)
+{
+ npctype_turret = turret;
+}
+
+} // namespace game
diff --git a/src/game/base/npctype.h b/src/game/base/npctype.h
new file mode 100644
index 0000000..fd9515f
--- /dev/null
+++ b/src/game/base/npctype.h
@@ -0,0 +1,122 @@
+/*
+ base/npctype.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_NPCTYPE_H__
+#define __INCLUDED_BASE_NPCTYPE_H__
+
+#include "base/faction.h"
+#include "base/shipmodel.h"
+#include "base/weapon.h"
+
+namespace game
+{
+
+/**
+ * @brief NPC generation information
+ * Used by Patrols to generate NPC instances
+ * */
+class NPCType {
+
+public:
+ /**
+ * @brief constructor
+ * */
+ NPCType();
+
+ /**
+ * @brief destructor
+ * */
+ ~NPCType();
+
+ /* --- inspectors ------------------------------------------ */
+
+ /**
+ * @brief entity name to be used by the NPC
+ * */
+ inline const std::string &name() const
+ {
+ return npctype_name;
+ }
+
+ /**
+ * @brief the maximal amount of NPCs of this type to generate
+ * */
+ inline const long amount() const
+ {
+ return npctype_amount;
+ }
+
+ /**
+ * @brief true if the NPC will buy cargo
+ * */
+ inline const bool is_merchant() const
+ {
+ return npctype_merchant;
+ }
+
+ /**
+ * @brief the faction the NPC will belong to
+ * */
+ inline const Faction *faction() const
+ {
+ return npctype_faction;
+ }
+
+ /**
+ * @brief the shipmodel the NPC will use
+ * */
+ inline const ShipModel *shipmodel() const
+ {
+ return npctype_shipmodel;
+ }
+
+ /**
+ * @brief the type of cannons the NPC will use
+ * */
+ inline const Weapon *cannon() const
+ {
+ return npctype_cannon;
+ }
+
+ /**
+ * @brief the type of turrets the NPC will use
+ * */
+ inline const Weapon *turret() const
+ {
+ return npctype_turret;
+ }
+
+ /* --- mutators -------------------------------------------- */
+
+ void set_name(const std::string &name);
+
+ void set_amount(const long amount);
+
+ void set_merchant(const bool is_merchant = false);
+
+ void set_faction(const Faction *faction);
+
+ void set_shipmodel(const ShipModel *shipmodel);
+
+ void set_cannon(const Weapon *cannon);
+
+ void set_turret(const Weapon *turret);
+
+private:
+ std::string npctype_name;
+ long npctype_amount;
+ bool npctype_merchant;
+
+ const Faction *npctype_faction;
+ const ShipModel *npctype_shipmodel;
+
+ const Weapon *npctype_cannon;
+ const Weapon *npctype_turret;
+};
+
+} // namespace game
+
+#endif // __INCLUDED_BASE_NPCTYPE_H__
diff --git a/src/game/base/patrol.cc b/src/game/base/patrol.cc
index 850efb9..f3cfa07 100644
--- a/src/game/base/patrol.cc
+++ b/src/game/base/patrol.cc
@@ -79,6 +79,13 @@ Patrol::~Patrol()
}
patrol_waypoints.clear();
+ // delete npc types
+ for (NPCTypes::iterator it = patrol_npctypes.begin(); it != patrol_npctypes.end(); ++it) {
+ delete(*it);
+ (*it) = 0;
+ }
+ patrol_npctypes.clear();
+
// detach and delete remaining members
for (Members::iterator it = patrol_members.begin(); it != patrol_members.end(); ++it) {
NPC *member = (*it);
@@ -167,22 +174,12 @@ void Patrol::validate()
++it;
}
}
-
- size_t nbships = 0;
- for (core::Inventory::Items::const_iterator it = inventory()->items().begin(); it != inventory()->items().end(); it++) {
- core::Item *item = (*it);
-
- if (item->info()->type() == ShipModel::infotype()) {
- nbships++;
- }
- }
-
+
if (patrol_waypoints.size() == 0) {
con_warn << " Patrol '" << label() << "' without waypoints" << "\n";
- die();
-
- } else if (nbships == 0) {
- con_warn << " Patrol '" << label() << "' without ship types" << "\n";
+ die();
+ } else if (patrol_npctypes.size() == 0) {
+ con_warn << " Patrol '" << label() << "' without NPC types" << "\n";
die();
} else if (!(*patrol_waypoints.begin())->target()->has_flag(core::Entity::Dockable)) {
con_warn << " Patrol '" << label() << "' spawn set to non-dockable target" << "\n";
@@ -194,10 +191,10 @@ void Patrol::validate()
// spawn waypoint is current
patrol_waypoint_current = patrol_waypoints.begin();
- con_debug << " " << label() << " patrol " << patrol_waypoints.size() << " " << aux::plural("waypoint", patrol_waypoints.size()) << " "
- << nbships << " ship " << aux::plural("type", nbships) << std::endl;
+ con_debug << " " << label() << " patrol "
+ << patrol_waypoints.size() << " " << aux::plural("waypoint", patrol_waypoints.size()) << " "
+ << patrol_npctypes.size() << " npc " << aux::plural("type", patrol_npctypes.size()) << std::endl;
}
-
}
Patrol::WayPoint *Patrol::add_waypoint()
@@ -209,6 +206,15 @@ Patrol::WayPoint *Patrol::add_waypoint()
return waypoint;
}
+NPCType *Patrol::add_npctype()
+{
+ NPCType *npctype = new NPCType();
+
+ patrol_npctypes.push_back(npctype);
+
+ return npctype;
+}
+
void Patrol::add_member(NPC *npc)
{
npc->set_patrol(this);
@@ -279,33 +285,34 @@ void Patrol::frame(const unsigned long elapsed)
if (spawn->has_flag(core::Entity::Dockable)) {
- // create NPC members for every ship in the patrol's inventory
- for (core::Inventory::Items::const_iterator it = inventory()->items().begin(); it != inventory()->items().end(); it++) {
- core::Item *item = (*it);
-
- if (item->info()->type() != ShipModel::infotype()) {
+ // create NPC members for every NPC type
+ for (NPCTypes::const_iterator it = patrol_npctypes.begin(); it != patrol_npctypes.end(); ++it) {
+
+ NPCType *npctype = (*it);
+
+ if (!npctype->shipmodel()) {
continue;
}
- // find shipmodel
- ShipModel *shipmodel = ShipModel::find(item->info()->label());
- if (!shipmodel) {
+ if (npctype->amount() <= 0) {
continue;
}
- const size_t nbships = 1 + math::randomi(item->amount());
+ const size_t nbships = 1 + math::randomi((unsigned int) npctype->amount());
for (size_t i = 0; i < nbships; i++) {
// add NPC
- NPC *npc = new NPC(patrol_profile, shipmodel);
+ NPC *npc = new NPC(patrol_profile, npctype->shipmodel());
// set NPC name
- if (shipmodel->npc_name().size()) {
- npc->set_name(shipmodel->npc_name());
+ if (npctype->name().size()) {
+ npc->set_name(npctype->name());
}
// set NPC color
- if (faction()) {
+ if (npctype->faction()) {
+ npctype->faction()->apply(npc);
+ } else if (faction()) {
faction()->apply(npc);
}
@@ -313,13 +320,57 @@ void Patrol::frame(const unsigned long elapsed)
if (npc->has_flag(core::Entity::Dockable)) {
unset_flag(core::Entity::Dockable);
// delete menus
- for (Menus::iterator mit = npc->menus().begin(); mit != npc->menus().end(); mit++) {
+ for (Menus::iterator mit = npc->menus().begin(); mit != npc->menus().end(); ++mit) {
delete (*mit);
(*mit) = 0;
}
npc->menus().clear();
}
+ // install inventory
+ if (!npc->inventory()) {
+ npc->add_inventory();
+ }
+
+ // install slots
+ if (!npc->slots()) {
+ npc->add_slots();
+ slots()->load(model());
+ }
+
+ // install weapons
+ for (core::Slots::iterator slit = npc->slots()->begin(); slit != npc->slots()->end(); ++slit) {
+ core::Slot *slot = (*slit);
+
+ core::Item *item = 0;
+
+ if (slot->type() == model::Weapon::Cannon) {
+ if (npctype->cannon()) {
+ item = new core::Item(npctype->cannon());
+ }
+ } else if (slot->type() == model::Weapon::Turret) {
+ if (npctype->turret()) {
+ item = new core::Item(npctype->turret());
+ }
+ }
+
+ if (item) {
+ // add item
+ item->set_flag(core::Item::Unique);
+ item->set_flag(core::Item::Mountable);
+ item->set_flag(core::Item::Unrestricted);
+ item->set_amount(1);
+ npc->inventory()->add(item);
+
+ // mount weapon
+ slot->set_item(item);
+ slot->set_flag(core::Slot::Active);
+ slot->set_flag(core::Slot::Mounted);
+ }
+ }
+
+ npc->inventory()->recalculate();
+
// dock npc at spawn
npc->set_zone(spawn->zone());
npc->set_dock(spawn);
@@ -362,6 +413,7 @@ void Patrol::frame(const unsigned long elapsed)
NPC *member = (*mit);
// buy cargo if requested
+ // FIXME apply NPCType is_merchant
if (waypoint()->dock() && waypoint()->cargo() && member->inventory()) {
// erase all cargo from inventory
diff --git a/src/game/base/patrol.h b/src/game/base/patrol.h
index 0e03234..e4ba19b 100644
--- a/src/game/base/patrol.h
+++ b/src/game/base/patrol.h
@@ -11,6 +11,7 @@
#include "base/faction.h"
#include "base/cargo.h"
#include "base/npc.h"
+#include "base/npctype.h"
namespace game
{
@@ -76,6 +77,8 @@ public:
typedef std::list<WayPoint *> WayPoints;
+ typedef std::list<NPCType *> NPCTypes;
+
typedef std::list<NPC *> Members;
Patrol();
@@ -106,6 +109,8 @@ public:
void set_faction(Faction *faction);
WayPoint *add_waypoint();
+
+ NPCType *add_npctype();
virtual void validate();
@@ -113,7 +118,7 @@ public:
void add_member(NPC *npc);
- void erase_member(NPC *npc);
+ void erase_member(NPC *npc);
private:
void set_leader();
@@ -126,6 +131,8 @@ private:
Members patrol_members;
+ NPCTypes patrol_npctypes;
+
NPC::Profile patrol_profile;
NPC *patrol_leader;
diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc
index 3582517..6fd809b 100644
--- a/src/game/base/shipmodel.cc
+++ b/src/game/base/shipmodel.cc
@@ -74,9 +74,6 @@ bool ShipModel::init()
} else if (inifile.got_key_string("name", str)) {
shipmodel->set_name(str);
continue;
- } else if (inifile.got_key_string("npcname", str)) {
- shipmodel->set_npc_name(str);
- continue;
} else if (inifile.got_key_string("info", str)) {
shipmodel->add_text(str);
continue;
diff --git a/src/game/base/shipmodel.h b/src/game/base/shipmodel.h
index 2231fea..9849cd0 100644
--- a/src/game/base/shipmodel.h
+++ b/src/game/base/shipmodel.h
@@ -114,14 +114,6 @@ public:
return shipmodel_radius;
}
- /**
- * @brief name used for NPCs with this ship model
- * */
- inline const std::string & npc_name() const
- {
- return shipmodel_npc_name;
- }
-
/// entity template
inline const Template *model_template() const
{
@@ -238,15 +230,7 @@ protected:
{
shipmodel_angular_damping = angular_damping;
}
-
- /**
- * @brief set the name used for NPCs with this ship model
- * */
- inline void set_npc_name(const std::string name)
- {
- shipmodel_npc_name.assign(name);
- }
-
+
public:
/**
* @brief generate specifications info.
@@ -285,7 +269,6 @@ private:
float shipmodel_turn_force;
float shipmodel_roll_force;
-// float shipmodel_maxspeed;
float shipmodel_maxcargo;
float shipmodel_maxarmor;
float shipmodel_maxshield;
@@ -295,8 +278,6 @@ private:
const Template *shipmodel_template;
- std::string shipmodel_npc_name;
-
/* --- static ----------------------------------------------------- */
static core::InfoType *shipmodel_infotype;