diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game-server/being.cpp | 84 | ||||
-rw-r--r-- | src/game-server/being.h | 14 | ||||
-rw-r--r-- | src/game-server/character.cpp | 89 | ||||
-rw-r--r-- | src/game-server/character.h | 10 | ||||
-rw-r--r-- | src/game-server/monster.cpp | 41 | ||||
-rw-r--r-- | src/game-server/monster.h | 8 | ||||
-rw-r--r-- | src/scripting/lua.cpp | 26 |
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 }, |