From 4d6abb9b40ee1b0a4642a208f314b4dbb41bbac8 Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Wed, 24 Apr 2013 15:42:23 +0200 Subject: [Abilities] Inform other players about ability uses --- src/common/manaserv_protocol.h | 2 ++ src/game-server/abilitycomponent.cpp | 22 ++++++++++++++++++++-- src/game-server/abilitycomponent.h | 27 +++++++++++++++++++++++++++ src/game-server/actor.h | 6 ++++-- src/game-server/state.cpp | 24 ++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/common/manaserv_protocol.h b/src/common/manaserv_protocol.h index 498e35f..73837b1 100644 --- a/src/common/manaserv_protocol.h +++ b/src/common/manaserv_protocol.h @@ -143,6 +143,8 @@ enum { GPMSG_BEING_HEALTH_CHANGE = 0x0274, // W being id, W hp, W max hp GPMSG_BEINGS_MOVE = 0x0280, // { W being id, B flags [, [W*2 position,] W*2 destination, B speed] }* GPMSG_ITEMS = 0x0281, // { W item id, W*2 position }* + GPMSG_BEING_ABILITY_POINT = 0x0282, // W being id, B abilityId, W*2 point + GPMSG_BEING_ABILITY_BEING = 0x0283, // W being id, B abilityId, W target being id PGMSG_ATTACK = 0x0290, // W being id GPMSG_BEING_ATTACK = 0x0291, // W being id, B direction, B attack Id PGMSG_USE_ABILITY_ON_BEING = 0x0292, // B abilityID, W being id diff --git a/src/game-server/abilitycomponent.cpp b/src/game-server/abilitycomponent.cpp index 5b27be1..60c9b86 100644 --- a/src/game-server/abilitycomponent.cpp +++ b/src/game-server/abilitycomponent.cpp @@ -27,7 +27,9 @@ #include "utils/logger.h" -AbilityComponent::AbilityComponent(Entity &entity) +AbilityComponent::AbilityComponent(Entity &entity): + mLastUsedAbilityId(0), + mLastTargetBeingId(0) { entity.getComponent()->signal_attribute_changed.connect( sigc::mem_fun(this, &AbilityComponent::attributeChanged)); @@ -136,6 +138,14 @@ void AbilityComponent::useAbilityOnBeing(Entity &user, int id, Entity *b) script->push(b); script->push(ability.abilityInfo->id); script->execute(user.getMap()); + + mLastUsedAbilityId = id; + if (b) + mLastTargetBeingId = b->getComponent()->getPublicID(); + else + mLastTargetBeingId = 0; + user.getComponent()->raiseUpdateFlags( + UPDATEFLAG_ABILITY_ON_BEING); } /** @@ -166,6 +176,11 @@ void AbilityComponent::useAbilityOnPoint(Entity &user, int id, int x, int y) script->push(y); script->push(ability.abilityInfo->id); script->execute(user.getMap()); + + mLastUsedAbilityId = id; + mLastTargetPoint = Point(x, y); + user.getComponent()->raiseUpdateFlags( + UPDATEFLAG_ABILITY_ON_POINT); } /** @@ -211,7 +226,10 @@ void AbilityComponent::startCooldown( { unsigned cooldownAttribute = abilityInfo->cooldownAttribute; auto *bc = entity.getComponent(); - mCooldown.set((int)bc->getModifiedAttribute(cooldownAttribute)); + int cooldown = (int)bc->getModifiedAttribute(cooldownAttribute); + // Enforce a minimum cooldown of 1 tick to prevent syncing issues + cooldown = std::max(cooldown, 1); + mCooldown.set(cooldown); signal_cooldown_activated.emit(); } diff --git a/src/game-server/abilitycomponent.h b/src/game-server/abilitycomponent.h index c44dcb7..def3e00 100644 --- a/src/game-server/abilitycomponent.h +++ b/src/game-server/abilitycomponent.h @@ -25,6 +25,8 @@ #include "game-server/component.h" #include "game-server/timeout.h" +#include "utils/point.h" + #include struct AbilityValue @@ -73,6 +75,11 @@ public: sigc::signal signal_ability_changed; sigc::signal signal_ability_took; sigc::signal signal_cooldown_activated; + + // For informing clients + int getLastUsedAbilityId() const; + const Point &getLastTargetPoint() const; + int getLastTargetBeingId() const; private: bool abilityUseCheck(AbilityMap::iterator it); void attributeChanged(Entity *entity, unsigned attr); @@ -80,6 +87,11 @@ private: Timeout mCooldown; AbilityMap mAbilities; + + // Variables required for informing clients + int mLastUsedAbilityId; + Point mLastTargetPoint; + int mLastTargetBeingId; }; @@ -117,4 +129,19 @@ inline int AbilityComponent::remainingCooldown() const return mCooldown.remaining(); } +inline int AbilityComponent::getLastUsedAbilityId() const +{ + return mLastUsedAbilityId; +} + +inline const Point &AbilityComponent::getLastTargetPoint() const +{ + return mLastTargetPoint; +} + +inline int AbilityComponent::getLastTargetBeingId() const +{ + return mLastTargetBeingId; +} + #endif /* ABILITYCOMPONENT_H_ */ diff --git a/src/game-server/actor.h b/src/game-server/actor.h index 2950d51..d1201aa 100644 --- a/src/game-server/actor.h +++ b/src/game-server/actor.h @@ -38,7 +38,9 @@ enum UPDATEFLAG_LOOKSCHANGE = 16, UPDATEFLAG_DIRCHANGE = 32, UPDATEFLAG_HEALTHCHANGE = 64, - UPDATEFLAG_EMOTE = 128 + UPDATEFLAG_EMOTE = 128, + UPDATEFLAG_ABILITY_ON_POINT = 256, + UPDATEFLAG_ABILITY_ON_BEING = 512 }; /** @@ -143,7 +145,7 @@ class ActorComponent : public Component unsigned short mMoveTime; private: - char mUpdateFlags; /**< Changes in actor status. */ + int mUpdateFlags; /**< Changes in actor status. */ /** Actor ID sent to clients (unique with respect to the map). */ unsigned short mPublicID; diff --git a/src/game-server/state.cpp b/src/game-server/state.cpp index 0b97ec0..6efeb14 100644 --- a/src/game-server/state.cpp +++ b/src/game-server/state.cpp @@ -228,6 +228,30 @@ static void informPlayer(MapComposite *map, Entity *p) gameHandler->sendTo(p, DirMsg); } + // Send ability uses + if (oflags & UPDATEFLAG_ABILITY_ON_POINT) + { + MessageOut abilityMsg(GPMSG_BEING_ABILITY_POINT); + abilityMsg.writeInt16(oid); + auto *abilityComponent = o->getComponent(); + const Point &point = abilityComponent->getLastTargetPoint(); + abilityMsg.writeInt8(abilityComponent->getLastUsedAbilityId()); + abilityMsg.writeInt16(point.x); + abilityMsg.writeInt16(point.y); + gameHandler->sendTo(p, abilityMsg); + } + + if (oflags & UPDATEFLAG_ABILITY_ON_BEING) + { + MessageOut abilityMsg(GPMSG_BEING_ABILITY_POINT); + abilityMsg.writeInt16(oid); + auto *abilityComponent = o->getComponent(); + abilityMsg.writeInt8(abilityComponent->getLastUsedAbilityId()); + abilityMsg.writeInt16( + abilityComponent->getLastTargetBeingId()); + gameHandler->sendTo(p, abilityMsg); + } + // Send damage messages. if (o->canFight()) { -- cgit