summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game-server/being.cpp84
-rw-r--r--src/game-server/being.h14
-rw-r--r--src/game-server/character.cpp89
-rw-r--r--src/game-server/character.h10
-rw-r--r--src/game-server/monster.cpp41
-rw-r--r--src/game-server/monster.h8
-rw-r--r--src/scripting/lua.cpp26
7 files changed, 96 insertions, 176 deletions
diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp
index d7df2df..2c334b3 100644
--- a/src/game-server/being.cpp
+++ b/src/game-server/being.cpp
@@ -34,6 +34,11 @@
#include "game-server/statusmanager.h"
#include "utils/logger.h"
#include "utils/speedconv.h"
+#include "scripting/scriptmanager.h"
+
+
+Script::Ref Being::mRecalculateDerivedAttributesCallback;
+Script::Ref Being::mRecalculateBaseAttributeCallback;
Being::Being(EntityType type):
Actor(type),
@@ -574,75 +579,64 @@ void Being::setModAttribute(unsigned, double)
return;
}
-bool Being::recalculateBaseAttribute(unsigned attr)
+void Being::recalculateBaseAttribute(unsigned attr)
{
LOG_DEBUG("Being: Received update attribute recalculation request for "
<< attr << ".");
if (!mAttributes.count(attr))
{
LOG_DEBUG("Being::recalculateBaseAttribute: " << attr << " not found!");
- return false;
+ return;
}
- double newBase = getAttribute(attr);
- switch (attr)
+ // Handle speed conversion inside the engine
+ if (attr == ATTR_MOVE_SPEED_RAW)
{
- 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::tpsToRawSpeed(
- 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);
- return true;
+ double newBase = utils::tpsToRawSpeed(
+ getModifiedAttribute(ATTR_MOVE_SPEED_TPS));
+ if (newBase != getAttribute(attr))
+ setAttribute(attr, newBase);
+ return;
}
- LOG_DEBUG("Being: No changes to sync for attribute '" << attr << "'.");
- return false;
+
+ if (!mRecalculateBaseAttributeCallback.isValid())
+ return;
+
+ Script *script = ScriptManager::currentState();
+ script->setMap(getMap());
+ script->prepare(mRecalculateBaseAttributeCallback);
+ script->push(this);
+ script->push(attr);
+ script->execute();
}
void Being::updateDerivedAttributes(unsigned attr)
{
LOG_DEBUG("Being: Updating derived attribute(s) of: " << attr);
+
+ // Handle default actions before handing over to the script engine
switch (attr)
{
case ATTR_MAX_HP:
- updateDerivedAttributes(ATTR_HP);
case ATTR_HP:
raiseUpdateFlags(UPDATEFLAG_HEALTHCHANGE);
break;
case ATTR_MOVE_SPEED_TPS:
- if (getAttribute(attr) > 0.0f)
- setAttribute(ATTR_MOVE_SPEED_RAW, utils::tpsToRawSpeed(
- getModifiedAttribute(ATTR_MOVE_SPEED_TPS)));
- break;
- default:
- // Do nothing
+ // Does not make a lot of sense to have in the scripts.
+ // So handle it here:
+ recalculateBaseAttribute(ATTR_MOVE_SPEED_RAW);
break;
}
+
+ if (!mRecalculateDerivedAttributesCallback.isValid())
+ return;
+
+ Script *script = ScriptManager::currentState();
+ script->setMap(getMap());
+ script->prepare(mRecalculateDerivedAttributesCallback);
+ script->push(this);
+ script->push(attr);
+ script->execute();
}
void Being::applyStatusEffect(int id, int timer)
diff --git a/src/game-server/being.h b/src/game-server/being.h
index d5a7358..1d1f420 100644
--- a/src/game-server/being.h
+++ b/src/game-server/being.h
@@ -238,7 +238,7 @@ class Being : public Actor
* attributes if it has changed.
* @returns Whether it was changed.
*/
- virtual bool recalculateBaseAttribute(unsigned);
+ virtual void recalculateBaseAttribute(unsigned);
/**
* Attribute has changed, recalculate base value of dependant
@@ -297,6 +297,12 @@ class Being : public Actor
void setTarget(Being *target)
{ mTarget = target; }
+ static void setUpdateDerivedAttributesCallback(Script *script)
+ { script->assignCallback(mRecalculateDerivedAttributesCallback); }
+
+ static void setRecalculateBaseAttributeCallback(Script *script)
+ { script->assignCallback(mRecalculateBaseAttributeCallback); }
+
sigc::signal<void, Being *> signal_died;
/**
@@ -356,6 +362,12 @@ class Being : public Actor
/** The last being emote Id. Used when triggering a being emoticon. */
int mEmoteId;
+
+ /** Called when derived attributes need to get calculated */
+ static Script::Ref mRecalculateDerivedAttributesCallback;
+
+ /** Called when a base attribute needs to get calculated */
+ static Script::Ref mRecalculateBaseAttributeCallback;
};
#endif // BEING_H
diff --git a/src/game-server/character.cpp b/src/game-server/character.cpp
index a977799..cf5415d 100644
--- a/src/game-server/character.cpp
+++ b/src/game-server/character.cpp
@@ -464,65 +464,26 @@ void Character::modifiedAllAttribute()
}
}
-bool Character::recalculateBaseAttribute(unsigned attr)
+void Character::recalculateBaseAttribute(unsigned attr)
{
- /*
- * `attr' may or may not have changed. Recalculate the base value.
- */
+ // `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);
-
- /*
- * Calculate new base.
- */
- switch (attr)
- {
- case ATTR_ACCURACY:
- newBase = getModifiedAttribute(ATTR_DEX); // Provisional
- break;
- case ATTR_DEFENSE:
- newBase = 0.3 * getModifiedAttribute(ATTR_VIT);
- break;
- case ATTR_DODGE:
- newBase = getModifiedAttribute(ATTR_AGI); // Provisional
- break;
- case ATTR_MAGIC_DODGE:
- newBase = 1.0;
- // TODO
- break;
- case ATTR_MAGIC_DEFENSE:
- newBase = 0.0;
- // TODO
- break;
- case ATTR_BONUS_ASPD:
- newBase = 0.0;
- // TODO
- break;
- case ATTR_STR:
- if (mKnuckleAttackInfo)
- {
- Damage &knuckleDamage = mKnuckleAttackInfo->getDamage();
- knuckleDamage.base = getModifiedAttribute(ATTR_STR);
- knuckleDamage.delta = knuckleDamage.base / 2;
- }
- break;
- default:
- return Being::recalculateBaseAttribute(attr);
- }
+ return;
- if (newBase != getAttribute(attr))
+ if (attr == ATTR_STR && mKnuckleAttackInfo)
{
- setAttribute(attr, newBase);
- updateDerivedAttributes(attr);
- return true;
+ // TODO: dehardcode this
+ Damage &knuckleDamage = mKnuckleAttackInfo->getDamage();
+ knuckleDamage.base = getModifiedAttribute(ATTR_STR);
+ knuckleDamage.delta = knuckleDamage.base / 2;
}
- LOG_DEBUG("No changes to sync for attribute '" << attr << "'.");
- return false;
+ Being::recalculateBaseAttribute(attr);
+
}
+
void Character::updateDerivedAttributes(unsigned attr)
{
/*
@@ -530,32 +491,8 @@ void Character::updateDerivedAttributes(unsigned attr)
*/
flagAttribute(attr);
- switch(attr)
- {
- case ATTR_STR:
- recalculateBaseAttribute(ATTR_INV_CAPACITY);
- break;
- case ATTR_AGI:
- recalculateBaseAttribute(ATTR_DODGE);
- recalculateBaseAttribute(ATTR_MOVE_SPEED_TPS);
- break;
- case ATTR_VIT:
- recalculateBaseAttribute(ATTR_MAX_HP);
- recalculateBaseAttribute(ATTR_HP_REGEN);
- recalculateBaseAttribute(ATTR_DEFENSE);
- break;
- case ATTR_INT:
- // TODO
- break;
- case ATTR_DEX:
- recalculateBaseAttribute(ATTR_ACCURACY);
- break;
- case ATTR_WIL:
- // TODO
- break;
- default:
- Being::updateDerivedAttributes(attr);
- }
+
+ Being::updateDerivedAttributes(attr);
}
void Character::flagAttribute(int attr)
diff --git a/src/game-server/character.h b/src/game-server/character.h
index d225081..9c9a545 100644
--- a/src/game-server/character.h
+++ b/src/game-server/character.h
@@ -251,11 +251,11 @@ class Character : public Being
void modifiedAllAttribute();
/**
- * Recalculate the base value of an attribute and update derived
- * attributes if it has changed.
- * @returns Whether it was changed.
- */
- bool recalculateBaseAttribute(unsigned);
+ * Recalculate the base value of an attribute and update derived
+ * attributes if it has changed.
+ */
+ void recalculateBaseAttribute(unsigned);
+
/**
* Attribute has changed, recalculate base value of dependant
diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp
index 9f30840..7d5ec76 100644
--- a/src/game-server/monster.cpp
+++ b/src/game-server/monster.cpp
@@ -488,44 +488,3 @@ void Monster::died()
}
}
}
-
-bool Monster::recalculateBaseAttribute(unsigned attr)
-{
- LOG_DEBUG("Monster: Received update attribute recalculation request for "
- << attr << ".");
- if (!mAttributes.count(attr))
- {
- LOG_DEBUG("Monster::recalculateBaseAttribute: "
- << attr << " not found!");
- return false;
- }
- double newBase = getAttribute(attr);
-
- switch (attr)
- {
- // Those a set only at load time.
- case ATTR_MAX_HP:
- case ATTR_DODGE:
- case ATTR_MAGIC_DODGE:
- case ATTR_ACCURACY:
- case ATTR_DEFENSE:
- case ATTR_MAGIC_DEFENSE:
- case ATTR_HP_REGEN:
- case ATTR_MOVE_SPEED_TPS:
- case ATTR_INV_CAPACITY:
- // nothing to do.
- break;
-
- // Only HP and Speed Raw updated for monsters
- default:
- Being::recalculateBaseAttribute(attr);
- break;
- }
- if (newBase != getAttribute(attr))
- {
- setAttribute(attr, newBase);
- return true;
- }
- LOG_DEBUG("Monster: No changes to sync for attribute '" << attr << "'.");
- return false;
-}
diff --git a/src/game-server/monster.h b/src/game-server/monster.h
index 3313345..93c9f4e 100644
--- a/src/game-server/monster.h
+++ b/src/game-server/monster.h
@@ -329,14 +329,6 @@ class Monster : public Being
*/
void forgetTarget(Entity *entity);
- /**
- * 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);
-
protected:
/**
* Returns the way the actor blocks pathfinding for other objects.
diff --git a/src/scripting/lua.cpp b/src/scripting/lua.cpp
index 880216d..4e2cd28 100644
--- a/src/scripting/lua.cpp
+++ b/src/scripting/lua.cpp
@@ -69,6 +69,30 @@ extern "C" {
/**
+ * on_update_derived_attribute( function(Being*) ): void
+ * Sets a listener function to handle
+ * recalculation of derived attributes event.
+ */
+static int on_update_derived_attribute(lua_State *s)
+{
+ luaL_checktype(s, 1, LUA_TFUNCTION);
+ Being::setUpdateDerivedAttributesCallback(getScript(s));
+ return 0;
+}
+
+
+/**
+ * on_recalculateBaseAttributeCallback( function(Being*) ): void
+ * Sets a listener function to the attribute recalculation event.
+ */
+static int on_recalculate_base_attribute(lua_State *s)
+{
+ luaL_checktype(s, 1, LUA_TFUNCTION);
+ Being::setRecalculateBaseAttributeCallback(getScript(s));
+ return 0;
+}
+
+/**
* on_character_death( function(Character*) ): void
* Sets a listener function to the character death event.
*/
@@ -2582,6 +2606,8 @@ LuaScript::LuaScript():
// Put the callback functions in the scripting environment.
static luaL_Reg const callbacks[] = {
+ { "on_update_derived_attribute", &on_update_derived_attribute },
+ { "on_recalculate_base_attribute", &on_recalculate_base_attribute },
{ "on_character_death", &on_character_death },
{ "on_character_death_accept", &on_character_death_accept },
{ "on_character_login", &on_character_login },