diff options
author | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2011-11-09 03:45:42 +0100 |
---|---|---|
committer | Yohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer> | 2012-02-02 15:35:17 +0100 |
commit | 1e562bdd132c4166ca4de2bdb3f241adaa9a7149 (patch) | |
tree | 84bca9f39cfd3c05d3a315c8e9cd854b18cb4682 /src | |
parent | 4cd1957231605e976c5cf001eddea80d5e49272f (diff) | |
download | manaserv-1e562bdd132c4166ca4de2bdb3f241adaa9a7149.tar.gz manaserv-1e562bdd132c4166ca4de2bdb3f241adaa9a7149.tar.bz2 manaserv-1e562bdd132c4166ca4de2bdb3f241adaa9a7149.tar.xz manaserv-1e562bdd132c4166ca4de2bdb3f241adaa9a7149.zip |
Added a way to specify the min and max attributes values.
This can now be done in attributes.xml through the
minimum and maximum attribute parameters.
I also changed the AttributeInfo struct as requested by bjorn.
Reviewed-by: Erik Schilling, Thorbjørn Lindeijer
Diffstat (limited to 'src')
-rw-r--r-- | src/common/defines.h | 32 | ||||
-rw-r--r-- | src/game-server/attribute.cpp | 42 | ||||
-rw-r--r-- | src/game-server/attribute.h | 14 | ||||
-rw-r--r-- | src/game-server/attributemanager.cpp | 38 | ||||
-rw-r--r-- | src/game-server/attributemanager.h | 62 | ||||
-rw-r--r-- | src/game-server/being.cpp | 4 | ||||
-rw-r--r-- | src/game-server/character.cpp | 6 | ||||
-rw-r--r-- | src/game-server/monster.cpp | 6 | ||||
-rw-r--r-- | src/game-server/monstermanager.cpp | 6 |
9 files changed, 129 insertions, 81 deletions
diff --git a/src/common/defines.h b/src/common/defines.h index ca596316..3c7d8463 100644 --- a/src/common/defines.h +++ b/src/common/defines.h @@ -185,36 +185,4 @@ enum MOB_ATTR_MAG_ATK = 22 }; -/** - * Stackable types. - * @todo non-stackable malus layers - */ -enum StackableType -{ - Stackable, - NonStackable, - NonStackableBonus -}; - -/** - * Attribute augmentation methods. - */ -enum ModifierEffectType -{ - Multiplicative, - Additive -}; - -struct AttributeInfoType -{ - StackableType stackableType; - ModifierEffectType effectType; - - AttributeInfoType(StackableType s, - ModifierEffectType effect) : - stackableType(s), - effectType(effect) - {} -}; - #endif // DEFINES_H diff --git a/src/game-server/attribute.cpp b/src/game-server/attribute.cpp index 91113f49..82419e43 100644 --- a/src/game-server/attribute.cpp +++ b/src/game-server/attribute.cpp @@ -312,28 +312,34 @@ bool AttributeModifiersEffect::tick() return ret; } -Attribute::Attribute(const std::vector<struct AttributeInfoType> &type) - : mBase(0) +Attribute::Attribute(const AttributeManager::AttributeInfo &info): + mBase(0), + mMinValue(info.minimum), + mMaxValue(info.maximum) { - LOG_DEBUG("Construction of new attribute with '" << type.size() << "' layers."); - for (unsigned int i = 0; i < type.size(); ++i) + const std::vector<AttributeModifier> &modifiers = info.modifiers; + LOG_DEBUG("Construction of new attribute with '" << modifiers.size() + << "' layers."); + for (unsigned int i = 0; i < modifiers.size(); ++i) { - LOG_DEBUG("Adding layer with stackable type " << type[i].stackableType - << " and effect type " << type[i].effectType << "."); - mMods.push_back(new AttributeModifiersEffect(type[i].stackableType, - type[i].effectType)); + LOG_DEBUG("Adding layer with stackable type " + << modifiers[i].stackableType + << " and effect type " << modifiers[i].effectType << "."); + mMods.push_back(new AttributeModifiersEffect(modifiers[i].stackableType, + modifiers[i].effectType)); LOG_DEBUG("Layer added."); } + mBase = checkBounds(mBase); } Attribute::~Attribute() { - for (std::vector<AttributeModifiersEffect *>::iterator it = mMods.begin(), - it_end = mMods.end(); it != it_end; ++it) - { +// for (std::vector<AttributeModifiersEffect *>::iterator it = mMods.begin(), +// it_end = mMods.end(); it != it_end; ++it) +// { // ? //delete *it; - } +// } } bool Attribute::tick() @@ -365,8 +371,10 @@ void Attribute::clearMods() void Attribute::setBase(double base) { + base = checkBounds(base); LOG_DEBUG("Setting base attribute from " << mBase << " to " << base << "."); double prev = mBase = base; + std::vector<AttributeModifiersEffect *>::iterator it = mMods.begin(); while (it != mMods.end()) { @@ -383,3 +391,13 @@ void AttributeModifiersEffect::clearMods(double baseValue) mCacheVal = baseValue; mMod = mEffectType == Additive ? 0 : 1; } + +double Attribute::checkBounds(double baseValue) +{ + LOG_DEBUG("Checking bounds for value: " << baseValue); + if (baseValue > mMaxValue) + baseValue = mMaxValue; + else if (baseValue < mMinValue) + baseValue = mMinValue; + return baseValue; +} diff --git a/src/game-server/attribute.h b/src/game-server/attribute.h index cc7302d4..046c8f63 100644 --- a/src/game-server/attribute.h +++ b/src/game-server/attribute.h @@ -22,6 +22,7 @@ #define ATTRIBUTE_H #include "common/defines.h" +#include "attributemanager.h" #include <vector> #include <list> @@ -133,12 +134,13 @@ class Attribute public: Attribute() {throw;} // DEBUG; Find improper constructions - Attribute(const std::vector<struct AttributeInfoType> &type); + Attribute(const AttributeManager::AttributeInfo &info); ~Attribute(); void setBase(double base); double getBase() const { return mBase; } + double getModifiedAttribute() const { return mMods.empty() ? mBase : (*mMods.rbegin())->getCachedModifiedValue(); } @@ -185,7 +187,15 @@ class Attribute bool tick(); private: - double mBase; + /** + * Checks the min and max permitted values for the given base value + * and return the adjusted value. + */ + double checkBounds(double baseValue); + + double mBase; // The attribute base value + double mMinValue; // The min authorized base and derived attribute value + double mMaxValue; // The max authorized base and derived attribute value std::vector<AttributeModifiersEffect *> mMods; }; diff --git a/src/game-server/attributemanager.cpp b/src/game-server/attributemanager.cpp index bb307846..d7a4214a 100644 --- a/src/game-server/attributemanager.cpp +++ b/src/game-server/attributemanager.cpp @@ -49,9 +49,9 @@ void AttributeManager::reload() { unsigned int lCount = 0; LOG_DEBUG(" "<<i->first<<" : "); - for (std::vector<struct AttributeInfoType>::const_iterator j = i->second.second.begin(); - j != i->second.second.end(); - ++j) + for (std::vector<AttributeModifier>::const_iterator j = + i->second.modifiers.begin(); + j != i->second.modifiers.end(); ++j) { tag = getTag(ModifierLocation(i->first, lCount)); std::string end = tag ? "tag of '" + (*tag) + "'." : "no tag."; @@ -74,15 +74,15 @@ void AttributeManager::reload() LOG_INFO("Loaded '" << mTagMap.size() << "' modifier tags."); } -const std::vector<struct AttributeInfoType> *AttributeManager::getAttributeInfo(int id) const +const std::vector<AttributeModifier> *AttributeManager::getAttributeInfo(int id) const { AttributeMap::const_iterator ret = mAttributeMap.find(id); if (ret == mAttributeMap.end()) return 0; - return &ret->second.second; + return &ret->second.modifiers; } -const AttributeScope &AttributeManager::getAttributeScope(ScopeType type) const +const AttributeManager::AttributeScope &AttributeManager::getAttributeScope(ScopeType type) const { return mAttributeScopes[type]; } @@ -92,7 +92,7 @@ bool AttributeManager::isAttributeDirectlyModifiable(int id) const AttributeMap::const_iterator ret = mAttributeMap.find(id); if (ret == mAttributeMap.end()) return false; - return ret->second.first; + return ret->second.modifiable; } ModifierLocation AttributeManager::getLocation(const std::string &tag) const @@ -144,8 +144,12 @@ void AttributeManager::readAttributeNode(xmlNodePtr attributeNode) return; } - mAttributeMap[id] = - AttributeInfoMap(false, std::vector<struct AttributeInfoType>()); + mAttributeMap[id].modifiable = false; + mAttributeMap[id].modifiers = std::vector<AttributeModifier>(); + mAttributeMap[id].minimum = XML::getFloatProperty(attributeNode, "minimum", + std::numeric_limits<double>::min()); + mAttributeMap[id].maximum = XML::getFloatProperty(attributeNode, "maximum", + std::numeric_limits<double>::max()); for_each_xml_child_node(subNode, attributeNode) { @@ -166,19 +170,22 @@ void AttributeManager::readAttributeNode(xmlNodePtr attributeNode) } else if (scope == "CHARACTER") { - mAttributeScopes[CharacterScope][id] = &mAttributeMap.at(id).second; + mAttributeScopes[CharacterScope][id] = + &mAttributeMap.at(id); LOG_DEBUG("Attribute manager: attribute '" << id << "' added to default character scope."); } else if (scope == "MONSTER") { - mAttributeScopes[MonsterScope][id] = &mAttributeMap.at(id).second; + mAttributeScopes[MonsterScope][id] = + &mAttributeMap.at(id); LOG_DEBUG("Attribute manager: attribute '" << id << "' added to default monster scope."); } else if (scope == "BEING") { - mAttributeScopes[BeingScope][id] = &mAttributeMap.at(id).second; + mAttributeScopes[BeingScope][id] = + &mAttributeMap.at(id); LOG_DEBUG("Attribute manager: attribute '" << id << "' added to default being scope."); } @@ -242,12 +249,13 @@ void AttributeManager::readModifierNode(xmlNodePtr modifierNode, return; } - mAttributeMap[attributeId].second.push_back( - AttributeInfoType(stackableType, effectType)); + mAttributeMap[attributeId].modifiers.push_back( + AttributeModifier(stackableType, effectType)); if (!tag.empty()) { - const int layer = mAttributeMap[attributeId].second.size() - 1; + const int layer = + mAttributeMap[attributeId].modifiers.size() - 1; mTagMap.insert(std::make_pair(tag, ModifierLocation(attributeId, layer))); } diff --git a/src/game-server/attributemanager.h b/src/game-server/attributemanager.h index c4843c3a..63ebf643 100644 --- a/src/game-server/attributemanager.h +++ b/src/game-server/attributemanager.h @@ -24,6 +24,7 @@ #include <map> #include <vector> #include <string> +#include <limits> #include "utils/xml.h" @@ -36,7 +37,36 @@ enum ScopeType MaxScope }; -typedef std::map<int, std::vector<struct AttributeInfoType> *> AttributeScope; +/** + * Stackable types. + * @todo non-stackable malus layers + */ +enum StackableType +{ + Stackable, + NonStackable, + NonStackableBonus +}; + +/** + * Attribute augmentation methods. + */ +enum ModifierEffectType +{ + Multiplicative, + Additive +}; + +struct AttributeModifier +{ + AttributeModifier(StackableType s, ModifierEffectType effect) : + stackableType(s), + effectType(effect) + {} + + StackableType stackableType; + ModifierEffectType effectType; +}; /** * Identifies a modifier by the attribute id that it applies to and its layer @@ -59,6 +89,22 @@ struct ModifierLocation class AttributeManager { public: + struct AttributeInfo { + AttributeInfo(): + minimum(std::numeric_limits<double>::min()), + maximum(std::numeric_limits<double>::max()), + modifiable(false) + {} + + /** The minimum and maximum permitted attribute values. */ + double minimum; + double maximum; + /** Tells whether the base attribute is modifiable by the player */ + bool modifiable; + /** Effect modifier type: stackability and modification type. */ + std::vector<struct AttributeModifier> modifiers; + }; + AttributeManager(const std::string &file) : mAttributeReferenceFile(file) {} @@ -73,7 +119,10 @@ class AttributeManager */ void reload(); - const std::vector<struct AttributeInfoType> *getAttributeInfo(int id) const; + const std::vector<AttributeModifier> *getAttributeInfo(int id) const; + + // being type id -> (*{ stackable type, effect type })[] + typedef std::map<int, AttributeInfo*> AttributeScope; const AttributeScope &getAttributeScope(ScopeType) const; @@ -88,17 +137,12 @@ class AttributeManager void readAttributeNode(xmlNodePtr attributeNode); void readModifierNode(xmlNodePtr modifierNode, int attributeId); - // modifiable, { stackable type, effect type }[] - typedef std::pair<bool, - std::vector<struct AttributeInfoType> > AttributeInfoMap; - - // Attribute id -> { modifiable, { stackable type, effect type }[] } - typedef std::map<int, AttributeInfoMap> AttributeMap; + // Attribute id -> { modifiable, min, max, { stackable type, effect type }[] } + typedef std::map<int, AttributeInfo> AttributeMap; /** Maps tag names to specific modifiers. */ typedef std::map<std::string, ModifierLocation> TagMap; - // being type id -> (*{ stackable type, effect type })[] AttributeScope mAttributeScopes[MaxScope]; AttributeMap mAttributeMap; TagMap mTagMap; diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index 82080459..d44d2a6d 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -42,9 +42,9 @@ Being::Being(ThingType type): mGender(GENDER_UNSPECIFIED), mDirection(DOWN) { - const AttributeScope &attr = attributeManager->getAttributeScope(BeingScope); + const AttributeManager::AttributeScope &attr = attributeManager->getAttributeScope(BeingScope); LOG_DEBUG("Being creation: initialisation of " << attr.size() << " attributes."); - for (AttributeScope::const_iterator it1 = attr.begin(), + for (AttributeManager::AttributeScope::const_iterator it1 = attr.begin(), it1_end = attr.end(); it1 != it1_end; ++it1) diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 70dd3444..66fbd160 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -69,11 +69,11 @@ Character::Character(MessageIn &msg): mParty(0), mTransaction(TRANS_NONE) { - const AttributeScope &attr = + const AttributeManager::AttributeScope &attr = attributeManager->getAttributeScope(CharacterScope); LOG_DEBUG("Character creation: initialisation of " << attr.size() << " attributes."); - for (AttributeScope::const_iterator it1 = attr.begin(), + for (AttributeManager::AttributeScope::const_iterator it1 = attr.begin(), it1_end = attr.end(); it1 != it1_end; ++it1) mAttributes.insert(std::make_pair(it1->first, Attribute(*it1->second))); @@ -396,7 +396,7 @@ bool Character::recalculateBaseAttribute(unsigned int attr) /* * `attr' may or may not have changed. Recalculate the base value. */ - LOG_DEBUG("Received update attribute recalculation request at Character" + LOG_DEBUG("Received update attribute recalculation request at Character " "for " << attr << "."); if (!mAttributes.count(attr)) return false; diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp index f7218686..6e40fb24 100644 --- a/src/game-server/monster.cpp +++ b/src/game-server/monster.cpp @@ -59,10 +59,10 @@ Monster::Monster(MonsterClass *specy): /* * Initialise the attribute structures. */ - const AttributeScope &mobAttr = attributeManager->getAttributeScope( - MonsterScope); + const AttributeManager::AttributeScope &mobAttr = + attributeManager->getAttributeScope(MonsterScope); - for (AttributeScope::const_iterator it = mobAttr.begin(), + for (AttributeManager::AttributeScope::const_iterator it = mobAttr.begin(), it_end = mobAttr.end(); it != it_end; ++it) { mAttributes.insert(std::pair< unsigned int, Attribute > diff --git a/src/game-server/monstermanager.cpp b/src/game-server/monstermanager.cpp index 313be34e..bebb74a3 100644 --- a/src/game-server/monstermanager.cpp +++ b/src/game-server/monstermanager.cpp @@ -169,11 +169,11 @@ void MonsterManager::initialize() } bool attributesComplete = true; - const AttributeScope &mobAttr = + const AttributeManager::AttributeScope &mobAttr = attributeManager->getAttributeScope(MonsterScope); - for (AttributeScope::const_iterator it = mobAttr.begin(), - it_end = mobAttr.end(); it != it_end; ++it) + for (AttributeManager::AttributeScope::const_iterator it = + mobAttr.begin(), it_end = mobAttr.end(); it != it_end; ++it) { if (!monster->mAttributes.count(it->first)) { |