Core/Skinning: Fixed the creatures becoming non-skinnable even before looting them completely.
Closes #5318
This commit is contained in:
1 parent
cac491bef8
commit
a0fedd1d78
6 files changed
+35
-8
No files matched your search
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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*/)
|
||||
|
||||
Reference in new issue
Block a user