From 7e1011ccea542f4bc972c0a9c03eaca4a718566b Mon Sep 17 00:00:00 2001 From: Philipp Sehmisch Date: Thu, 15 Mar 2007 23:47:13 +0000 Subject: Set the default map position of new characters to a value that makes more sense. Implemented new basic attribute system on account server. Removed attribute modifiers, unified basic and derived attributes, storing attributes in a vector, renamed some attribute identifiers, removed identifiers for derived attributes that aren't needed yet. --- src/game-server/being.cpp | 162 ++++++++++------------------------------ src/game-server/being.hpp | 99 ++++++++---------------- src/game-server/character.cpp | 42 +++++++---- src/game-server/character.hpp | 20 +++-- src/game-server/item.hpp | 3 +- src/game-server/itemmanager.cpp | 27 +++---- src/game-server/testing.cpp | 7 +- 7 files changed, 126 insertions(+), 234 deletions(-) (limited to 'src/game-server') diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index 8703fc2b..d3c151e7 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -22,6 +22,7 @@ #include "game-server/being.hpp" +#include "defines.h" #include "game-server/collisiondetection.hpp" #include "game-server/mapcomposite.hpp" #include "utils/logger.h" @@ -30,17 +31,7 @@ Being::Being(int type, int id): MovingObject(type, id), mAction(STAND) { - for (int i = 0; i < NB_BASE_ATTRIBUTES; i++) - { - mBaseAttributes[i] = 0; - } - for (int j = 0; j < NB_COMPOUND_ATTRIBUTES; j++) - { - mCompoundAttributes[j] = 0; - } - mBeingModificators.absoluteModificator.resize(NB_COMPOUND_ATTRIBUTES, 0); - mBeingModificators.percentModificators.resize(NB_COMPOUND_ATTRIBUTES); - //TODO: set the base attributes, calculate the compound attributes + mAttributes.resize(NB_ATTRIBUTES_BEING); } Being::~Being() @@ -59,14 +50,14 @@ void Being::damage(Damage damage) switch (damage.type) { case DAMAGETYPE_PHYSICAL: - HPloss -= getCompoundAttribute(ATT_PHYSICAL_DEFENCE) - / damage.penetration; + HPloss -= getAttribute(DERIVED_ATTR_PHYSICAL_DEFENCE) / damage.piercing; + HPloss -= getAttribute(BASE_ATTR_VITALITY); break; case DAMAGETYPE_MAGICAL: - // NIY + HPloss /= getAttribute(BASE_ATTR_WILLPOWER) + 1; break; case DAMAGETYPE_HAZARD: - // NIY + HPloss /= getAttribute(BASE_ATTR_VITALITY) + 1; break; case DAMAGETYPE_OTHER: // nothing to do here @@ -165,127 +156,54 @@ void Being::setAction(Action action) } } -void Being::addAbsoluteStatModifier(int attributeNumber, short value) -{ - mBeingModificators.absoluteModificator.at(attributeNumber) += value; - calculateCompoundAttribute(attributeNumber); -} - -void Being::removeAbsoluteStatModifier(int attributeNumber, short value) -{ - mBeingModificators.absoluteModificator.at(attributeNumber) -= value; - calculateCompoundAttribute(attributeNumber); -} - -void Being::addPercentStatModifier(int attributeNumber, short value) -{ - if (value < -100) - { - LOG_WARN( "Attempt to add a stat modificator for Being"<< - getPublicID()<< - "that would make the stat negative!" - ); - return; - } - - mBeingModificators.percentModificators.at(attributeNumber).push_back(value); - calculateCompoundAttribute(attributeNumber); -} - -void Being::removePercentStatModifier(int attributeNumber, short value) -{ - std::list::iterator - i = mBeingModificators.percentModificators.at(attributeNumber).begin(), - i_end = mBeingModificators.percentModificators.at(attributeNumber).end(); - for (; i != i_end; i++) - { - if ((*i) = value) - { - mBeingModificators.percentModificators.at(attributeNumber).erase(i); - break; - } - } - if (i == i_end) - LOG_WARN("Attempt to remove a stat modificator for Being" << - getPublicID() << - "that hasn't been added before!"); - - calculateCompoundAttribute(attributeNumber); - - return; -} - -void Being::calculateCompoundAttribute(int attributeNumber) +void Being::calculateDerivedAttributes() { - int value; - - if (attributeNumber < NB_BASE_ATTRIBUTES) - value = getBaseAttribute(attributeNumber); - - switch (attributeNumber) + // effective values for basic attributes + for (int i = NB_BASE_ATTRIBUTES; i < NB_EFFECTIVE_ATTRIBUTES; i++) { - case ATT_HP_MAXIMUM: - value = 20 + (20 * getBaseAttribute(ATT_VITALITY)); - break; - case ATT_PHYSICAL_ATTACK_MINIMUM: - value = 10 + getBaseAttribute(ATT_STRENGTH); - break; - case ATT_PHYSICAL_ATTACK_FLUCTUATION: - value = 10; - break; - case ATT_PHYSICAL_DEFENCE: - value = 10 + getBaseAttribute(ATT_STRENGTH); - break; - case ATT_MAGIC: - value = 0; - break; - case ATT_ACCURACY: - value = 50 + getBaseAttribute(ATT_DEXTERITY); - break; - case ATT_SPEED: - value = getBaseAttribute(ATT_AGILITY); - break; + mAttributes.at(i) + = getAttribute(i - NB_BASE_ATTRIBUTES); // TODO: add modifiers } - value += mBeingModificators.absoluteModificator.at(attributeNumber); + // combat-related derived stats + mAttributes.at(DERIVED_ATTR_HP_MAXIMUM) + = getAttribute(ATTR_EFF_VITALITY); // TODO: find a better formula - std::list::iterator i; + mAttributes.at(DERIVED_ATTR_PHYSICAL_ATTACK_MINIMUM) + = getAttribute(ATTR_EFF_STRENGTH); - float multiplier = 1.0f; - - for ( i = mBeingModificators.percentModificators.at(attributeNumber).begin(); - i != mBeingModificators.percentModificators.at(attributeNumber).end(); - i++ - ) - { - multiplier *= (100.0f + (float)(*i)) / 100.0f; - } + mAttributes.at(DERIVED_ATTR_PHYSICAL_ATTACK_FLUCTUATION) + = getAttribute(getWeaponStats().skill); - /* Floating point inaccuracies might result in a negative multiplier. That - * would result in a stat near 2^16. To make sure that this doesn't happen - * we return a value of 0 in that case - */ - mCompoundAttributes[attributeNumber] = - (multiplier < 0.0f) ? 0 : (unsigned short)(value * multiplier); -} - -void Being::recalculateAllCompoundAttributes() -{ - for (int i = 0; i < (NB_COMPOUND_ATTRIBUTES); i++) - { - calculateCompoundAttribute(i); - } + mAttributes.at(DERIVED_ATTR_PHYSICAL_DEFENCE) + = 0 /* + sum of equipment pieces */; } Damage Being::getPhysicalAttackDamage() { Damage damage; + WeaponStats weaponStats = getWeaponStats(); + damage.type = DAMAGETYPE_PHYSICAL; - damage.value = getCompoundAttribute(ATT_PHYSICAL_ATTACK_MINIMUM) - + (rand()%getCompoundAttribute(ATT_PHYSICAL_ATTACK_FLUCTUATION)); - damage.penetration = 1; // TODO: get from equipped weapon - damage.element = ELEMENT_NEUTRAL; // TODO: get from equipped weapon + damage.value = getAttribute(DERIVED_ATTR_PHYSICAL_ATTACK_MINIMUM) + + (rand()%getAttribute(DERIVED_ATTR_PHYSICAL_ATTACK_FLUCTUATION)); + damage.piercing = weaponStats.piercing; + damage.element = weaponStats.element; damage.source = this; return damage; } + +WeaponStats Being::getWeaponStats() +{ + /* this function should never be called. it is just here to pacify the + * compiler. + */ + WeaponStats weaponStats; + + weaponStats.piercing = 1; + weaponStats.element = ELEMENT_NEUTRAL; + weaponStats.skill = 0; + + return weaponStats; +}; diff --git a/src/game-server/being.hpp b/src/game-server/being.hpp index a245f617..cd613376 100644 --- a/src/game-server/being.hpp +++ b/src/game-server/being.hpp @@ -38,14 +38,7 @@ class MapComposite; */ enum { - ATT_HP_MAXIMUM = NB_BASE_ATTRIBUTES, - ATT_PHYSICAL_ATTACK_MINIMUM, - ATT_PHYSICAL_ATTACK_FLUCTUATION, - ATT_PHYSICAL_DEFENCE, - ATT_MAGIC, - ATT_ACCURACY, - ATT_SPEED, - NB_COMPOUND_ATTRIBUTES + }; /** @@ -92,25 +85,26 @@ enum Damagetype struct Damage { int value; - int penetration; + int piercing; Element element; Damagetype type; Being *source; }; /** - * Type definition for a list of hits + * Structure that holds weapon stats that are relevant for damage calculation */ -typedef std::list Hits; +struct WeaponStats +{ + int piercing; + Element element; + int skill; +}; /** - * Structures for storing the attribute modifiers of a Being. + * Type definition for a list of hits */ -struct BeingModificators -{ - std::vector absoluteModificator; - std::vector< std::list > percentModificators; -}; +typedef std::list Hits; /** @@ -142,34 +136,6 @@ class Being : public MovingObject ~Being(); - /** - * Adds a fixed value stat modifier - */ - void addAbsoluteStatModifier(int attributeNumber, short value); - - /** - * Removes a fixed value stat modifier - */ - void removeAbsoluteStatModifier(int attributeNumber, short value); - - /** - * Adds a multiplier stat modificator in percent - */ - void addPercentStatModifier(int attributeNumber, short value); - - /** - * Removes a previously added percent stat modifier. - * Does nothing and logs a warning when no modifier with the same - * value has been added before. - */ - void removePercentStatModifier(int attributeNumber, short value); - - /** - * Returns a specific compound attribute of a being. - */ - unsigned short getCompoundAttribute(int attributeNumber) - { return mCompoundAttributes[attributeNumber]; } - /** * Creates a damage structure for a normal melee attack based on the * current being stats and equipment. @@ -177,10 +143,10 @@ class Being : public MovingObject Damage getPhysicalAttackDamage(); /** - * sets the hit points + * Sets the hit points to maximum */ - void setHitpoints(unsigned hp) - { mHitpoints = hp; } + void fillHitpoints() + { mHitpoints = getAttribute(DERIVED_ATTR_HP_MAXIMUM); } /** * Takes a damage structure, computes the real damage based on the @@ -228,44 +194,41 @@ class Being : public MovingObject virtual void move(); /** - * FOR TESTING PURPOSES ONLY - * Sets a compound attribute. - * Remember, they're modified after a modifier is added. + * Sets an attribute (doesn't work on derived attributes) */ - void setCompoundAttribute(int attributeNumber, unsigned short value) - { mCompoundAttributes[attributeNumber] = value; } - - protected: + void setAttribute(int attributeNumber, unsigned short value) + { + mAttributes.at(attributeNumber) = value; + calculateDerivedAttributes(); + } /** - * Sets a base attribute. + * Gets an attribute. */ - void setBaseAttribute(int attributeNumber, unsigned short value) - { mBaseAttributes[attributeNumber] = value; } + unsigned short getAttribute(int attributeNumber) const + { return mAttributes.at(attributeNumber); } + protected: /** - * Gets a derived attribute. + * Calculates all derived attributes of a beings */ - unsigned short getBaseAttribute(int attributeNumber) const - { return mBaseAttributes[attributeNumber]; } + void calculateDerivedAttributes(); /** - * Recalculates the compound attributes of a being. + * Gets the stats of the currently equipped weapon that are relevant + * for damage calculation */ - void recalculateAllCompoundAttributes(); - - void calculateCompoundAttribute(int attributeNumber); + virtual WeaponStats getWeaponStats(); int mHitpoints; /**< Hitpoints of the being */ Action mAction; - BeingModificators mBeingModificators; + + std::vector mAttributes; private: Being(Being const &rhs); Being &operator=(Being const &rhs); - unsigned short mBaseAttributes[NB_BASE_ATTRIBUTES]; - unsigned short mCompoundAttributes[NB_COMPOUND_ATTRIBUTES]; Hits mHitsTaken; /**< List of punches taken since last update */ }; diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp index 4aa0576d..ea4dd7c4 100644 --- a/src/game-server/character.cpp +++ b/src/game-server/character.cpp @@ -29,30 +29,23 @@ InventoryItem tempItem; -Character::Character(): - Being(OBJECT_CHARACTER, 65535), - mClient(NULL), - mDatabaseID(-1), mName(""), mGender(0), mHairStyle(0), mHairColor(0), - mLevel(0), mMoney(0) -{ - for (int i = 0; i < EQUIPMENT_SLOTS; ++i) - { - mPossessions.equipment[i] = 0; - } -} - Character::Character(MessageIn & msg): Being(OBJECT_CHARACTER, 65535), mClient(NULL), mDatabaseID(-1), mName(""), mGender(0), mHairStyle(0), mHairColor(0), mLevel(0), mMoney(0) { + // clear equipment for (int i = 0; i < EQUIPMENT_SLOTS; ++i) { mPossessions.equipment[i] = 0; } + // prepare attributes vector + mAttributes.resize(NB_ATTRIBUTES_CHAR, 1); + // get base attributes deserialize(msg); - recalculateAllCompoundAttributes(); + // give the player 10 weapon skill for testing purpose + setAttribute(CHAR_SKILL_WEAPON_UNARMED, 10); } /** * Update the internal status. @@ -106,3 +99,26 @@ Character::addItemToInventory(const InventoryItem& item) // TODO: implement after redesign/improvement of Inventory } +void Character::calculateDerivedAttributes() +{ + Being::calculateDerivedAttributes(); + /* + * Do any player character specific attribute calculation here + */ +} + +WeaponStats +Character::getWeaponStats() +{ + WeaponStats weaponStats; + + /* + * TODO: get all this stuff from the currently equipped weapon + */ + weaponStats.piercing = 1; + weaponStats.element = ELEMENT_NEUTRAL; + weaponStats.skill = CHAR_SKILL_WEAPON_UNARMED; + + return weaponStats; +}; + diff --git a/src/game-server/character.hpp b/src/game-server/character.hpp index 42736a79..b1c31f1b 100644 --- a/src/game-server/character.hpp +++ b/src/game-server/character.hpp @@ -47,11 +47,6 @@ class Character : public Being, public AbstractCharacterData { public: - /** - * Basic constructor - */ - Character(); - /** * Utility constructor for creating a Character from a received * characterdata message. @@ -165,7 +160,7 @@ class Character : public Being, public AbstractCharacterData */ unsigned short getBaseAttribute(int attributeNumber) const - { return Being::getBaseAttribute(attributeNumber); } + { return Being::getAttribute(attributeNumber); } /** * Sets the value of an attribute of the character. @@ -174,7 +169,7 @@ class Character : public Being, public AbstractCharacterData */ void setBaseAttribute(int attributeNumber, int value) - { Being::setBaseAttribute(attributeNumber, value); } + { Being::setAttribute(attributeNumber, value); } /** * Gets the Id of the map that the character is on. @@ -242,6 +237,17 @@ class Character : public Being, public AbstractCharacterData void addItemToInventory(const InventoryItem& item); + protected: + /** + * Calculates all derived attributes + */ + void calculateDerivedAttributes(); + + /** + * Gets the stats of the currently equipped weapon that are relevant + * for damage calculation + */ + virtual WeaponStats getWeaponStats(); private: Character(Character const &); diff --git a/src/game-server/item.hpp b/src/game-server/item.hpp index 08965076..d4d4af74 100644 --- a/src/game-server/item.hpp +++ b/src/game-server/item.hpp @@ -114,8 +114,7 @@ struct Modifiers unsigned short lifetime; /**< Modifiers lifetime in seconds. */ // Characteristics Modifiers - short baseAttributes[NB_BASE_ATTRIBUTES]; /**< Raw Stats modifiers */ - short derivedAttributes[NB_COMPOUND_ATTRIBUTES - NB_BASE_ATTRIBUTES]; /**< Computed Stats modifiers */ + short attributes[NB_ATTRIBUTES_CHAR]; /**< Attribute modifiers */ // Weapon unsigned short range; /**< Weapon Item Range */ diff --git a/src/game-server/itemmanager.cpp b/src/game-server/itemmanager.cpp index a372906c..1c456175 100644 --- a/src/game-server/itemmanager.cpp +++ b/src/game-server/itemmanager.cpp @@ -87,25 +87,18 @@ ItemManager::ItemManager(std::string const &itemReferenceFile) Modifiers modifiers; modifiers.element = XML::getProperty(node, "element", 0); modifiers.lifetime = XML::getProperty(node, "lifetime", 0); - modifiers.baseAttributes[ATT_STRENGTH] = XML::getProperty(node, "strength", 0); - modifiers.baseAttributes[ATT_AGILITY] = XML::getProperty(node, "agility", 0); - modifiers.baseAttributes[ATT_VITALITY] = XML::getProperty(node, "vitality", 0); - modifiers.baseAttributes[ATT_INTELLIGENCE] = XML::getProperty(node, "intelligence", 0); - modifiers.baseAttributes[ATT_DEXTERITY] = XML::getProperty(node, "dexterity", 0); - modifiers.baseAttributes[ATT_LUCK] = XML::getProperty(node, "luck", 0); -/** modifiers.baseAttributes[ATT_WILLPOWER] = XML::getProperty(node, "willpower", 0); - modifiers.baseAttributes[ATT_CHARISMA] = XML::getProperty(node, "charisma", 0);*/ - modifiers.derivedAttributes[ATT_HP_MAXIMUM] = XML::getProperty(node, "hp", 0); - modifiers.derivedAttributes[ATT_PHYSICAL_ATTACK_MINIMUM] = XML::getProperty(node, "attack", 0); - modifiers.derivedAttributes[ATT_PHYSICAL_DEFENCE] = XML::getProperty(node, "defence", 0); - modifiers.derivedAttributes[ATT_MAGIC] = XML::getProperty(node, "magic", 0); - modifiers.derivedAttributes[ATT_ACCURACY] = XML::getProperty(node, "accuracy", 0); - modifiers.derivedAttributes[ATT_SPEED] = XML::getProperty(node, "speed", 0); -/** modifiers.hp = XML::getProperty(node, "hp", 0); - modifiers.mp = XML::getProperty(node, "mp", 0);*/ + modifiers.attributes[BASE_ATTR_STRENGTH] = XML::getProperty(node, "strength", 0); + modifiers.attributes[BASE_ATTR_AGILITY] = XML::getProperty(node, "agility", 0); + modifiers.attributes[BASE_ATTR_VITALITY] = XML::getProperty(node, "vitality", 0); + modifiers.attributes[BASE_ATTR_INTELLIGENCE] = XML::getProperty(node, "intelligence", 0); + modifiers.attributes[BASE_ATTR_DEXTERITY] = XML::getProperty(node, "dexterity", 0); + modifiers.attributes[BASE_ATTR_WILLPOWER] = XML::getProperty(node, "willpower", 0); + modifiers.attributes[BASE_ATTR_CHARISMA] = XML::getProperty(node, "charisma", 0); + modifiers.attributes[DERIVED_ATTR_HP_MAXIMUM] = XML::getProperty(node, "hp", 0); + modifiers.attributes[DERIVED_ATTR_PHYSICAL_ATTACK_MINIMUM] = XML::getProperty(node, "attack", 0); + modifiers.attributes[DERIVED_ATTR_PHYSICAL_DEFENCE] = XML::getProperty(node, "defence", 0); modifiers.range = XML::getProperty(node, "range", 0); modifiers.weaponType = XML::getProperty(node, "weapon_type", 0); -/** modifiers.beingStateEffect = XML::getProperty(node, "status_effect", 0);*/ ItemClass *item = new ItemClass(id, itemType); item->setWeight(weight); diff --git a/src/game-server/testing.cpp b/src/game-server/testing.cpp index e09f4feb..7243793a 100644 --- a/src/game-server/testing.cpp +++ b/src/game-server/testing.cpp @@ -41,12 +41,9 @@ void testingMap(int id) being->setSize(8); // some bogus stats for testing - being->setCompoundAttribute(ATT_HP_MAXIMUM, 42); - being->setCompoundAttribute(ATT_PHYSICAL_ATTACK_MINIMUM, 1); - being->setCompoundAttribute(ATT_PHYSICAL_ATTACK_FLUCTUATION, 0); - being->setCompoundAttribute(ATT_PHYSICAL_DEFENCE, 5); + being->setAttribute(BASE_ATTR_VITALITY, 10); - being->setHitpoints(42); + being->fillHitpoints(); being->setMapId(1); Point pos(720, 900); -- cgit v1.2.3-60-g2f50