Core/Misc: Fixed player corpse looting, added player corpse loot and some more
Port From (https://github.com/TrinityCore/TrinityCore/commit/89f728cd5b6ae3041fdae3c853ac4b0ac5f0a848)
This commit is contained in:
@@ -70,6 +70,7 @@ namespace Framework.Constants
|
||||
/// </summary>
|
||||
public const int MaxNRLootItems = 16;
|
||||
public const int MaxNRQuestItems = 32;
|
||||
public const int PlayerCorpseLootEntry = 1;
|
||||
|
||||
/// <summary>
|
||||
/// Movement Const
|
||||
|
||||
@@ -567,7 +567,11 @@ namespace Game.BattleFields
|
||||
return;
|
||||
|
||||
if (victim.IsTypeId(TypeId.Player))
|
||||
{
|
||||
HandlePromotion(killer, victim);
|
||||
// Allow to Skin non-released corpse
|
||||
victim.AddUnitFlag(UnitFlags.Skinnable);
|
||||
}
|
||||
|
||||
// @todo Recent PvP activity worldstate
|
||||
}
|
||||
|
||||
@@ -548,7 +548,7 @@ namespace Game.BattleFields
|
||||
public const uint Max = 7;
|
||||
}
|
||||
|
||||
struct WintergraspAreaIds
|
||||
public struct WintergraspAreaIds
|
||||
{
|
||||
public const uint WintergraspFortress = 4575;
|
||||
public const uint TheSunkenRing = 4538;
|
||||
|
||||
@@ -281,7 +281,6 @@ namespace Game.Entities
|
||||
|
||||
public Loot loot = new Loot();
|
||||
public Player lootRecipient;
|
||||
public bool lootForBody;
|
||||
|
||||
CorpseType m_type;
|
||||
long m_time;
|
||||
|
||||
@@ -93,7 +93,6 @@ namespace Game.Entities
|
||||
public ObjectGuid lootingGroupLowGUID; // used to find group which is looting corpse
|
||||
ObjectGuid m_lootRecipient;
|
||||
ObjectGuid m_lootRecipientGroup;
|
||||
ObjectGuid _skinner;
|
||||
}
|
||||
|
||||
public enum ObjectCellMoveState
|
||||
|
||||
@@ -940,8 +940,7 @@ namespace Game.Entities
|
||||
}
|
||||
public void ResetPickPocketRefillTimer() { _pickpocketLootRestore = 0; }
|
||||
public bool CanGeneratePickPocketLoot() { return _pickpocketLootRestore <= Time.UnixTime; }
|
||||
public void SetSkinner(ObjectGuid guid) { _skinner = guid; }
|
||||
public ObjectGuid GetSkinner() { return _skinner; } // Returns the player who skinned this creature
|
||||
public ObjectGuid GetLootRecipientGUID() { return m_lootRecipient; }
|
||||
|
||||
public Player GetLootRecipient()
|
||||
{
|
||||
@@ -958,7 +957,7 @@ namespace Game.Entities
|
||||
return Global.GroupMgr.GetGroupByGUID(m_lootRecipientGroup);
|
||||
}
|
||||
|
||||
public void SetLootRecipient(Unit unit)
|
||||
public void SetLootRecipient(Unit unit, bool withGroup = true)
|
||||
{
|
||||
// set the player whose group should receive the right
|
||||
// to loot the creature after it dies
|
||||
@@ -980,9 +979,14 @@ namespace Game.Entities
|
||||
return;
|
||||
|
||||
m_lootRecipient = player.GetGUID();
|
||||
Group group = player.GetGroup();
|
||||
if (group)
|
||||
m_lootRecipientGroup = group.GetGUID();
|
||||
if (withGroup)
|
||||
{
|
||||
Group group = player.GetGroup();
|
||||
if (group)
|
||||
m_lootRecipientGroup = group.GetGUID();
|
||||
}
|
||||
else
|
||||
m_lootRecipientGroup = ObjectGuid.Empty;
|
||||
|
||||
AddDynamicFlag(UnitDynFlags.Tapped);
|
||||
}
|
||||
|
||||
@@ -1015,6 +1015,19 @@ namespace Game.Entities
|
||||
GetMap().GetZoneAndAreaId(GetPhaseShift(), out zoneid, out areaid, posX, posY, posZ);
|
||||
}
|
||||
|
||||
public bool IsInWorldPvpZone()
|
||||
{
|
||||
switch (GetZoneId())
|
||||
{
|
||||
case 4197: // Wintergrasp
|
||||
case 5095: // Tol Barad
|
||||
case 6941: // Ashran
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public InstanceScript GetInstanceScript()
|
||||
{
|
||||
Map map = GetMap();
|
||||
|
||||
@@ -31,6 +31,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Game.BattleFields;
|
||||
|
||||
namespace Game.Entities
|
||||
{
|
||||
@@ -6164,7 +6165,8 @@ namespace Game.Entities
|
||||
/// <param name="looterPlr"></param>
|
||||
public void RemovedInsignia(Player looterPlr)
|
||||
{
|
||||
if (GetBattlegroundId() == 0)
|
||||
// If player is not in battleground and not in worldpvpzone
|
||||
if (GetBattlegroundId() == 0 && !IsInWorldPvpZone())
|
||||
return;
|
||||
|
||||
// If not released spirit, do it !
|
||||
@@ -6262,9 +6264,12 @@ namespace Game.Entities
|
||||
group.UpdateLooterGuid(go);
|
||||
}
|
||||
|
||||
GameObjectTemplateAddon addon = go.GetTemplateAddon();
|
||||
if (addon != null)
|
||||
loot.generateMoneyLoot(addon.mingold, addon.maxgold);
|
||||
if (go.GetLootMode() > 0)
|
||||
{
|
||||
GameObjectTemplateAddon addon = go.GetTemplateAddon();
|
||||
if (addon != null)
|
||||
loot.generateMoneyLoot(addon.mingold, addon.maxgold);
|
||||
}
|
||||
|
||||
if (loot_type == LootType.Fishing)
|
||||
go.getFishLoot(loot, this);
|
||||
@@ -6373,15 +6378,21 @@ namespace Game.Entities
|
||||
|
||||
loot = bones.loot;
|
||||
|
||||
if (!bones.lootForBody)
|
||||
if (loot.loot_type == LootType.None)
|
||||
{
|
||||
bones.lootForBody = true;
|
||||
uint pLevel = bones.loot.gold;
|
||||
bones.loot.clear();
|
||||
|
||||
// For AV Achievement
|
||||
Battleground bg = GetBattleground();
|
||||
if (bg)
|
||||
{
|
||||
if (bg.GetTypeID(true) == BattlegroundTypeId.AV)
|
||||
loot.FillLoot(1, LootStorage.Creature, this, true);
|
||||
loot.FillLoot(SharedConst.PlayerCorpseLootEntry, LootStorage.Creature, this, true);
|
||||
}
|
||||
else if (GetZoneId() == WintergraspAreaIds.Wintergrasp)
|
||||
loot.FillLoot(SharedConst.PlayerCorpseLootEntry, LootStorage.Creature, this, true);
|
||||
|
||||
// It may need a better formula
|
||||
// Now it works like this: lvl10: ~6copper, lvl70: ~9silver
|
||||
bones.loot.gold = (uint)(RandomHelper.URand(50, 150) * 0.016f * Math.Pow(pLevel / 5.76f, 2.5f) * WorldConfig.GetFloatValue(WorldCfg.RateDropMoney));
|
||||
@@ -6439,6 +6450,22 @@ namespace Game.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
// exploit fix
|
||||
if (!creature.HasDynamicFlag(UnitDynFlags.Lootable))
|
||||
{
|
||||
SendLootError(loot.GetGUID(), guid, LootError.DidntKill);
|
||||
return;
|
||||
}
|
||||
|
||||
// the player whose group may loot the corpse
|
||||
Player recipient = creature.GetLootRecipient();
|
||||
Group recipientGroup = creature.GetLootRecipientGroup();
|
||||
if (!recipient && !recipientGroup)
|
||||
{
|
||||
SendLootError(loot.GetGUID(), guid, LootError.DidntKill);
|
||||
return;
|
||||
}
|
||||
|
||||
if (loot.loot_type == LootType.None)
|
||||
{
|
||||
// for creature, loot is filled when creature is killed.
|
||||
@@ -6463,14 +6490,16 @@ namespace Game.Entities
|
||||
if (loot.loot_type == LootType.Skinning)
|
||||
{
|
||||
loot_type = LootType.Skinning;
|
||||
permission = creature.GetSkinner() == GetGUID() ? PermissionTypes.Owner : PermissionTypes.None;
|
||||
permission = creature.GetLootRecipientGUID() == GetGUID() ? PermissionTypes.Owner : PermissionTypes.None;
|
||||
}
|
||||
else if (loot_type == LootType.Skinning)
|
||||
{
|
||||
loot.clear();
|
||||
loot.FillLoot(creature.GetCreatureTemplate().SkinLootId, LootStorage.Skinning, this, true);
|
||||
creature.SetSkinner(GetGUID());
|
||||
permission = PermissionTypes.Owner;
|
||||
|
||||
// Set new loot recipient
|
||||
creature.SetLootRecipient(this, false);
|
||||
}
|
||||
// set group rights only for loot_type != LOOT_SKINNING
|
||||
else
|
||||
@@ -6554,12 +6583,12 @@ namespace Game.Entities
|
||||
// add 'this' player as one of the players that are looting 'loot'
|
||||
loot.AddLooter(GetGUID());
|
||||
m_AELootView[loot.GetGUID()] = guid;
|
||||
|
||||
if (loot_type == LootType.Corpse && !guid.IsItem())
|
||||
SetUnitFlags(UnitFlags.Looting);
|
||||
}
|
||||
else
|
||||
SendLootError(loot.GetGUID(), guid, LootError.DidntKill);
|
||||
|
||||
if (loot_type == LootType.Corpse && !guid.IsItem())
|
||||
AddUnitFlag(UnitFlags.Looting);
|
||||
}
|
||||
|
||||
public void SendLootError(ObjectGuid lootObj, ObjectGuid owner, LootError error)
|
||||
|
||||
@@ -3664,7 +3664,7 @@ namespace Game.Entities
|
||||
return false;
|
||||
|
||||
if (loot.loot_type == LootType.Skinning)
|
||||
return creature.GetSkinner() == GetGUID();
|
||||
return creature.GetLootRecipientGUID() == GetGUID();
|
||||
|
||||
Group thisGroup = GetGroup();
|
||||
if (!thisGroup)
|
||||
|
||||
@@ -1422,7 +1422,8 @@ namespace Game.Entities
|
||||
if (lootid != 0)
|
||||
loot.FillLoot(lootid, LootStorage.Creature, looter, false, false, creature.GetLootMode());
|
||||
|
||||
loot.generateMoneyLoot(creature.GetCreatureTemplate().MinGold, creature.GetCreatureTemplate().MaxGold);
|
||||
if (creature.GetLootMode() > 0)
|
||||
loot.generateMoneyLoot(creature.GetCreatureTemplate().MinGold, creature.GetCreatureTemplate().MaxGold);
|
||||
|
||||
if (group)
|
||||
{
|
||||
|
||||
@@ -90,6 +90,9 @@ namespace Game.Loots
|
||||
foreach (var id in lootIdSetUsed)
|
||||
lootIdSet.Remove(id);
|
||||
|
||||
// 1 means loot for player corpse
|
||||
lootIdSet.Remove(SharedConst.PlayerCorpseLootEntry);
|
||||
|
||||
// output error for any still listed (not referenced from appropriate table) ids
|
||||
Creature.ReportUnusedIds(lootIdSet);
|
||||
|
||||
|
||||
+44
-11
@@ -6411,18 +6411,51 @@ namespace Game.Spells
|
||||
|
||||
// @todo shit below shouldn't be here, but it's temporary
|
||||
//Check targets for LOS visibility
|
||||
if (losPosition != null)
|
||||
return target.IsWithinLOS(losPosition.GetPositionX(), losPosition.GetPositionY(), losPosition.GetPositionZ(), ModelIgnoreFlags.M2);
|
||||
else
|
||||
switch (effect.Effect)
|
||||
{
|
||||
// Get GO cast coordinates if original caster . GO
|
||||
WorldObject caster = null;
|
||||
if (m_originalCasterGUID.IsGameObject())
|
||||
caster = m_caster.GetMap().GetGameObject(m_originalCasterGUID);
|
||||
if (!caster)
|
||||
caster = m_caster;
|
||||
if (target != m_caster && !target.IsWithinLOSInMap(caster, ModelIgnoreFlags.M2))
|
||||
return false;
|
||||
case SpellEffectName.SkinPlayerCorpse:
|
||||
{
|
||||
if (m_targets.GetCorpseTargetGUID().IsEmpty())
|
||||
{
|
||||
if (target.IsWithinLOSInMap(m_caster, ModelIgnoreFlags.M2) && target.HasUnitFlag(UnitFlags.Skinnable))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Corpse corpse = ObjectAccessor.GetCorpse(m_caster, m_targets.GetCorpseTargetGUID());
|
||||
if (!corpse)
|
||||
return false;
|
||||
|
||||
if (target.GetGUID() != corpse.GetOwnerGUID())
|
||||
return false;
|
||||
|
||||
if (!corpse.HasDynamicFlag(UnitDynFlags.Lootable))
|
||||
return false;
|
||||
|
||||
if (!corpse.IsWithinLOSInMap(m_caster, ModelIgnoreFlags.M2))
|
||||
return false;
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (losPosition != null)
|
||||
return target.IsWithinLOS(losPosition.GetPositionX(), losPosition.GetPositionY(), losPosition.GetPositionZ(), ModelIgnoreFlags.M2);
|
||||
else
|
||||
{
|
||||
// Get GO cast coordinates if original caster -> GO
|
||||
WorldObject caster = null;
|
||||
if (m_originalCasterGUID.IsGameObject())
|
||||
caster = m_caster.GetMap().GetGameObject(m_originalCasterGUID);
|
||||
if (!caster)
|
||||
caster = m_caster;
|
||||
if (target != m_caster && !target.IsWithinLOSInMap(caster, ModelIgnoreFlags.M2))
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -4046,9 +4046,9 @@ namespace Game.Spells
|
||||
|
||||
SkillType skill = creature.GetCreatureTemplate().GetRequiredLootSkill();
|
||||
|
||||
m_caster.ToPlayer().SendLoot(creature.GetGUID(), LootType.Skinning);
|
||||
creature.RemoveUnitFlag(UnitFlags.Skinnable);
|
||||
creature.AddDynamicFlag(UnitDynFlags.Lootable);
|
||||
m_caster.ToPlayer().SendLoot(creature.GetGUID(), LootType.Skinning);
|
||||
|
||||
if (skill == SkillType.Skinning)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user