From 614ce1267772d67825a32fb7495a049cd6498fe5 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Tue, 1 Jan 2013 15:20:14 +0000 Subject: Initial support for turret-style weapons. --- src/core/slot.cc | 12 ++++++++++++ src/core/slot.h | 43 +++++++++++++++++++++++++++++++++++++++++++ src/core/slots.cc | 3 +-- src/game/base/ship.cc | 9 +++++++-- src/game/base/shipmodel.cc | 12 ++++++++++++ src/model/mapfile.cc | 15 +++++++-------- src/model/tags.cc | 23 ++++++++++++++++++++--- src/model/tags.h | 34 ++++++++++++++++++++++++++-------- 8 files changed, 128 insertions(+), 23 deletions(-) diff --git a/src/core/slot.cc b/src/core/slot.cc index e842f78..58ab155 100644 --- a/src/core/slot.cc +++ b/src/core/slot.cc @@ -17,6 +17,8 @@ Slot::Slot() slot_flags = 0; slot_timestamp = 0; slot_last_fired = 0; + slot_cone = 0; + slot_type = model::Weapon::Cannon; } Slot::~Slot() @@ -41,4 +43,14 @@ void Slot::set_item(Item *item) set_timestamp(game() ? game()->timestamp() : 1); } +void Slot::load(const model::Weapon * weapon_tag) +{ + if (weapon_tag) { + set_type(weapon_tag->type()); + set_cone(weapon_tag->cone()); + set_location(weapon_tag->location()); + set_axis(weapon_tag->axis()); + } +} + } // namespace core diff --git a/src/core/slot.h b/src/core/slot.h index eef640a..596244b 100644 --- a/src/core/slot.h +++ b/src/core/slot.h @@ -11,6 +11,7 @@ #include "math/axis.h" #include "core/item.h" +#include "model/tags.h" #include @@ -83,6 +84,22 @@ public: { return slot_last_fired; } + + /** + * @brief slot fire cone, in degrees + * */ + inline float cone() const + { + return slot_cone; + } + + /** + * @brief weapon slot type + * */ + inline const model::Weapon::Type type() const + { + return slot_type; + } /* --- mutators -------------------------------------------- */ @@ -134,7 +151,29 @@ public: * @brief set the item this slot is holding * */ void set_item(Item *item); + + /** + * @brief set slot fire cone, in degrees + * */ + inline void set_cone(const float cone) + { + slot_cone = cone; + } + + /** + * @brief set slot type + * */ + void set_type(const model::Weapon::Type type) + { + slot_type = type; + } + /** + * @brief load slot parameters from a model weapon tag + * */ + void load(const model::Weapon *weapon_tag); + + private: math::Vector3f slot_location; @@ -152,6 +191,10 @@ private: // item mounted in this slot Item *slot_item; + + model::Weapon::Type slot_type; + + float slot_cone; }; } // namespace core diff --git a/src/core/slots.cc b/src/core/slots.cc index 12f6208..6d6096a 100644 --- a/src/core/slots.cc +++ b/src/core/slots.cc @@ -23,8 +23,7 @@ void Slots::load(model::Model *model) { for (model::Model::Weapons::iterator it = model->weapons().begin(); it != model->weapons().end(); ++it) { Slot *slot = new Slot(); - slot->set_location((*it)->location()); - slot->set_axis((*it)->axis()); + slot->load((*it)); slots_container.push_back(slot); } //con_debug << " loaded " << slots_container.size() << " entity slots" << std::endl; diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index 219cb0c..4c3885a 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -925,10 +925,15 @@ void Ship::frame(const unsigned long elapsed) math::Vector3f projectile_direction(target_aim - projectile_location); projectile_direction.normalize(); float cosa = math::dotproduct(projectile_direction, projectile_axis.forward()); + + // fire a projectile if the angle between the aim direction and the slot's forward direction is small enough - // TODO configurable aim cone - if (cosa > 0.5f) { + + // we only need half the cone angle for the cosine calculation + float conecos = cosf( slot->cone() / 360.0f * M_PI); + + if (cosa >= conecos) { // aim math::Vector3f normal(math::crossproduct(projectile_direction, projectile_axis.forward())); if (normal.length() > MIN_DELTA) { diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc index ba87024..7d54ee2 100644 --- a/src/game/base/shipmodel.cc +++ b/src/game/base/shipmodel.cc @@ -235,6 +235,7 @@ void ShipModel::generate_info() add_line(""); add_line("^BSpecifications:^N"); + std::stringstream str; str << "price: ^B" << price() << " ^Ncredits"; add_line(str.str()); @@ -259,6 +260,17 @@ void ShipModel::generate_info() if (dockable()) { add_line("^Bdockable"); } + + if (modelname().size()) { + // FIXME the model has to be loaded to got slot information + /* + int nbcannons = 0; + int nbturrets = 0; + + add_line(""); + add_line("^BWeapons:^N"); + */ + } } ShipModel *ShipModel::find(const std::string & label) diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc index 3df2659..e06de58 100644 --- a/src/model/mapfile.cc +++ b/src/model/mapfile.cc @@ -1834,7 +1834,7 @@ Model * MapFile::load(std::string const &name) } else if (mapfile.got_classname("location_cannon")) { // new cannon slot - tag_weapon = new Weapon(); + tag_weapon = new Weapon(Weapon::Cannon); model->add_weapon(tag_weapon); continue; @@ -1848,8 +1848,8 @@ Model * MapFile::load(std::string const &name) tag_weapon->get_location().assign(location * SCALE); continue; - } else if (mapfile.got_key_float("radius", r)) { - tag_weapon->set_radius(r * SCALE); + } else if (mapfile.got_key_float("cone", r)) { + tag_weapon->set_cone(r); continue; } else if (mapfile.got_key()) { @@ -1858,10 +1858,10 @@ Model * MapFile::load(std::string const &name) } continue; - } else if (mapfile.got_classname("location_turret")) { + } else if (mapfile.got_classname("location_turret")) { // new turret slot - tag_weapon = new Weapon(); + tag_weapon = new Weapon(Weapon::Turret); model->add_weapon(tag_weapon); continue; @@ -1875,8 +1875,8 @@ Model * MapFile::load(std::string const &name) tag_weapon->get_location().assign(location * SCALE); continue; - } else if (mapfile.got_key_float("radius", r)) { - tag_weapon->set_radius(r * SCALE); + } else if (mapfile.got_key_float("cone", r)) { + tag_weapon->set_cone(r); continue; } else if (mapfile.got_key()) { @@ -2039,7 +2039,6 @@ Model * MapFile::load(std::string const &name) for (Model::Weapons::const_iterator wit = submodel_model->weapons().begin(); wit != submodel_model->weapons().end(); wit++) { tag_weapon = new Weapon(*(*wit)); tag_weapon->get_location().assign(tag_submodel->location() + tag_submodel->axis() * (tag_weapon->location() - submodel_model->origin()) * tag_submodel->scale()); - tag_weapon->set_radius(tag_weapon->radius() * tag_submodel->scale()); model->add_weapon(tag_weapon); } diff --git a/src/model/tags.cc b/src/model/tags.cc index 76f18ce..7e5a393 100644 --- a/src/model/tags.cc +++ b/src/model/tags.cc @@ -155,14 +155,15 @@ Sound::~Sound() /* ---- class Dock ------------------------------------------------- */ -Weapon::Weapon() : Tag() +Weapon::Weapon(const Type type) : Tag() { - weapon_radius = 0.01f; + set_type(type); } Weapon::Weapon(const Weapon& other) : Tag(other) { - weapon_radius = other.radius(); + weapon_type = other.type(); + weapon_cone = other.cone(); weapon_axis.assign(other.axis()); } @@ -170,6 +171,22 @@ Weapon::~Weapon() { } +void Weapon::set_type(const Type type) +{ + weapon_type = type; + switch (weapon_type) { + case Unmountable: + weapon_cone = 0.0f; + break; + case Cannon: + weapon_cone = 60.0f; // 60 degrees + break; + case Turret: + weapon_cone = 180.0f; // 180 degrees + break; + } +} + /* ---- class SubModel---------------------------------------------- */ SubModel::SubModel() : Tag() diff --git a/src/model/tags.h b/src/model/tags.h index 200c977..7f7d5d7 100644 --- a/src/model/tags.h +++ b/src/model/tags.h @@ -702,10 +702,12 @@ private: class Weapon : public Tag { public: + enum Type {Unmountable = 0, Cannon = 1, Turret = 2 }; + /** * @brief default constructor * */ - Weapon(); + Weapon(const Type type = Cannon); /** * @brief copy constructor @@ -724,19 +726,29 @@ public: } /** - * @brief weapon slot radius, default is 0.01f + * @brief weapon fire cone, in degrees * */ - inline float radius() const + inline float cone() const + { + return weapon_cone; + } + + /** + * @brief weapon slot type + * */ + inline const Type type() const { - return weapon_radius; + return weapon_type; } + + /* ---- mutators ------------------------------------------- */ /** - * @brief set weapon slot radius + * @brief set weapon fire cone, in degrees * */ - inline void set_radius(const float radius) + inline void set_cone(const float cone) { - weapon_radius = radius; + weapon_cone = cone; } /** @@ -746,6 +758,11 @@ public: { weapon_axis.assign(axis); } + + /** + * @brief set weapon slot type + * */ +; void set_type(const Type type); /* ---- actors --------------------------------------------- */ @@ -757,8 +774,9 @@ public: } private: - float weapon_radius; + Type weapon_type; math::Axis weapon_axis; + float weapon_cone; }; -- cgit v1.2.3