Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2012-11-18 15:10:37 +0000
committerStijn Buys <ingar@osirion.org>2012-11-18 15:10:37 +0000
commitab61530779c73e7e145193efcb1e23a47c16e7f3 (patch)
tree9aed75947be45585cf884effc3a59575a1b1bb8e /src
parent69b0cd536aee5cf948e5a97af4df3dd75a545bd0 (diff)
Implements server-side ship damage,
adds a damage key to the weapons.ini file, configurable spacemine damage.
Diffstat (limited to 'src')
-rw-r--r--src/game/base/game.cc17
-rw-r--r--src/game/base/projectile.cc1
-rw-r--r--src/game/base/projectile.h39
-rw-r--r--src/game/base/ship.cc61
-rw-r--r--src/game/base/ship.h59
-rw-r--r--src/game/base/shipmodel.cc13
-rw-r--r--src/game/base/shipmodel.h112
-rw-r--r--src/game/base/spacemine.cc16
-rw-r--r--src/game/base/spacemine.h27
-rw-r--r--src/game/base/weapon.cc12
-rw-r--r--src/game/base/weapon.h24
11 files changed, 311 insertions, 70 deletions
diff --git a/src/game/base/game.cc b/src/game/base/game.cc
index cebbe01..47fab0f 100644
--- a/src/game/base/game.cc
+++ b/src/game/base/game.cc
@@ -990,10 +990,11 @@ void Game::func_drop(core::Player *player, const std::string &args)
// drop a mine
// find a mine in inventory
+ const Weapon *weapon = 0;
core::Item *item = 0;
for (core::Inventory::Items::iterator it = ship->inventory()->items().begin(); (!item) && (it != ship->inventory()->items().end()); it++) {
if ((*it)->info()->type() == Weapon::infotype()) {
- const Weapon *weapon = static_cast<const Weapon *>((*it)->info());
+ weapon = static_cast<const Weapon *>((*it)->info());
if (weapon->subtype() == Weapon::Mine) {
item = (*it);
@@ -1006,16 +1007,16 @@ void Game::func_drop(core::Player *player, const std::string &args)
return;
}
- // create a spacemine entity
- SpaceMine *spacemine = new SpaceMine(item->info());
+ // create a spacemine entity using the Weapon instance as constructiong info
+ SpaceMine *spacemine = new SpaceMine(weapon);
+
spacemine->set_color(ship->color());
spacemine->set_color_second(ship->color_second());
spacemine->set_location(ship->location() + ship->axis().forward() * -1.0f * (ship->radius() + spacemine->radius()));
spacemine->set_axis(ship->axis());
spacemine->set_zone(ship->zone());
- spacemine->set_info(item->info());
- player->send(item->info()->name() + " ejected");
+ player->send(weapon->name() + " ejected");
player->sound("fx/eject");
spacemine->reset();
@@ -1283,7 +1284,8 @@ void Game::func_respawn(core::Player *player, std::string const &args)
core::Entity *spawn = ship->spawn();
if (!spawn) {
- spawn = player->control()->zone()->default_view();
+ ship->set_zone(Default::zone);
+ spawn = ship->zone()->default_view();
}
if (spawn && spawn->has_flag(core::Entity::Dockable)) {
@@ -1291,14 +1293,13 @@ void Game::func_respawn(core::Player *player, std::string const &args)
player->set_view(spawn);
player->send("^BRespawning at " + spawn->name());
} else {
+ ship->set_zone(Default::zone);
ship->get_location().clear();
ship->get_axis().clear();
ship->set_state(core::Entity::Normal);
player->set_view(0);
player->send("^BRespawning");
}
-
- ship->set_zone(Default::zone);
}
diff --git a/src/game/base/projectile.cc b/src/game/base/projectile.cc
index 992c55b..b80d7a6 100644
--- a/src/game/base/projectile.cc
+++ b/src/game/base/projectile.cc
@@ -30,6 +30,7 @@ Projectile::Projectile(unsigned long lifespan) : EntityDynamic()
//const float damp = Game::g_damping->value();
//body()->setDamping(0.0f, 0.0f);
+ projectile_damage = 0.0f;
projectile_lifespan = lifespan;
projectile_timestamp = core::server()->timestamp();
}
diff --git a/src/game/base/projectile.h b/src/game/base/projectile.h
index bbaea99..238de6a 100644
--- a/src/game/base/projectile.h
+++ b/src/game/base/projectile.h
@@ -17,17 +17,52 @@ class Projectile : public core::EntityDynamic
public:
Projectile(unsigned long lifespan);
virtual ~Projectile();
-
+
virtual void upkeep(const unsigned long timestamp);
-
+
virtual void collision(Entity *other);
virtual void frame(const unsigned long elapsed);
+ /* --- inspectors ------------------------------------------ */
+
+ inline const unsigned long timestamp() const
+ {
+ return projectile_timestamp;
+ }
+
+ /**
+ * @brief the lifespan of this projectile, in milliseconds
+ * */
+ inline const unsigned long lifespan() const
+ {
+ return projectile_lifespan;
+ }
+
+ /**
+ * @brief the amount of damage this projectile inflicts
+ * */
+ inline const float damage() const
+ {
+ return projectile_damage;
+ }
+
+ /* --- mutators -------------------------------------------- */
+
+ /**
+ * @brief set the amount of damage this projectile inflicts
+ * */
+ inline void set_damage(const float damage)
+ {
+ projectile_damage = damage;
+ }
+
private:
unsigned long projectile_timestamp;
unsigned long projectile_lifespan;
+
+ float projectile_damage;
};
} // namespace game
diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc
index 854bdab..ac4db15 100644
--- a/src/game/base/ship.cc
+++ b/src/game/base/ship.cc
@@ -14,6 +14,7 @@
#include "base/game.h"
#include "base/ship.h"
#include "base/projectile.h"
+#include "base/spacemine.h"
#include "math/functions.h"
using math::degrees360f;
@@ -40,6 +41,11 @@ Ship::Ship(core::Player *owner, const ShipModel *shipmodel) : core::EntityContro
ship_dock = 0;
ship_spawn = 0;
+ ship_maxarmor = 100.0f;
+
+ ship_maxshield = 0.0f;
+ ship_shield = 0.0f;
+
current_impulse = false;
// apply ship type settings
@@ -106,6 +112,8 @@ Ship::Ship(core::Player *owner, const ShipModel *shipmodel) : core::EntityContro
set_flag(core::Entity::Dockable);
}
+ ship_armor = maxarmor();
+
// initialize physics
// FIXME probably should not be called here
//reset();
@@ -318,6 +326,10 @@ void Ship::set_dock(core::Entity *dock)
get_location().assign(dock->location());
get_axis().assign(dock->axis());
ship_dock = dock;
+ if (dock->zone() != zone())
+ {
+ set_zone(dock->zone());
+ }
set_state(core::Entity::Docked);
reset();
@@ -436,6 +448,8 @@ void Ship::collision(core::Entity *other)
// do not fly into planets
if (other->moduletype() == planet_enttype) {
+
+ // ran into a planet
explode();
if (owner()) {
@@ -449,16 +463,60 @@ void Ship::collision(core::Entity *other)
die();
}
} else if (other->moduletype() == star_enttype) {
+
+ // flew into a star
explode();
if (owner()) {
std::string message("^B");
message.append(owner()->name());
- message.append(" ^Bcould not resist the light.");
+ message.append(" ^Bflew into a star.");
core::server()->broadcast(message);
} else {
die();
}
+
+ } else if (other->moduletype() == spacemine_enttype) {
+
+ // hit by a mine
+ SpaceMine * spacemine = static_cast<SpaceMine *>(other);
+ if (spacemine->state() != core::Entity::Destroyed) {
+ ship_armor -= spacemine->damage();
+ }
+
+ // destroyed
+ if (ship_armor <= 0) {
+ if (owner()) {
+ ship_armor = 0;
+ std::string message("^B");
+ message.append(owner()->name());
+ message.append(" ^Bwent boom.");
+ explode();
+ } else {
+ die();
+ }
+ }
+
+ } else if (other->moduletype() == projectile_enttype) {
+
+ // hit by projectile
+ Projectile * projectile = static_cast<Projectile *>(other);
+ if (projectile->state() != core::Entity::Destroyed) {
+ ship_armor -= projectile->damage();
+ }
+
+ // destroyed
+ if (ship_armor <= 0) {
+ if (owner()) {
+ ship_armor = 0;
+ std::string message("^B");
+ message.append(owner()->name());
+ message.append(" ^Bwas blown to bits.");
+ explode();
+ } else {
+ die();
+ }
+ }
}
}
@@ -773,6 +831,7 @@ void Ship::frame(const unsigned long elapsed)
if ((*it)->last_fired() + (*it)->interval() <= core::server()->timestamp()) {
(*it)->set_last_fired(core::server()->timestamp());
Projectile * projectile = new Projectile((*it)->lifespan());
+ projectile->set_damage(10.0f);
projectile->set_zone(zone());
projectile->set_axis(axis() * (*it)->axis());
projectile->set_location(location() + (axis() * (*it)->location() * modelscale) + projectile->axis().forward() * projectile->radius());
diff --git a/src/game/base/ship.h b/src/game/base/ship.h
index 2670ee2..d68c647 100644
--- a/src/game/base/ship.h
+++ b/src/game/base/ship.h
@@ -16,7 +16,9 @@
namespace game
{
-/// A ship in the game, controled by a player
+/**
+ * @brief A ship in the game, controled by a player
+ * */
class Ship : public core::EntityControlable
{
public:
@@ -26,45 +28,65 @@ public:
/* -- inspectors ------------------------------------------- */
/// shipmodel
- inline const ShipModel *shipmodel() const {
+ inline const ShipModel *shipmodel() const
+ {
return ship_shipmodel;
}
/// impulse drive force
- inline const float impulse_force() const {
+ inline const float impulse_force() const
+ {
return ship_impulse_force;
}
/// thruster force
- inline const float thrust_force() const {
+ inline const float thrust_force() const
+ {
return ship_thrust_force;
}
/// strafe force
- inline const float strafe_force() const {
+ inline const float strafe_force() const
+ {
return ship_strafe_force;
}
/// turn force
- inline const float turn_force() const {
+ inline const float turn_force() const
+ {
return ship_turn_force;
}
/// roll force
- inline const float roll_force() const {
+ inline const float roll_force() const
+ {
return ship_roll_force;
}
/// entity the ship is currently docked at
- inline core::Entity *dock() {
+ inline core::Entity *dock()
+ {
return ship_dock;
}
/// (dockable) entity where the ship will respawn if destroyed
- core::Entity *spawn() {
+ core::Entity *spawn()
+ {
return ship_spawn;
}
+ /// maximum amount of armor
+ inline const float maxarmor() const
+ {
+ return ship_maxarmor;
+ }
+
+ /// current amount of armor
+ inline const float armor() const
+ {
+ return ship_armor;
+ }
+
/* -- mutators --------------------------------------------- */
/// physics frame
@@ -112,6 +134,18 @@ public:
ship_roll_force = roll;
}
+ /// set maximal armor amount (100% health)
+ inline void set_maxarmor(const float maxarmor)
+ {
+ ship_maxarmor = maxarmor;
+ }
+
+ /// set current armor amount (current health)
+ inline void set_armor(const float armor)
+ {
+ ship_armor = armor;
+ }
+
/// Initiate jump, departing from a jump point
void initiate_jump(JumpPoint *depart);
@@ -154,7 +188,6 @@ private:
bool ship_jumpdrive;
float ship_jumpdrive_timer;
-
float ship_impulsedrive_timer;
JumpPoint *ship_jumpdepart;
@@ -165,6 +198,12 @@ private:
float ship_turn_force;
float ship_roll_force;
+ float ship_maxarmor;
+ float ship_armor;
+
+ float ship_maxshield;
+ float ship_shield;
+
core::Entity *ship_dock;
core::Entity *ship_spawn;
diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc
index 6e21d91..fe8889d 100644
--- a/src/game/base/shipmodel.cc
+++ b/src/game/base/shipmodel.cc
@@ -92,9 +92,9 @@ bool ShipModel::init()
} else if (inifile.got_key_bool("dock", b)) {
shipmodel->set_dockable(b);
continue;
- } else if (inifile.got_key_float("maxspeed", f)) {
- shipmodel->set_maxspeed(f * 0.01f);
- continue;
+// } else if (inifile.got_key_float("maxspeed", f)) {
+// shipmodel->set_maxspeed(f * 0.01f);
+// continue;
} else if (inifile.got_key_float("impulse", f)) {
shipmodel->set_impulse_force(f);
continue;
@@ -113,6 +113,9 @@ bool ShipModel::init()
} else if (inifile.got_key_float("mass", f)) {
shipmodel->set_mass(f);
continue;
+ } else if (inifile.got_key_float("armor", f)) {
+ shipmodel->set_maxarmor(f);
+ continue;
} else if (inifile.got_key_float("radius", f)) {
shipmodel->set_radius(f);
continue;
@@ -196,7 +199,7 @@ void ShipModel::done()
ShipModel::ShipModel() : core::Info(shipmodel_infotype)
{
- shipmodel_maxspeed = 0;
+ //shipmodel_maxspeed = 0;
//default specifications
shipmodel_radius = 0.0f;
@@ -211,6 +214,7 @@ ShipModel::ShipModel() : core::Info(shipmodel_infotype)
shipmodel_roll_force = 1.0f;
shipmodel_maxcargo = 0.0f;
+ shipmodel_maxarmor = 100.0f;
shipmodel_jumpdrive = false; // no jumpdrive capability
shipmodel_dockable = false; // not dockable
@@ -392,6 +396,7 @@ void ShipModel::apply(Ship *ship) const
ship->set_turn_force(turn_force());
ship->set_roll_force(roll_force());
ship->set_jumpdrive(jumpdrive());
+ ship->set_maxarmor(maxarmor());
}
}
diff --git a/src/game/base/shipmodel.h b/src/game/base/shipmodel.h
index f790bcd..243860d 100644
--- a/src/game/base/shipmodel.h
+++ b/src/game/base/shipmodel.h
@@ -31,72 +31,92 @@ public:
/* ---- inspectors ------------------------------------------------ */
/// indicates if this model can be equiped with a jump drive
- inline const bool jumpdrive() const {
+ inline const bool jumpdrive() const
+ {
return shipmodel_jumpdrive;
}
/// indicates if players can dock this ship model
- inline const bool dockable() const {
+ inline const bool dockable() const
+ {
return shipmodel_dockable;
}
/// default mass
- inline const float mass() const {
+ inline const float mass() const
+ {
return shipmodel_mass;
}
/// default impulse drive force
- inline const float impulse_force() const {
+ inline const float impulse_force() const
+ {
return shipmodel_impulse_force;
}
/// default thruster force
- inline const float thrust_force() const {
+ inline const float thrust_force() const
+ {
return shipmodel_thrust_force;
}
/// default strafe force
- inline const float strafe_force() const {
+ inline const float strafe_force() const
+ {
return shipmodel_strafe_force;
}
/// default turn force
- inline const float turn_force() const {
+ inline const float turn_force() const
+ {
return shipmodel_turn_force;
}
/// default turn force
- inline const float roll_force() const {
+ inline const float roll_force() const
+ {
return shipmodel_roll_force;
}
/// linear damping factor
- inline const float linear_damping() const {
+ inline const float linear_damping() const
+ {
return shipmodel_linear_damping;
}
/// angular damping factor
- inline const float angular_damping() const {
+ inline const float angular_damping() const
+ {
return shipmodel_angular_damping;
}
- /// maximum thrust speed
- inline const float maxspeed() const {
- return shipmodel_maxspeed;
- }
+// /// maximum thrust speed
+// inline const float maxspeed() const
+// {
+// return shipmodel_maxspeed;
+// }
/// size of the cargo hold, in cubic meters
- inline const float maxcargo() const {
+ inline const float maxcargo() const
+ {
return shipmodel_maxcargo;
}
+ /// maximum armor amount
+ inline const float maxarmor() const
+ {
+ return shipmodel_maxarmor;
+ }
+
/// ship radius
- inline const float radius() const {
+ inline const float radius() const
+ {
return shipmodel_radius;
}
/// entity template
- inline const Template *model_template() const {
+ inline const Template *model_template() const
+ {
return shipmodel_template;
}
@@ -117,77 +137,97 @@ protected:
/* ---- mutators -------------------------------------------------- */
/// set mass
- inline void set_mass(const float mass) {
+ inline void set_mass(const float mass)
+ {
shipmodel_mass = mass;
}
/// set impulse drive force
- inline void set_impulse_force(const float impulse) {
+ inline void set_impulse_force(const float impulse)
+ {
shipmodel_impulse_force = impulse;
}
/// set thruster force
- inline void set_thrust_force(const float thrust) {
+ inline void set_thrust_force(const float thrust)
+ {
shipmodel_thrust_force = thrust;
}
/// set strafe force
- inline void set_strafe_force(const float strafe) {
+ inline void set_strafe_force(const float strafe)
+ {
shipmodel_strafe_force = strafe;
}
/// set turn forceshipmodel_lineardamping
- inline void set_turn_force(const float turn) {
+ inline void set_turn_force(const float turn)
+ {
shipmodel_turn_force = turn;
}
/// set roll force
- inline void set_roll_force(const float roll) {
+ inline void set_roll_force(const float roll)
+ {
shipmodel_roll_force = roll;
}
- /// set maximum speed
- inline void set_maxspeed(const float maxspeed) {
- shipmodel_maxspeed = maxspeed;
+// /// set maximum speed
+// inline void set_maxspeed(const float maxspeed)
+// {
+// shipmodel_maxspeed = maxspeed;
+// }
+
+ /// set maximum armor amount
+ inline void set_maxarmor(const float maxarmor)
+ {
+ shipmodel_maxarmor = maxarmor;
}
/// set size of the cargo hold
- inline void set_maxcargo(const float maxcargo) {
+ inline void set_maxcargo(const float maxcargo)
+ {
shipmodel_maxcargo = maxcargo;
}
/// set jumpdrive capability
- inline void set_jumpdrive(const bool jumpdrive) {
+ inline void set_jumpdrive(const bool jumpdrive)
+ {
shipmodel_jumpdrive = jumpdrive;
}
/// set dock capability
- inline void set_dockable(const bool dockable) {
+ inline void set_dockable(const bool dockable)
+ {
shipmodel_dockable = dockable;
}
/// set radius
- inline void set_radius(const float radius) {
+ inline void set_radius(const float radius)
+ {
shipmodel_radius = radius;
}
/// set entity template
- inline void set_template(const Template *model_template) {
+ inline void set_template(const Template *model_template)
+ {
shipmodel_template = model_template;
}
/**
* @brief set physics linear damping factor
*/
- inline void set_linear_damping(const float linear_damping) {
+ inline void set_linear_damping(const float linear_damping)
+ {
shipmodel_linear_damping = linear_damping;
}
/**
* @brief set physics linear damping factor
*/
- inline void set_angular_damping(const float angular_damping) {
+ inline void set_angular_damping(const float angular_damping)
+ {
shipmodel_angular_damping = angular_damping;
}
@@ -226,8 +266,10 @@ private:
float shipmodel_turn_force;
float shipmodel_roll_force;
- float shipmodel_maxspeed;
- float shipmodel_maxcargo;
+// float shipmodel_maxspeed;
+ float shipmodel_maxcargo;
+ float shipmodel_maxarmor;
+ float shipmodel_maxshield;
bool shipmodel_jumpdrive;
bool shipmodel_dockable;
diff --git a/src/game/base/spacemine.cc b/src/game/base/spacemine.cc
index dc5f6c5..32d4798 100644
--- a/src/game/base/spacemine.cc
+++ b/src/game/base/spacemine.cc
@@ -13,7 +13,7 @@ namespace game
const Template *SpaceMine::spacemine_template = 0;
-SpaceMine::SpaceMine(const core::Info *info) : EntityDynamic()
+SpaceMine::SpaceMine(const Weapon *weapon) : EntityDynamic()
{
entity_moduletypeid = spacemine_enttype;
set_name("Space mine");
@@ -24,6 +24,7 @@ SpaceMine::SpaceMine(const core::Info *info) : EntityDynamic()
// setting
set_radius(0);
+ set_damage(0.0f);
// use template settings if available
if (spacemine_template) {
@@ -31,13 +32,14 @@ SpaceMine::SpaceMine(const core::Info *info) : EntityDynamic()
}
// item type model overrides template
- if (info) {
- set_info(info);
- if (info->modelname().size()) {
- set_modelname(info->modelname());
+ if (weapon) {
+ set_info(weapon);
+ if (weapon->modelname().size()) {
+ set_modelname(weapon->modelname());
}
- set_name(info->name());
- set_label(info->label());
+ set_name(weapon->name());
+ set_label(weapon->label());
+ set_damage(weapon->damage());
}
// radius fallback
diff --git a/src/game/base/spacemine.h b/src/game/base/spacemine.h
index 632c48c..4f95849 100644
--- a/src/game/base/spacemine.h
+++ b/src/game/base/spacemine.h
@@ -9,6 +9,7 @@
#include "core/entity.h"
#include "base/template.h"
+#include "base/weapon.h"
namespace game
{
@@ -16,7 +17,7 @@ namespace game
class SpaceMine : public core::EntityDynamic
{
public:
- SpaceMine(const core::Info *info);
+ SpaceMine(const Weapon *weapon);
virtual ~SpaceMine();
virtual void upkeep(const unsigned long timestamp);
@@ -25,12 +26,34 @@ public:
virtual void frame(const unsigned long elapsed);
- static inline void set_template (const Template *entitytemplate) {
+ static inline void set_template (const Template *entitytemplate)
+ {
spacemine_template = entitytemplate;
}
+
+ /* --- inspectors ------------------------------------------ */
+
+ /**
+ * @brief the amount of damage this spacemine inflicts
+ * */
+ inline const float damage() const
+ {
+ return spacemine_damage;
+ }
+
+ /* --- mutators -------------------------------------------- */
+
+ /**
+ * @brief set the amount of damage this spacemine inflicts
+ * */
+ inline void set_damage(const float damage)
+ {
+ spacemine_damage = damage;
+ }
private:
unsigned long spacemine_detonated_timestamp;
+ float spacemine_damage;
static const Template *spacemine_template;
};
diff --git a/src/game/base/weapon.cc b/src/game/base/weapon.cc
index 59384e2..ec87b34 100644
--- a/src/game/base/weapon.cc
+++ b/src/game/base/weapon.cc
@@ -75,6 +75,10 @@ bool Weapon::init()
} else if (weaponsini.got_key_float("volume", f)) {
weapon->set_volume(f);
continue;
+
+ } else if (weaponsini.got_key_float("damage", f)) {
+ weapon->set_damage(f);
+ continue;
} else if (weaponsini.got_key_long("level", l)) {
weapon->set_level(l);
@@ -108,6 +112,10 @@ bool Weapon::init()
weapon->set_volume(f);
continue;
+ } else if (weaponsini.got_key_float("damage", f)) {
+ weapon->set_damage(f);
+ continue;
+
} else if (weaponsini.got_key_long("level", l)) {
weapon->set_level(l);
continue;
@@ -139,6 +147,10 @@ bool Weapon::init()
} else if (weaponsini.got_key_float("volume", f)) {
weapon->set_volume(f);
continue;
+
+ } else if (weaponsini.got_key_float("damage", f)) {
+ weapon->set_damage(f);
+ continue;
} else if (weaponsini.got_key_long("level", l)) {
weapon->set_level(l);
diff --git a/src/game/base/weapon.h b/src/game/base/weapon.h
index 01a135b..ba28810 100644
--- a/src/game/base/weapon.h
+++ b/src/game/base/weapon.h
@@ -19,6 +19,8 @@ public:
Weapon();
~Weapon();
+ /* --- inspectors ------------------------------------------ */
+
inline SubType subtype() const {
return weapon_subtype;
}
@@ -29,6 +31,24 @@ public:
inline int level() const {
return weapon_level;
}
+
+ /**
+ * @brief the amount of damage this weapon inflicts
+ * */
+ inline const float damage() const
+ {
+ return weapon_damage;
+ }
+
+ /* --- mutators -------------------------------------------- */
+
+ /**
+ * @brief set the amount of damage this weapon inflicts
+ * */
+ inline void set_damage(const float damage)
+ {
+ weapon_damage = damage;
+ }
void set_stackable(bool stackable);
@@ -53,11 +73,13 @@ public:
private:
static core::InfoType *weapon_infotype;
+ SubType weapon_subtype;
+
int weapon_level;
bool weapon_stackable;
- SubType weapon_subtype;
+ float weapon_damage;
};
} // namespace game