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/cargopod.cc3
-rw-r--r--src/game/base/game.cc139
-rw-r--r--src/game/base/game.h6
-rw-r--r--src/game/base/patrol.cc2
-rw-r--r--src/game/base/ship.cc132
-rw-r--r--src/game/base/ship.h7
6 files changed, 197 insertions, 92 deletions
diff --git a/src/game/base/cargopod.cc b/src/game/base/cargopod.cc
index 67ae51e..d6e72c9 100644
--- a/src/game/base/cargopod.cc
+++ b/src/game/base/cargopod.cc
@@ -41,8 +41,9 @@ CargoPod::CargoPod() : EntityDynamic()
set_mass(radius());
reset();
+ // increased dampening for cargo pods
const float damp = Game::g_damping->value();
- body()->setDamping(damp, damp);
+ body()->setDamping(damp * 2.0f, damp * 2.0f);
}
CargoPod::~CargoPod()
diff --git a/src/game/base/game.cc b/src/game/base/game.cc
index b3fb415..6921f72 100644
--- a/src/game/base/game.cc
+++ b/src/game/base/game.cc
@@ -63,6 +63,7 @@ core::Cvar *Game::g_jumppointrange = 0;
core::Cvar *Game::g_devel = 0;
core::Cvar *Game::g_damping = 0;
core::Cvar *Game::g_deplete = 0;
+core::Cvar *Game::g_cargoloss = 0;
core::Module *factory()
{
@@ -121,8 +122,9 @@ void Game::func_spectate(core::Player *player, std::string const &args)
player->remove_asset(player->control());
}
- if (!player->zone())
+ if (!player->zone()) {
player->set_zone(Default::zone);
+ }
player->set_view(0);
}
@@ -1229,109 +1231,38 @@ void Game::func_eject(core::Player *player, const std::string &args)
return;
}
- core::EntityControlable *ejector = player->control();
+ if (player->control()->moduletype() != ship_enttype) {
+ return;
+ }
+ Ship * ship = static_cast<Ship *>(player->control());
+
// cannot eject while jumping
- if ((ejector->state() == core::Entity::Jump) || (ejector->state() == core::Entity::JumpInitiate)) {
- if (ejector->owner()) {
- ejector->owner()->send("^WCan not eject while hyperspace jump drive is active");
+ if ((ship->state() == core::Entity::Jump) || (ship->state() == core::Entity::JumpInitiate)) {
+ if (ship->owner()) {
+ ship->owner()->send("^WCan not eject while hyperspace jump drive is active");
}
return;
}
// find the item in the inventory
- core::Item *item = ejector->inventory()->find(id);
+ core::Item *item = ship->inventory()->find(id);
if (!item) {
- if (ejector->owner()) {
+ if (ship->owner()) {
std::stringstream msgstr;
msgstr << "^WItem " << id << " not in inventory";
- ejector->owner()->send(msgstr.str());
+ ship->owner()->send(msgstr.str());
}
return;
}
if (!item->amount()) {
- if (ejector->owner()) {
- ejector->owner()->send("^WYou do not own any " + item->info()->name());
+ if (ship->owner()) {
+ ship->owner()->send("^WYou do not own any " + item->info()->name());
}
return;
- }
-
- if ((amount < 0) || (amount > item->amount())) {
- amount = item->amount();
}
- item->dec_amount(amount);
- if (ejector->state() == core::Entity::Docked) {
- if (ejector->owner()) {
- std::stringstream msgstr;
- msgstr << "^BDestroyed " << amount << " " << aux::plural("unit", amount) << " of " << item->info()->name();
- ejector->owner()->send(msgstr.str());
- ejector->owner()->sound("game/eject");
- }
- } else {
- // create cargo pod
- CargoPod *pod = new CargoPod();
-
- if (item->info()->modelname().size()) {
- pod->set_name(item->info()->name());
- // setting item modesl looks silly, but can be uncommented server-side
- //pod->set_modelname(item->info()->modelname());
- }
- pod->set_color(ejector->color());
- pod->set_color_second(ejector->color_second());
- pod->set_location(ejector->location() + ejector->axis().up() * (ejector->radius() + pod->radius()));
- pod->set_axis(ejector->axis());
- pod->set_zone(ejector->zone());
- pod->set_info(item->info());
-
- // add loot to inventory
- pod->add_inventory();
- pod->inventory()->set_capacity(item->info()->volume() * amount);
-
- core::Item *loot = new core::Item(item->info());
- loot->set_amount(amount);
- loot->set_flags(item->flags());
- loot->unset_flag(core::Item::Mounted);
-
- pod->inventory()->add(loot);
- pod->inventory()->set_dirty();
-
- if (ejector->owner()) {
- std::stringstream msgstr;
- if (item->unique()) {
- msgstr << "^BEjected " << item->info()->name();
- } else {
- msgstr << "^BEjected " << amount << " " << aux::plural("unit", amount) << " of " << item->info()->name();
- }
- ejector->owner()->send(msgstr.str());
- ejector->owner()->sound("game/eject");
- }
-
- pod->reset();
- }
-
- if (item->amount() == 0) {
- if (item->has_flag(core::Item::Mounted)) {
- // unmount
- core::Slot *slot = 0;
-
- for(core::Slots::iterator it = ejector->slots()->begin(); (!slot) && (it != ejector->slots()->end()); ++it) {
- if ((*it)->item() == item) {
- slot = (*it);
- }
- }
-
- if (slot) {
- slot->set_item(0);
- slot->unset_flag(core::Slot::Active);
- slot->unset_flag(core::Slot::Mounted);
- item->unset_flag(core::Item::Mounted);
- }
-
- }
- ejector->inventory()->erase(item->id());
- }
- ejector->inventory()->set_dirty();
+ ship->eject(item, amount, true);
}
// mount weapons into slots
@@ -1617,16 +1548,19 @@ void Game::func_respawn(core::Player *player, std::string const &args)
// instantaniously goto a specified entity within the zone
void Game::func_goto(core::Player *player, const std::string &args)
{
- if (!args.size())
- return;
-
if (!g_devel->value()) {
player->send("Cheats disabled");
return;
}
- if (!player->control())
+ if (!player->control()) {
+ player->send("^WYou need to join the game first!");
return;
+ }
+
+ if (!args.size()) {
+ return;
+ }
core::Entity *dock = player->control()->zone()->search_entity(args);
Ship *ship = static_cast<Ship *>(player->control());
@@ -1662,6 +1596,25 @@ void Game::func_goto(core::Player *player, const std::string &args)
}
}
+// self-destruct
+void Game::func_explode(core::Player *player, const std::string &args)
+{
+ if (!g_devel->value()) {
+ player->send("Cheats disabled");
+ return;
+ }
+
+ if (!player->control()) {
+ player->send("^WYou need to join the game first!");
+ return;
+ }
+
+ assert(player->control()->moduletype() == ship_enttype);
+ Ship *ship = static_cast<Ship *>(player->control());
+
+ ship->explode();
+}
+
/* -- class Game -------------------------------------------------- */
Game::Game() : core::Module("Project::OSiRiON", true)
@@ -1762,6 +1715,9 @@ Game::Game() : core::Module("Project::OSiRiON", true)
func = core::Func::add("respawn", Game::func_respawn);
func->set_info("respawn when your ship has been destroyed");
+ func = core::Func::add("explode", Game::func_explode);
+ func->set_info("self-destruct");
+
func = core::Func::add("goto", Game::func_goto);
func->set_info("[string] goto to an entity within the zone");
@@ -1795,6 +1751,9 @@ Game::Game() : core::Module("Project::OSiRiON", true)
g_deplete = core::Cvar::get("g_deplete", "60", core::Cvar::Game | core::Cvar::Archive);
g_deplete->set_info("[int] number of seconds to deplete 1 unit of cargo from inventories");
+
+ g_cargoloss = core::Cvar::get("g_cargoloss", "100", core::Cvar::Game | core::Cvar::Archive);
+ g_cargoloss->set_info("[int] percentage of cargo to drop on player death");
}
Game::~Game()
diff --git a/src/game/base/game.h b/src/game/base/game.h
index bb1c9ae..bd8d402 100644
--- a/src/game/base/game.h
+++ b/src/game/base/game.h
@@ -86,7 +86,7 @@ public:
/* --- game variables -------------------------------------- */
- /// game variable: maximum speed of the impulse drive
+ /// game variable: maximum ship speed
static core::Cvar *g_impulsespeed;
/// game variable: jumppoint range
@@ -98,6 +98,9 @@ public:
/// game variable: number of seconds it takes for 1 unit of cargo to deplete from station inventories
static core::Cvar *g_deplete;
+ /// game variable: percentage of cargo to drop on player death
+ static core::Cvar *g_cargoloss;
+
/// physics variable: default damping factor of space
static core::Cvar *g_damping;
@@ -124,6 +127,7 @@ private:
static void func_launch(core::Player *player, std::string const &args);
static void func_respawn(core::Player *player, std::string const &args);
static void func_goto(core::Player *player, const std::string &args);
+ static void func_explode(core::Player *player, const std::string &args);
static void func_buy(core::Player *player, std::string const &args);
static void func_sell(core::Player *player, const std::string &args);
static void func_give(core::Player *player, const std::string &args);
diff --git a/src/game/base/patrol.cc b/src/game/base/patrol.cc
index 48f687e..4ad16df 100644
--- a/src/game/base/patrol.cc
+++ b/src/game/base/patrol.cc
@@ -347,6 +347,8 @@ void Patrol::frame(const unsigned long elapsed)
} else if ((patrol_leader->state() == core::Entity::Normal) || (patrol_leader->state() == core::Entity::ImpulseInitiate) || (patrol_leader->state() == core::Entity::Impulse)) {
+ patrol_launch_timeout = 0;
+
if (waypoint()->target()->zone() == patrol_leader->zone()) {
patrol_leader->set_autopilot_target(waypoint()->target());
diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc
index e800c93..cdc860a 100644
--- a/src/game/base/ship.cc
+++ b/src/game/base/ship.cc
@@ -20,6 +20,8 @@
#include "base/spacemine.h"
#include "base/jumppoint.h"
#include "base/racetrack.h"
+#include "base/cargo.h"
+#include "base/cargopod.h"
using math::degrees360f;
using math::degrees180f;
@@ -307,6 +309,112 @@ JumpPoint * Ship::find_closest_jumppoint()
return 0;
}
+void Ship::eject(core::Item *item, const long eject_amount, const bool eject_message)
+{
+ // verify whe have the item in our inventory
+ if (!inventory()->find(item)) {
+ return;
+ }
+
+ // clamp amount to what's available
+ const long amount = math::min(eject_amount, item->amount());
+ if (amount < 1) {
+ return;
+ }
+
+ // remove the requested amount
+ item->dec_amount(amount);
+
+ if (state() == Docked) {
+
+ if (eject_message && owner()) {
+ std::stringstream msgstr;
+ msgstr << "^BDestroyed " << amount << " " << aux::plural("unit", amount) << " of " << item->info()->name();
+ owner()->send(msgstr.str());
+ owner()->sound("game/eject");
+ }
+ } else {
+ // create cargo pod
+ CargoPod *pod = new CargoPod();
+
+ if (item->info()->modelname().size()) {
+ pod->set_name(item->info()->name());
+ /*
+ // setting item models looks silly, but can be uncommented server-side
+ //pod->set_modelname(item->info()->modelname());
+ */
+ }
+
+ // randomize location
+ math::Axis pod_axis;
+ pod_axis.change_direction(math::randomf(360.0f));
+ pod_axis.change_pitch(math::randomf(180.0f));
+ pod_axis.change_roll(math::randomf(360.0f));
+
+ pod->set_color(color());
+ pod->set_color_second(color_second());
+ pod->set_location(location() + pod_axis.up() * (radius() + pod->radius()));
+ pod->set_axis(pod_axis);
+ pod->set_zone(zone());
+ pod->set_info(item->info());
+
+ // add loot to inventory
+ pod->add_inventory();
+ pod->inventory()->set_capacity(item->info()->volume() * amount);
+
+ core::Item *loot = new core::Item(item->info());
+ loot->set_amount(amount);
+ loot->set_flags(item->flags());
+ loot->unset_flag(core::Item::Mounted);
+
+ pod->inventory()->add(loot);
+ pod->inventory()->set_dirty();
+
+ if (eject_message && owner()) {
+ std::stringstream msgstr;
+ if (item->unique()) {
+ msgstr << "^BEjected " << item->info()->name();
+ } else {
+ msgstr << "^BEjected " << amount << " " << aux::plural("unit", amount) << " of " << item->info()->name();
+ }
+ owner()->send(msgstr.str());
+ owner()->sound("game/eject");
+ }
+
+ // reset cargopod physics
+ pod->reset();
+
+ assert(pod->body());
+
+ const float CARGOPOD_SPEED = 0.5f;
+ pod->set_speed(CARGOPOD_SPEED);
+ pod->body()->setLinearVelocity(math::to_btVector3(pod_axis.forward() * CARGOPOD_SPEED));
+ }
+
+ if (item->amount() == 0) {
+ if (item->has_flag(core::Item::Mounted)) {
+ // unmount
+ core::Slot *slot = 0;
+
+ for(core::Slots::iterator it = slots()->begin(); (!slot) && (it != slots()->end()); ++it) {
+ if ((*it)->item() == item) {
+ slot = (*it);
+ }
+ }
+
+ if (slot) {
+ slot->set_item(0);
+ slot->unset_flag(core::Slot::Active);
+ slot->unset_flag(core::Slot::Mounted);
+ item->unset_flag(core::Item::Mounted);
+ }
+
+ }
+ inventory()->erase(item->id());
+ }
+ inventory()->set_dirty();
+}
+
void Ship::explode()
{
target_direction = 0;
@@ -322,10 +430,34 @@ void Ship::explode()
set_state(core::Entity::Destroyed);
+ // 100 % cargo loss by default
+ float percentage = 100.0f;
+
if (owner()) {
+ // make the player watch his death
if (owner()->control() == this) {
owner()->set_view(this);
}
+
+ // cargo loss % is set by the g_cargoloss CVar
+ percentage = Game::g_cargoloss->value();
+ percentage = floorf(percentage);
+ math::clamp(percentage, 0.0f, 100.0f);
+ }
+
+ if (percentage > 0) {
+ core::Inventory::Items::iterator it = inventory()->items().begin();
+
+ while (it != inventory()->items().end()) {
+ if ((*it)->info()->type() == Cargo::infotype()) {
+ long loss = (*it)->amount() * ((long) percentage) / 100l;
+ if (loss > 0) {
+ eject((*it++), loss, false);
+ continue;
+ }
+ }
+ ++it;
+ }
}
};
diff --git a/src/game/base/ship.h b/src/game/base/ship.h
index fa6e60d..e8a6505 100644
--- a/src/game/base/ship.h
+++ b/src/game/base/ship.h
@@ -214,6 +214,13 @@ public:
void launch();
void set_spawn(core::Entity *spawn);
+
+ /**
+ * @brief eject an item from inventory
+ * Ejecting an item while the ship is docked will destroy it,
+ * otherwise it will create a cargo pod
+ * */
+ void eject(core::Item *item, const long eject_amount, const bool eject_message);
protected:
/**