From 54de212214a9cfe8aaa52365daede58b3d8f1deb Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Thu, 30 Jun 2016 17:50:31 -0400 Subject: [PATCH] Implement OP_CancelSneakHide Didn't test every client, but they should all work --- common/emu_oplist.h | 1 + utils/patches/patch_RoF.conf | 1 + utils/patches/patch_RoF2.conf | 1 + utils/patches/patch_SoD.conf | 1 + utils/patches/patch_SoF.conf | 1 + utils/patches/patch_Titanium.conf | 1 + utils/patches/patch_UF.conf | 1 + zone/client.h | 1 + zone/client_packet.cpp | 8 ++++++++ zone/client_process.cpp | 15 +++++++++++++++ zone/mob.cpp | 10 +++++++--- zone/mob.h | 1 + 12 files changed, 39 insertions(+), 3 deletions(-) diff --git a/common/emu_oplist.h b/common/emu_oplist.h index 936595afa..8b913095b 100644 --- a/common/emu_oplist.h +++ b/common/emu_oplist.h @@ -64,6 +64,7 @@ N(OP_BuffRemoveRequest), N(OP_Bug), N(OP_CameraEffect), N(OP_Camp), +N(OP_CancelSneakHide), N(OP_CancelTask), N(OP_CancelTrade), N(OP_CastSpell), diff --git a/utils/patches/patch_RoF.conf b/utils/patches/patch_RoF.conf index 466043c39..00682d57f 100644 --- a/utils/patches/patch_RoF.conf +++ b/utils/patches/patch_RoF.conf @@ -357,6 +357,7 @@ OP_Weblink=0x7cce OP_OpenContainer=0x654f OP_Marquee=0x288a OP_Fling=0x6b8e +OP_CancelSneakHide=0x265f OP_DzQuit=0x5fc8 OP_DzListTimers=0x67b9 diff --git a/utils/patches/patch_RoF2.conf b/utils/patches/patch_RoF2.conf index 8582ab503..9237a0238 100644 --- a/utils/patches/patch_RoF2.conf +++ b/utils/patches/patch_RoF2.conf @@ -358,6 +358,7 @@ OP_ItemRecastDelay=0x15a9 #OP_OpenInventory=0x0000 # Likely does not exist in RoF -U OP_ResetAA=0x1669 OP_Fling=0x6f80 +OP_CancelSneakHide=0x0927 # Expeditions OP_DzAddPlayer=0x4701 diff --git a/utils/patches/patch_SoD.conf b/utils/patches/patch_SoD.conf index 1c362111b..4944b0ef3 100644 --- a/utils/patches/patch_SoD.conf +++ b/utils/patches/patch_SoD.conf @@ -352,6 +352,7 @@ OP_OpenInventory=0x1003 OP_OpenContainer=0x3278 OP_Marquee=0x7dc9 OP_Fling=0x2b88 +OP_CancelSneakHide=0x7705 # Expedition OP_DzQuit=0x054e diff --git a/utils/patches/patch_SoF.conf b/utils/patches/patch_SoF.conf index 9c58b5684..113038e49 100644 --- a/utils/patches/patch_SoF.conf +++ b/utils/patches/patch_SoF.conf @@ -334,6 +334,7 @@ OP_OpenInventory=0x66c8 OP_OpenContainer=0x10e3 OP_Marquee=0x2f75 OP_Untargetable=0x3e36 +OP_CancelSneakHide=0x5335 #expedition OP_DzQuit=0x20d6 diff --git a/utils/patches/patch_Titanium.conf b/utils/patches/patch_Titanium.conf index 99ef322a0..a48de92b5 100644 --- a/utils/patches/patch_Titanium.conf +++ b/utils/patches/patch_Titanium.conf @@ -286,6 +286,7 @@ OP_RemoveNimbusEffect=0x0000 OP_CrystalReclaim=0x7cfe OP_CrystalCreate=0x62c3 OP_Marquee=0x1d4d +OP_CancelSneakHide=0x48C2 OP_DzQuit=0x486d OP_DzListTimers=0x39aa diff --git a/utils/patches/patch_UF.conf b/utils/patches/patch_UF.conf index cb7d11851..4b650176f 100644 --- a/utils/patches/patch_UF.conf +++ b/utils/patches/patch_UF.conf @@ -362,6 +362,7 @@ OP_InspectMessageUpdate=0x7fa1 # C OP_OpenContainer=0x041a OP_Marquee=0x3675 OP_Fling=0x51b1 +OP_CancelSneakHide=0x7686 OP_DzQuit=0x1539 OP_DzListTimers=0x21e9 diff --git a/zone/client.h b/zone/client.h index b3965b031..9bd22f815 100644 --- a/zone/client.h +++ b/zone/client.h @@ -834,6 +834,7 @@ public: eqFilterMode GetFilter(eqFilterType filter_id) const { return ClientFilters[filter_id]; } void SetFilter(eqFilterType filter_id, eqFilterMode value) { ClientFilters[filter_id]=value; } + void CancelSneakHide(); void BreakInvis(); void BreakSneakWhenCastOn(Mob* caster, bool IsResisted); void BreakFeignDeathWhenCastOn(bool IsResisted); diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index fc376c64e..2dfaec3b9 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -7871,6 +7871,14 @@ void Client::Handle_OP_Heartbeat(const EQApplicationPacket *app) void Client::Handle_OP_Hide(const EQApplicationPacket *app) { + // newer client respond to OP_CancelSneakHide with OP_Hide with a size of 4 and 0 data + if (app->size == 4) { + auto data = app->ReadUInt32(0); + if (data) + Log.Out(Logs::Detail, Logs::None, "Got OP_Hide with unexpected data %d", data); + return; + } + if (!HasSkill(EQEmu::skills::SkillHide) && GetSkill(EQEmu::skills::SkillHide) == 0) { //Can not be able to train hide but still have it from racial though diff --git a/zone/client_process.cpp b/zone/client_process.cpp index f61b475bc..ecab035b6 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -1127,6 +1127,21 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app) Save(); } +void Client::CancelSneakHide() +{ + if (hidden || improved_hidden) { + auto app = new EQApplicationPacket(OP_CancelSneakHide, 0); + FastQueuePacket(&app); + // SoF and Tit send back a OP_SpawnAppearance turning off AT_Invis + // so we need to handle our sneaking flag only + // The later clients send back a OP_Hide (this has a size but data is 0) + // as well as OP_SpawnAppearance with AT_Invis and one with AT_Sneak + // So we don't have to handle any of those flags + if (ClientVersionBit() & EQEmu::versions::bit_SoFAndEarlier) + sneaking = false; + } +} + void Client::BreakInvis() { if (invisible) diff --git a/zone/mob.cpp b/zone/mob.cpp index a4aa4e15a..b2dd61687 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -5854,10 +5854,8 @@ int Mob::CheckBaneDamage(const ItemInst *item) return damage; } -void Mob::CommonBreakInvisible() +void Mob::CancelSneakHide() { - BreakInvisibleSpells(); - if (hidden || improved_hidden) { hidden = false; improved_hidden = false; @@ -5871,6 +5869,12 @@ void Mob::CommonBreakInvisible() } } +void Mob::CommonBreakInvisible() +{ + BreakInvisibleSpells(); + CancelSneakHide(); +} + #ifdef BOTS bool Mob::JoinHealRotationTargetPool(std::shared_ptr* heal_rotation) { diff --git a/zone/mob.h b/zone/mob.h index 3608efa9c..841e3a24e 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -173,6 +173,7 @@ public: void RogueEvade(Mob *other); void CommonOutgoingHitSuccess(Mob* defender, int32 &damage, EQEmu::skills::SkillType skillInUse, ExtraAttackOptions *opts = nullptr); void BreakInvisibleSpells(); + virtual void CancelSneakHide(); void CommonBreakInvisible(); void CommonBreakInvisibleFromCombat(); bool HasDied();