Add Remove Buff Behavior and patch infinite use Imagination Backpack(#845)

Testing does not reveal any issues with existing buff removals sending this GM as well and may fix more bugs that were unknown, or cause more.
This commit is contained in:
David Markowitz 2022-11-27 16:40:14 -08:00 committed by GitHub
parent 1556f580d6
commit 3939f19b08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 71 additions and 3 deletions

View File

@ -537,6 +537,7 @@ enum GAME_MSG : unsigned short {
GAME_MSG_REMOVE_RUN_SPEED_MODIFIER = 1506,
GAME_MSG_UPDATE_PROPERTY_PERFORMANCE_COST = 1547,
GAME_MSG_PROPERTY_ENTRANCE_BEGIN = 1553,
GAME_MSG_REMOVE_BUFF = 1648,
GAME_MSG_REQUEST_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1666,
GAME_MSG_RESPONSE_MOVE_ITEM_BETWEEN_INVENTORY_TYPES = 1667,
GAME_MSG_PLAYER_SET_CAMERA_CYCLING_MODE = 1676,

View File

@ -42,6 +42,7 @@
#include "SkillCastFailedBehavior.h"
#include "SpawnBehavior.h"
#include "ForceMovementBehavior.h"
#include "RemoveBuffBehavior.h"
#include "ImmunityBehavior.h"
#include "InterruptBehavior.h"
#include "PlayEffectBehavior.h"
@ -226,7 +227,9 @@ Behavior* Behavior::CreateBehavior(const uint32_t behaviorId) {
break;
case BehaviorTemplates::BEHAVIOR_ALTER_CHAIN_DELAY: break;
case BehaviorTemplates::BEHAVIOR_CAMERA: break;
case BehaviorTemplates::BEHAVIOR_REMOVE_BUFF: break;
case BehaviorTemplates::BEHAVIOR_REMOVE_BUFF:
behavior = new RemoveBuffBehavior(behaviorId);
break;
case BehaviorTemplates::BEHAVIOR_GRAB: break;
case BehaviorTemplates::BEHAVIOR_MODULAR_BUILD: break;
case BehaviorTemplates::BEHAVIOR_NPC_COMBAT_SKILL:

View File

@ -34,6 +34,7 @@ set(DGAME_DBEHAVIORS_SOURCES "AirMovementBehavior.cpp"
"PlayEffectBehavior.cpp"
"ProjectileAttackBehavior.cpp"
"PullToPointBehavior.cpp"
"RemoveBuffBehavior.cpp"
"RepairBehavior.cpp"
"SkillCastFailedBehavior.cpp"
"SkillEventBehavior.cpp"

View File

@ -0,0 +1,21 @@
#include "RemoveBuffBehavior.h"
#include "BehaviorBranchContext.h"
#include "BehaviorContext.h"
#include "EntityManager.h"
#include "BuffComponent.h"
void RemoveBuffBehavior::Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) {
auto* entity = EntityManager::Instance()->GetEntity(context->caster);
if (!entity) return;
auto* buffComponent = entity->GetComponent<BuffComponent>();
if (!buffComponent) return;
buffComponent->RemoveBuff(m_BuffId, false, m_RemoveImmunity);
}
void RemoveBuffBehavior::Load() {
this->m_RemoveImmunity = GetBoolean("remove_immunity");
this->m_BuffId = GetInt("buff_id");
}

View File

@ -0,0 +1,22 @@
#pragma once
#include "Behavior.h"
class RemoveBuffBehavior final : public Behavior
{
public:
/*
* Inherited
*/
explicit RemoveBuffBehavior(const uint32_t behaviorId) : Behavior(behaviorId) {
}
void Handle(BehaviorContext* context, RakNet::BitStream* bitStream, BehaviorBranchContext branch) override;
void Load() override;
private:
bool m_RemoveImmunity;
uint32_t m_BuffId;
};

View File

@ -123,13 +123,15 @@ void BuffComponent::ApplyBuff(const int32_t id, const float duration, const LWOO
m_Buffs.emplace(id, buff);
}
void BuffComponent::RemoveBuff(int32_t id) {
void BuffComponent::RemoveBuff(int32_t id, bool fromUnEquip, bool removeImmunity) {
const auto& iter = m_Buffs.find(id);
if (iter == m_Buffs.end()) {
return;
}
GameMessages::SendRemoveBuff(m_Parent, fromUnEquip, removeImmunity, id);
m_Buffs.erase(iter);
RemoveBuffEffect(id);

View File

@ -78,8 +78,9 @@ public:
/**
* Removes a buff from the parent entity, reversing its effects
* @param id the id of the buff to remove
* @param removeImmunity whether or not to remove immunity on removing the buff
*/
void RemoveBuff(int32_t id);
void RemoveBuff(int32_t id, bool fromUnEquip = false, bool removeImmunity = false);
/**
* Returns whether or not the entity has a buff identified by `id`

View File

@ -986,6 +986,7 @@ void InventoryComponent::ApplyBuff(Item* item) const {
}
}
// TODO Something needs to send the remove buff GameMessage as well when it is unequipping items that would remove buffs.
void InventoryComponent::RemoveBuff(Item* item) const {
const auto buffs = FindBuffs(item, false);

View File

@ -3476,6 +3476,20 @@ void GameMessages::SendPlayEmote(LWOOBJID objectId, int32_t emoteID, LWOOBJID ta
SEND_PACKET;
}
void GameMessages::SendRemoveBuff(Entity* entity, bool fromUnEquip, bool removeImmunity, uint32_t buffId) {
CBITSTREAM;
CMSGHEADER;
bitStream.Write(entity->GetObjectID());
bitStream.Write(GAME_MSG::GAME_MSG_REMOVE_BUFF);
bitStream.Write(false); // bFromRemoveBehavior but setting this to true makes the GM not do anything on the client?
bitStream.Write(fromUnEquip);
bitStream.Write(removeImmunity);
bitStream.Write(buffId);
SEND_PACKET_BROADCAST;
}
void GameMessages::SendBouncerActiveStatus(LWOOBJID objectId, bool bActive, const SystemAddress& sysAddr) {
CBITSTREAM;

View File

@ -566,6 +566,8 @@ namespace GameMessages {
void HandleReportBug(RakNet::BitStream* inStream, Entity* entity);
void SendRemoveBuff(Entity* entity, bool fromUnEquip, bool removeImmunity, uint32_t buffId);
/* Message to synchronize a skill cast */
class EchoSyncSkill {
static const GAME_MSG MsgID = GAME_MSG_ECHO_SYNC_SKILL;