From d4f1b510aef9070f225b1dde72a1a5b1de1c86a5 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Wed, 19 May 2010 14:40:20 +0400 Subject: [PATCH] [9934] Skinning related fixes * Show skinning tooltip only after creature loot (when creature can be explcitly skinned). * Allow reopen skinning loot if still have not looted items. --- src/game/Creature.cpp | 37 +++++++++++++++++++++++++++++++++---- src/game/Creature.h | 2 ++ src/game/LootHandler.cpp | 7 +++---- src/game/Player.cpp | 12 ++++++++++-- src/game/Spell.cpp | 2 +- src/game/Unit.cpp | 9 ++------- src/shared/revision_nr.h | 2 +- 7 files changed, 52 insertions(+), 19 deletions(-) diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 14d473e50..a8dba28db 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -370,6 +370,7 @@ void Creature::Update(uint32 diff) m_respawnTime = 0; lootForPickPocketed = false; lootForBody = false; + lootForSkin = false; if(m_originalEntry != GetEntry()) UpdateEntry(m_originalEntry); @@ -810,6 +811,38 @@ void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, Splin SendMonsterMove(x, y, z, type, flags, time); } +void Creature::PrepareBodyLootState() +{ + loot.clear(); + + // if have normal loot then prepare it access + if (!isAlive() && GetCreatureInfo()->lootid && !lootForBody) + { + SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + return; + } + + // if not have normal loot allow skinning if need + if (!isAlive() && !lootForSkin) + { + lootForBody = true; // pass this loot mode + + if (GetCreatureInfo()->SkinLootId) + { + if (LootTemplates_Skinning.HaveLootFor(GetCreatureInfo()->SkinLootId)) + { + RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); + return; + } + } + } + + RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); +} + + /** * Return original player who tap creature, it can be different from player/group allowed to loot so not use it for loot code */ @@ -1330,10 +1363,6 @@ void Creature::setDeathState(DeathState s) SetTargetGUID(0); // remove target selection in any cases (can be set at aura remove in Unit::setDeathState) SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); - if (!isPet() && GetCreatureInfo()->SkinLootId) - if (LootTemplates_Skinning.HaveLootFor(GetCreatureInfo()->SkinLootId)) - SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); - if (canFly() && FallGround()) return; diff --git a/src/game/Creature.h b/src/game/Creature.h index 6369a58bf..3bb0591de 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -531,7 +531,9 @@ class MANGOS_DLL_SPEC Creature : public Unit Loot loot; bool lootForPickPocketed; bool lootForBody; + bool lootForSkin; + void PrepareBodyLootState(); ObjectGuid GetLootRecipientGuid() const { return m_lootRecipientGuid; } uint32 GetLootGroupRecipientId() const { return m_lootGroupRecipientId; } Player* GetLootRecipient() const; // use group cases as prefered diff --git a/src/game/LootHandler.cpp b/src/game/LootHandler.cpp index 1f494841f..61fded607 100644 --- a/src/game/LootHandler.cpp +++ b/src/game/LootHandler.cpp @@ -442,12 +442,11 @@ void WorldSession::DoLootRelease(ObjectGuid lguid) if (loot->isLooted()) { - // skip pickpocketing loot for speed, skinning timer redunction is no-op in fact + // for example skinning after normal loot + pCreature->PrepareBodyLootState(); + if(!pCreature->isAlive()) pCreature->AllLootRemovedFromCorpse(); - - pCreature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); - loot->clear(); } break; } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 724dd5e34..1776d1953 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -7886,8 +7886,16 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type) // possible only if creature->lootForBody && loot->empty() at spell cast check if (loot_type == LOOT_SKINNING) { - loot->clear(); - loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, this, false); + if (!creature->lootForSkin) + { + creature->lootForSkin = true; + loot->clear(); + loot->FillLoot(creature->GetCreatureInfo()->SkinLootId, LootTemplates_Skinning, this, false); + + // let reopen skinning loot if will closed. + if (!loot->empty()) + creature->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + } } // set group rights only for loot_type != LOOT_SKINNING else diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 6160a6acd..9c8716e1e 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -4805,7 +4805,7 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_TARGET_UNSKINNABLE; Creature* creature = (Creature*)m_targets.getUnitTarget(); - if ( creature->GetCreatureType() != CREATURE_TYPE_CRITTER && ( !creature->lootForBody || !creature->loot.empty() ) ) + if ( creature->GetCreatureType() != CREATURE_TYPE_CRITTER && ( !creature->lootForBody || creature->lootForSkin || !creature->loot.empty() ) ) { return SPELL_FAILED_TARGET_NOT_LOOTED; } diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 812e22013..55817ca8a 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -566,9 +566,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa pVictim->SetHealth(0); // allow loot only if has loot_id in creature_template - CreatureInfo const* cInfo = ((Creature*)pVictim)->GetCreatureInfo(); - if(cInfo && cInfo->lootid) - pVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + ((Creature*)pVictim)->PrepareBodyLootState(); // some critters required for quests (need normal entry instead possible heroic in any cases) if(GetTypeId() == TYPEID_PLAYER) @@ -809,10 +807,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa { cVictim->DeleteThreatList(); // only lootable if it has loot or can drop gold - if(cVictim->GetCreatureInfo()->lootid || cVictim->GetCreatureInfo()->maxgold > 0) - cVictim->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); - else - cVictim->lootForBody = true; // needed for skinning + cVictim->PrepareBodyLootState(); } // Call creature just died function if (cVictim->AI()) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 622ba1f05..81e745922 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9933" + #define REVISION_NR "9934" #endif // __REVISION_NR_H__