diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 4 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Handlers/LootHandler.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Spells/Spell.cpp | 6 | ||||
-rw-r--r-- | src/server/game/Spells/SpellEffects.cpp | 17 |
6 files changed, 35 insertions, 8 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 1823c7c96c2..71143c3c7eb 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -142,7 +142,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) } Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(), -lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLowGUID(0), +lootForPickPocketed(false), lootForBody(false), lootForSkinned(false), _skinner(0), m_groupLootTimer(0), lootingGroupLowGUID(0), m_PlayerDamageReq(0), m_lootRecipient(0), m_lootRecipientGroup(0), m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 9cc08e3b71d..069308c9e84 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -553,6 +553,9 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject Loot loot; bool lootForPickPocketed; bool lootForBody; + bool lootForSkinned; + void SetSkinner(uint64 guid) { _skinner = guid; } + uint64 GetSkinner() const { return _skinner; } // Returns the player who skinned this creature Player* GetLootRecipient() const; Group* GetLootRecipientGroup() const; bool hasLootRecipient() const { return m_lootRecipient || m_lootRecipientGroup; } @@ -688,6 +691,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject uint64 m_lootRecipient; uint32 m_lootRecipientGroup; + uint64 _skinner; /// Timers time_t m_corpseRemoveTime; // (msecs)timer for death or corpse disappearance diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 6548b2dffde..b28d20c937c 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -9020,8 +9020,12 @@ void Player::SendLoot(uint64 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->GetCreatureTemplate()->SkinLootId, LootTemplates_Skinning, this, true); + if (!creature->lootForSkinned) + { + creature->lootForSkinned = true; + loot->clear(); + loot->FillLoot(creature->GetCreatureTemplate()->SkinLootId, LootTemplates_Skinning, this, true); + } permission = OWNER_PERMISSION; } // set group rights only for loot_type != LOOT_SKINNING diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 61f0b9afce2..2464a5385a4 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -355,11 +355,15 @@ void WorldSession::DoLootRelease(uint64 lguid) loot = &creature->loot; if (loot->isLooted()) { + creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + + if (loot->loot_type == LOOT_SKINNING) + creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); + // skip pickpocketing loot for speed, skinning timer reduction is no-op in fact if (!creature->IsAlive()) creature->AllLootRemovedFromCorpse(); - creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); loot->clear(); } else diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 48c2a76578d..f9a5e742f9f 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -5058,11 +5058,13 @@ SpellCastResult Spell::CheckCast(bool strict) return SPELL_FAILED_TARGET_UNSKINNABLE; Creature* creature = m_targets.GetUnitTarget()->ToCreature(); - if (creature->GetCreatureType() != CREATURE_TYPE_CRITTER && !creature->loot.isLooted()) + if (creature->GetCreatureType() != CREATURE_TYPE_CRITTER && creature->loot.loot_type != LOOT_SKINNING && !creature->loot.isLooted()) return SPELL_FAILED_TARGET_NOT_LOOTED; uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill(); + bool alreadySkinned = creature->loot.loot_type == LOOT_SKINNING && creature->GetSkinner() == m_caster->GetGUID(); + int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill); int32 TargetLevel = m_targets.GetUnitTarget()->getLevel(); int32 ReqValue = (skillValue < 100 ? (TargetLevel-10) * 10 : TargetLevel * 5); @@ -5072,7 +5074,7 @@ SpellCastResult Spell::CheckCast(bool strict) // chance for fail at orange skinning attempt if ((m_selfContainer && (*m_selfContainer) == this) && skillValue < sWorld->GetConfigMaxSkillValue() && - (ReqValue < 0 ? 0 : ReqValue) > irand(skillValue - 25, skillValue + 37)) + (ReqValue < 0 ? 0 : ReqValue) > irand(skillValue - 25, skillValue + 37) && !alreadySkinned) return SPELL_FAILED_TRY_AGAIN; break; diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 9cf0e1ae45c..0a43c5a2c45 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -4702,15 +4702,28 @@ void Spell::EffectSkinning(SpellEffIndex /*effIndex*/) uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill(); + bool awardPoints = true; + + // Check if a skinning loot table was already generated for this creature + if (creature->loot.loot_type == LOOT_SKINNING) + { + if (creature->GetSkinner() != m_caster->GetGUID()) + return; + + awardPoints = false; // Do not grant skill points for this loot, they were already granted the first time. + } + else + creature->SetSkinner(m_caster->GetGUID()); + m_caster->ToPlayer()->SendLoot(creature->GetGUID(), LOOT_SKINNING); - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel-10)*10 : targetLevel*5; int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill); // Double chances for elites - m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1); + if (awardPoints) + m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1); } void Spell::EffectCharge(SpellEffIndex /*effIndex*/) |