From ab61530779c73e7e145193efcb1e23a47c16e7f3 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sun, 18 Nov 2012 15:10:37 +0000 Subject: Implements server-side ship damage, adds a damage key to the weapons.ini file, configurable spacemine damage. --- src/game/base/game.cc | 17 +++---- src/game/base/projectile.cc | 1 + src/game/base/projectile.h | 39 ++++++++++++++- src/game/base/ship.cc | 61 +++++++++++++++++++++++- src/game/base/ship.h | 59 +++++++++++++++++++---- src/game/base/shipmodel.cc | 13 +++-- src/game/base/shipmodel.h | 112 ++++++++++++++++++++++++++++++-------------- src/game/base/spacemine.cc | 16 ++++--- src/game/base/spacemine.h | 27 ++++++++++- src/game/base/weapon.cc | 12 +++++ src/game/base/weapon.h | 24 +++++++++- 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((*it)->info()); + weapon = static_cast((*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(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(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 -- cgit v1.2.3