From 48ae5acc0eed6e88f82802c1a5acd23bd11284cd Mon Sep 17 00:00:00 2001 From: Carlos Failde Date: Sat, 5 Oct 2013 19:47:25 +0100 Subject: [PATCH 1/3] Stop autofire when shooter shoots out floor without flying armor. --- src/Battlescape/ProjectileFlyBState.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/Battlescape/ProjectileFlyBState.cpp b/src/Battlescape/ProjectileFlyBState.cpp index 940d9aec6b..a7ad6d643a 100644 --- a/src/Battlescape/ProjectileFlyBState.cpp +++ b/src/Battlescape/ProjectileFlyBState.cpp @@ -32,6 +32,7 @@ #include "../Savegame/Tile.h" #include "../Resource/ResourcePack.h" #include "../Engine/Sound.h" +#include "../Ruleset/Armor.h" #include "../Ruleset/RuleItem.h" #include "../Engine/Options.h" #include "AlienBAIState.h" @@ -293,7 +294,16 @@ void ProjectileFlyBState::think() /* TODO refactoring : store the projectile in this state, instead of getting it from the map each time? */ if (_parent->getMap()->getProjectile() == 0) { - if (_action.type == BA_AUTOSHOT && _action.autoShotCounter < _action.weapon->getRules()->getAutoShots() && !_action.actor->isOut() && _ammo->getAmmoQuantity() != 0) + Tile *t = _parent->getSave()->getTile(_action.actor->getPosition()); + Tile *bt = _parent->getSave()->getTile(_action.actor->getPosition() + Position(0,0,-1)); + bool hasFloor = t && !t->hasNoFloor(bt); + bool unitCanFly = _action.actor->getArmor()->getMovementType() == MT_FLY; + + if (_action.type == BA_AUTOSHOT + && _action.autoShotCounter < _action.weapon->getRules()->getAutoShots() + && !_action.actor->isOut() + && _ammo->getAmmoQuantity() != 0 + && (hasFloor || unitCanFly)) { createNewProjectile(); } From 64c47671604bdc76e613fccbf51e1bc49c6414ed Mon Sep 17 00:00:00 2001 From: Warboy Date: Mon, 14 Oct 2013 17:39:56 +1100 Subject: [PATCH 2/3] add weight to armor --- src/Ruleset/Armor.cpp | 12 +++++++++++- src/Ruleset/Armor.h | 4 +++- src/Savegame/BattleUnit.cpp | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/Ruleset/Armor.cpp b/src/Ruleset/Armor.cpp index 92fa1ec858..0aabb035c8 100644 --- a/src/Ruleset/Armor.cpp +++ b/src/Ruleset/Armor.cpp @@ -30,7 +30,7 @@ namespace OpenXcom * @param movementType The movement type for this armor (walk, fly or slide). * @param size The size of the armor. Normally this is 1 (small) or 2 (big). */ -Armor::Armor(const std::string &type, std::string spriteSheet, int drawingRoutine, MovementType movementType, int size) : _type(type), _spriteSheet(spriteSheet), _spriteInv(""), _corpseItem(""), _storeItem(""), _frontArmor(0), _sideArmor(0), _rearArmor(0), _underArmor(0), _drawingRoutine(drawingRoutine), _movementType(movementType), _size(size) +Armor::Armor(const std::string &type, std::string spriteSheet, int drawingRoutine, MovementType movementType, int size) : _type(type), _spriteSheet(spriteSheet), _spriteInv(""), _corpseItem(""), _storeItem(""), _frontArmor(0), _sideArmor(0), _rearArmor(0), _underArmor(0), _drawingRoutine(drawingRoutine), _movementType(movementType), _size(size), _weight(6) { for (int i=0; i < DAMAGE_TYPES; i++) _damageModifier[i] = 1.0; @@ -62,6 +62,7 @@ void Armor::load(const YAML::Node &node) _drawingRoutine = node["drawingRoutine"].as(_drawingRoutine); _movementType = (MovementType)node["movementType"].as(_movementType); _size = node["size"].as(_size); + _weight = node["weight"].as(_weight); if (const YAML::Node &dmg = node["damageModifier"]) { for (size_t i = 0; i < dmg.size() && i < DAMAGE_TYPES; ++i) @@ -203,4 +204,13 @@ std::vector Armor::getLoftempsSet() const return _loftempsSet; } + +/** + * Gets the armor's weight. + * @return the weight of the armor. + */ +int Armor::getWeight() +{ + return _weight; +} } diff --git a/src/Ruleset/Armor.h b/src/Ruleset/Armor.h index bfb019dee7..1b1474d591 100644 --- a/src/Ruleset/Armor.h +++ b/src/Ruleset/Armor.h @@ -38,7 +38,7 @@ class Armor std::string _type, _spriteSheet, _spriteInv, _corpseItem, _storeItem; int _frontArmor, _sideArmor, _rearArmor, _underArmor, _drawingRoutine; MovementType _movementType; - int _size; + int _size, _weight; float _damageModifier[DAMAGE_TYPES]; std::vector _loftempsSet; public: @@ -76,6 +76,8 @@ class Armor float getDamageModifier(ItemDamageType dt); /// Gets loftempSet std::vector getLoftempsSet() const; + /// Gets the armor's weight. + int getWeight(); }; } diff --git a/src/Savegame/BattleUnit.cpp b/src/Savegame/BattleUnit.cpp index e2eb8cd1d5..acc6547e0c 100644 --- a/src/Savegame/BattleUnit.cpp +++ b/src/Savegame/BattleUnit.cpp @@ -2324,7 +2324,7 @@ BattleUnit *BattleUnit::getCharging() */ int BattleUnit::getCarriedWeight(BattleItem *draggingItem) const { - int weight = 6; + int weight = _armor->getWeight(); for (std::vector::const_iterator i = _inventory.begin(); i != _inventory.end(); ++i) { if ((*i) == draggingItem) continue; From 67fced706c3df4652438048876ac4be1499c54ac Mon Sep 17 00:00:00 2001 From: Warboy Date: Mon, 14 Oct 2013 19:53:43 +1100 Subject: [PATCH 3/3] allow armors to modify effective stats. adds a UnitStats property to armors, allowing them to modify effective stats during battlescapes. --- src/Ruleset/Armor.cpp | 20 ++++++++++++++++++++ src/Ruleset/Armor.h | 4 ++++ src/Ruleset/Unit.h | 2 ++ src/Savegame/BattleUnit.cpp | 2 ++ 4 files changed, 28 insertions(+) diff --git a/src/Ruleset/Armor.cpp b/src/Ruleset/Armor.cpp index 0aabb035c8..e6af835f98 100644 --- a/src/Ruleset/Armor.cpp +++ b/src/Ruleset/Armor.cpp @@ -34,6 +34,17 @@ Armor::Armor(const std::string &type, std::string spriteSheet, int drawingRoutin { for (int i=0; i < DAMAGE_TYPES; i++) _damageModifier[i] = 1.0; + _stats.bravery = 0; + _stats.firing = 0; + _stats.health = 0; + _stats.melee = 0; + _stats.psiSkill = 0; + _stats.psiStrength = 0; + _stats.reactions = 0; + _stats.stamina = 0; + _stats.strength = 0; + _stats.tu = 0; + _stats.throwing = 0; } /** @@ -63,6 +74,7 @@ void Armor::load(const YAML::Node &node) _movementType = (MovementType)node["movementType"].as(_movementType); _size = node["size"].as(_size); _weight = node["weight"].as(_weight); + _stats = node["stats"].as(_stats); if (const YAML::Node &dmg = node["damageModifier"]) { for (size_t i = 0; i < dmg.size() && i < DAMAGE_TYPES; ++i) @@ -204,6 +216,14 @@ std::vector Armor::getLoftempsSet() const return _loftempsSet; } +/** + * Gets pointer to the armor's stats. + * @return stats Pointer to the armor's stats. + */ +UnitStats *Armor::getStats() +{ + return &_stats; +} /** * Gets the armor's weight. diff --git a/src/Ruleset/Armor.h b/src/Ruleset/Armor.h index 1b1474d591..d36da4ae3e 100644 --- a/src/Ruleset/Armor.h +++ b/src/Ruleset/Armor.h @@ -22,6 +22,7 @@ #include #include #include "MapData.h" +#include "Unit.h" namespace OpenXcom { @@ -41,6 +42,7 @@ class Armor int _size, _weight; float _damageModifier[DAMAGE_TYPES]; std::vector _loftempsSet; + UnitStats _stats; public: /// Creates a blank armor ruleset. Armor(const std::string &type, std::string spriteSheet, int drawingRoutine, MovementType _movementType = MT_WALK, int size = 1); @@ -76,6 +78,8 @@ class Armor float getDamageModifier(ItemDamageType dt); /// Gets loftempSet std::vector getLoftempsSet() const; + /// Gets the armor's stats. + UnitStats *getStats(); /// Gets the armor's weight. int getWeight(); }; diff --git a/src/Ruleset/Unit.h b/src/Ruleset/Unit.h index 89cf01b884..cfbb87bab2 100644 --- a/src/Ruleset/Unit.h +++ b/src/Ruleset/Unit.h @@ -32,6 +32,8 @@ enum SpecialAbility { SPECAB_NONE = 0, SPECAB_EXPLODEONDEATH, SPECAB_BURNFLOOR, struct UnitStats { int tu, stamina, health, bravery, reactions, firing, throwing, strength, psiStrength, psiSkill, melee; +public: + UnitStats& operator+=(const UnitStats& stats) { tu+=stats.tu; stamina+=stats.stamina; health+=stats.health; bravery+=stats.bravery; reactions+=stats.reactions; firing+=stats.firing; throwing+=stats.throwing; strength+=stats.strength; psiStrength+=stats.psiStrength; psiSkill+=stats.psiSkill; melee+=stats.melee; return *this; } }; /** diff --git a/src/Savegame/BattleUnit.cpp b/src/Savegame/BattleUnit.cpp index acc6547e0c..386fa3d6de 100644 --- a/src/Savegame/BattleUnit.cpp +++ b/src/Savegame/BattleUnit.cpp @@ -68,6 +68,7 @@ BattleUnit::BattleUnit(Soldier *soldier, UnitFaction faction) : _faction(faction _aggression = 1; _specab = SPECAB_NONE; _armor = soldier->getArmor(); + _stats += *_armor->getStats(); // armors may modify effective stats _loftempsSet = _armor->getLoftempsSet(); _gender = soldier->getGender(); _faceDirection = -1; @@ -144,6 +145,7 @@ BattleUnit::BattleUnit(Unit *unit, UnitFaction faction, int id, Armor *armor, in _value = unit->getValue(); _gender = GENDER_MALE; _faceDirection = -1; + _stats += *_armor->getStats(); // armors may modify effective stats _tu = _stats.tu; _energy = _stats.stamina;