summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/game-server/being.cpp70
-rw-r--r--src/game-server/being.hpp26
-rw-r--r--src/game-server/character.cpp74
-rw-r--r--src/game-server/character.hpp11
4 files changed, 115 insertions, 66 deletions
diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp
index 5fbd9a8b..65338696 100644
--- a/src/game-server/being.cpp
+++ b/src/game-server/being.cpp
@@ -33,6 +33,7 @@
#include "game-server/statuseffect.hpp"
#include "game-server/statusmanager.hpp"
#include "utils/logger.h"
+#include "utils/speedconv.hpp"
Being::Being(ThingType type):
Actor(type),
@@ -360,7 +361,7 @@ bool Being::removeModifier(unsigned int attr, double value, unsigned int layer,
return ret;
}
-void Being::setAttribute(unsigned int id, double value, bool calc)
+void Being::setAttribute(unsigned int id, double value)
{
AttributeMap::iterator ret = mAttributes.find(id);
if (ret == mAttributes.end())
@@ -373,10 +374,10 @@ void Being::setAttribute(unsigned int id, double value, bool calc)
LOG_WARN("Being: Creation of new attributes dynamically is not "
"implemented yet!");
}
- else {
+ else
+ {
ret->second.setBase(value);
- if (calc)
- updateDerivedAttributes(id);
+ updateDerivedAttributes(id);
}
}
@@ -402,6 +403,67 @@ void Being::setModAttribute(unsigned int id, double value)
return;
}
+bool Being::recalculateBaseAttribute(unsigned int attr)
+{
+ LOG_DEBUG("Received update attribute recalculation request at Being for "
+ << attr << ".");
+ if (!mAttributes.count(attr)) return false;
+ double newBase = getAttribute(attr);
+
+ switch (attr)
+ {
+ case ATTR_HP_REGEN:
+ {
+ double hpPerSec = getModifiedAttribute(ATTR_VIT) * 0.05;
+ newBase = (hpPerSec * TICKS_PER_HP_REGENERATION / 10);
+ }
+ break;
+ case ATTR_HP:
+ double diff;
+ if ((diff = getModifiedAttribute(ATTR_HP)
+ - getModifiedAttribute(ATTR_MAX_HP)) > 0)
+ newBase -= diff;
+ break;
+ case ATTR_MAX_HP:
+ newBase = ((getModifiedAttribute(ATTR_VIT) + 3)
+ * (getModifiedAttribute(ATTR_VIT) + 20)) * 0.125;
+ break;
+ case ATTR_MOVE_SPEED_TPS:
+ newBase = 3.0 + getModifiedAttribute(ATTR_AGI) * 0.08; // Provisional.
+ break;
+ case ATTR_MOVE_SPEED_RAW:
+ newBase = utils::tpsToSpeed(getModifiedAttribute(ATTR_MOVE_SPEED_TPS));
+ break;
+ case ATTR_INV_CAPACITY:
+ // Provisional
+ newBase = 2000.0 + getModifiedAttribute(ATTR_STR) * 180.0;
+ break;
+ }
+ if (newBase != getAttribute(attr))
+ {
+ setAttribute(attr, newBase);
+ updateDerivedAttributes(attr);
+ return true;
+ }
+ LOG_DEBUG("No changes to sync for attribute '" << attr << "'.");
+ return false;
+}
+
+void Being::updateDerivedAttributes(unsigned int attr)
+{
+ switch(attr)
+ {
+ case ATTR_MAX_HP:
+ updateDerivedAttributes(ATTR_HP);
+ case ATTR_HP:
+ raiseUpdateFlags(UPDATEFLAG_HEALTHCHANGE);
+ break;
+ case ATTR_MOVE_SPEED_TPS:
+ updateDerivedAttributes(ATTR_MOVE_SPEED_RAW);
+ break;
+ }
+}
+
void Being::applyStatusEffect(int id, int timer)
{
if (mAction == DEAD)
diff --git a/src/game-server/being.hpp b/src/game-server/being.hpp
index 0fb60a29..4506cfec 100644
--- a/src/game-server/being.hpp
+++ b/src/game-server/being.hpp
@@ -174,18 +174,6 @@ class Being : public Actor
{ return mDirection; }
/**
- * Gets beings speed.
- * The speed is given in tiles per second.
- */
-
- /**
- * Gets beings speed.
- * The speed is to be set in tiles per second
- * This function automatically transform it
- * into millsecond per tile.
- */
-
- /**
* Gets the damage list.
*/
const Hits &getHitsTaken() const
@@ -234,7 +222,7 @@ class Being : public Actor
/**
* Sets an attribute.
*/
- void setAttribute(unsigned int id, double value, bool calc = true);
+ void setAttribute(unsigned int id, double value);
/**
* Gets an attribute.
@@ -276,8 +264,18 @@ class Being : public Actor
/**
* Called when an attribute modifier is changed.
+ * Recalculate the base value of an attribute and update derived
+ * attributes if it has changed.
+ * @returns Whether it was changed.
+ */
+ virtual bool recalculateBaseAttribute(unsigned int);
+
+ /**
+ * Attribute has changed, recalculate base value of dependant
+ * attributes (and handle other actions for the modified
+ * attribute)
*/
- virtual void updateDerivedAttributes(unsigned int) {}
+ virtual void updateDerivedAttributes(unsigned int);
/**
* Sets a statuseffect on this being
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp
index 3b27ae64..feed0e0f 100644
--- a/src/game-server/character.cpp
+++ b/src/game-server/character.cpp
@@ -44,7 +44,6 @@
#include "serialize/characterdata.hpp"
#include "utils/logger.h"
-#include "utils/speedconv.hpp"
// Experience curve related values
const float Character::EXPCURVE_EXPONENT = 3.0f;
@@ -358,14 +357,15 @@ void Character::modifiedAllAttribute()
updateDerivedAttributes(it->first);
}
-void Character::updateDerivedAttributes(unsigned int attr)
+bool Character::recalculateBaseAttribute(unsigned int attr)
{
-// Much of this is remnants from the previous attribute system (placeholder?)
-// This could be improved by defining what attributes are derived from others
-// in xml or otherwise, so only those that need to be recomputed are.
- LOG_DEBUG("Received modified attribute recalculation request for "
- << attr << ".");
- if (!mAttributes.count(attr)) return;
+ /*
+ * `attr' may or may not have changed. Recalculate the base value.
+ */
+ LOG_DEBUG("Received update attribute recalculation request at Character"
+ "for " << attr << ".");
+ if (!mAttributes.count(attr))
+ return false;
double newBase = getAttribute(attr);
/*
@@ -394,44 +394,27 @@ void Character::updateDerivedAttributes(unsigned int attr)
newBase = 0.0;
// TODO
break;
- case ATTR_HP_REGEN:
- {
- double hpPerSec = getModifiedAttribute(ATTR_VIT) * 0.05;
- newBase = (hpPerSec * TICKS_PER_HP_REGENERATION / 10);
- }
- break;
- case ATTR_HP:
- double diff;
- if ((diff = getModifiedAttribute(ATTR_HP)
- - getModifiedAttribute(ATTR_MAX_HP)) > 0)
- newBase -= diff;
- break;
- case ATTR_MAX_HP:
- newBase = ((getModifiedAttribute(ATTR_VIT) + 3)
- * (getModifiedAttribute(ATTR_VIT) + 20)) * 0.125;
- break;
- case ATTR_MOVE_SPEED_TPS:
- newBase = 3.0 + getModifiedAttribute(ATTR_AGI) * 0.08; // Provisional.
- break;
- case ATTR_MOVE_SPEED_RAW:
- newBase = utils::tpsToSpeed(getModifiedAttribute(ATTR_MOVE_SPEED_TPS));
- break;
- case ATTR_INV_CAPACITY:
- // Provisional
- newBase = 2000.0 + getModifiedAttribute(ATTR_STR) * 180.0;
- break;
- default: break;
+ default:
+ return Being::recalculateBaseAttribute(attr);
}
if (newBase != getAttribute(attr))
- Being::setAttribute(attr, newBase, false);
- else
- LOG_DEBUG("No changes to sync.");
- flagAttribute(attr);
+ {
+ setAttribute(attr, newBase);
+ updateDerivedAttributes(attr);
+ return true;
+ }
+ LOG_DEBUG("No changes to sync for attribute '" << attr << "'.");
+ return false;
+}
+void Character::updateDerivedAttributes(unsigned int attr)
+{
/*
- * Update attributes dependent on this one, if applicable.
+ * `attr' has changed, perform updates accordingly.
*/
+ flagAttribute(attr);
+
switch(attr)
{
case ATTR_STR:
@@ -447,19 +430,16 @@ void Character::updateDerivedAttributes(unsigned int attr)
updateDerivedAttributes(ATTR_DEFENSE);
break;
case ATTR_INT:
+ // TODO
break;
case ATTR_DEX:
updateDerivedAttributes(ATTR_ACCURACY);
break;
case ATTR_WIL:
+ // TODO
break;
- case ATTR_MAX_HP:
- updateDerivedAttributes(ATTR_HP);
- break;
- case ATTR_MOVE_SPEED_TPS:
- updateDerivedAttributes(ATTR_MOVE_SPEED_RAW);
- break;
- default: break;
+ default:
+ Being::updateDerivedAttributes(attr);
}
}
diff --git a/src/game-server/character.hpp b/src/game-server/character.hpp
index 99d9953b..ed41c2b2 100644
--- a/src/game-server/character.hpp
+++ b/src/game-server/character.hpp
@@ -227,7 +227,16 @@ class Character : public Being
void modifiedAllAttribute();
/**
- * Updates base Being attributes.
+ * Recalculate the base value of an attribute and update derived
+ * attributes if it has changed.
+ * @returns Whether it was changed.
+ */
+ bool recalculateBaseAttribute(unsigned int);
+
+ /**
+ * Attribute has changed, recalculate base value of dependant
+ * attributes (and handle other actions for the modified
+ * attribute)
*/
void updateDerivedAttributes(unsigned int);