Core/Loot: Move loot generation out of Player::SendLoot
Port From (https://github.com/TrinityCore/TrinityCore/commit/8c20f620d7b070b13b40803095e5fa97f9349512)
This commit is contained in:
@@ -176,6 +176,11 @@ namespace Game
|
||||
}
|
||||
|
||||
public bool Invoke(Creature creature)
|
||||
{
|
||||
return IsValidAELootTarget(creature);
|
||||
}
|
||||
|
||||
public bool IsValidLootTarget(Creature creature)
|
||||
{
|
||||
if (creature.IsAlive())
|
||||
return false;
|
||||
@@ -189,6 +194,14 @@ namespace Game
|
||||
return _looter.IsAllowedToLoot(creature);
|
||||
}
|
||||
|
||||
bool IsValidAELootTarget(Creature creature)
|
||||
{
|
||||
if (creature.GetGUID() == _mainLootTarget)
|
||||
return false;
|
||||
|
||||
return IsValidLootTarget(creature);
|
||||
}
|
||||
|
||||
Player _looter;
|
||||
ObjectGuid _mainLootTarget;
|
||||
}
|
||||
@@ -200,6 +213,14 @@ namespace Game
|
||||
if (!GetPlayer().IsAlive() || !packet.Unit.IsCreatureOrVehicle())
|
||||
return;
|
||||
|
||||
Creature lootTarget = ObjectAccessor.GetCreature(GetPlayer(), packet.Unit);
|
||||
if (!lootTarget)
|
||||
return;
|
||||
|
||||
AELootCreatureCheck check = new(_player, packet.Unit);
|
||||
if (!check.IsValidLootTarget(lootTarget))
|
||||
return;
|
||||
|
||||
// interrupt cast
|
||||
if (GetPlayer().IsNonMeleeSpellCast(false))
|
||||
GetPlayer().InterruptNonMeleeSpells(false);
|
||||
@@ -207,7 +228,6 @@ namespace Game
|
||||
GetPlayer().RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Looting);
|
||||
|
||||
List<Creature> corpses = new();
|
||||
AELootCreatureCheck check = new(_player, packet.Unit);
|
||||
CreatureListSearcher searcher = new(_player, corpses, check);
|
||||
Cell.VisitGridObjects(_player, searcher, AELootCreatureCheck.LootDistance);
|
||||
|
||||
@@ -247,6 +267,8 @@ namespace Game
|
||||
if (player.GetLootGUID() == lguid)
|
||||
player.SetLootGUID(ObjectGuid.Empty);
|
||||
|
||||
//Player is not looking at loot list, he doesn't need to see updates on the loot list
|
||||
loot.RemoveLooter(player.GetGUID());
|
||||
player.SendLootRelease(lguid);
|
||||
player.GetAELootView().Remove(loot.GetGUID());
|
||||
|
||||
@@ -264,12 +286,7 @@ namespace Game
|
||||
if (!go || ((go.GetOwnerGUID() != player.GetGUID() && go.GetGoType() != GameObjectTypes.FishingHole) && !go.IsWithinDistInMap(player)))
|
||||
return;
|
||||
|
||||
if (go.GetGoType() == GameObjectTypes.Door)
|
||||
{
|
||||
// locked doors are opened with spelleffect openlock, prevent remove its as looted
|
||||
go.UseDoorOrButton();
|
||||
}
|
||||
else if (loot.IsLooted() || go.GetGoType() == GameObjectTypes.FishingNode)
|
||||
if (loot.IsLooted() || go.GetGoType() == GameObjectTypes.FishingNode || go.GetGoType() == GameObjectTypes.FishingHole)
|
||||
{
|
||||
if (go.GetGoType() == GameObjectTypes.FishingHole)
|
||||
{ // The fishing hole used once more
|
||||
@@ -288,10 +305,6 @@ namespace Game
|
||||
{
|
||||
// not fully looted object
|
||||
go.SetLootState(LootState.Activated, player);
|
||||
|
||||
// if the round robin player release, reset it.
|
||||
if (player.GetGUID() == loot.roundRobinPlayer)
|
||||
loot.roundRobinPlayer.Clear();
|
||||
}
|
||||
}
|
||||
else if (lguid.IsCorpse()) // ONLY remove insignia at BG
|
||||
@@ -342,12 +355,6 @@ namespace Game
|
||||
if (creature == null)
|
||||
return;
|
||||
|
||||
if (!creature.IsWithinDistInMap(player, AELootCreatureCheck.LootDistance))
|
||||
return;
|
||||
|
||||
if (creature.IsAlive() != (loot != null && loot.loot_type == LootType.Pickpocketing))
|
||||
return;
|
||||
|
||||
if (loot.IsLooted())
|
||||
{
|
||||
creature.RemoveDynamicFlag(UnitDynFlags.Lootable);
|
||||
|
||||
@@ -20,10 +20,10 @@ using Framework.Database;
|
||||
using Game.DataStorage;
|
||||
using Game.Entities;
|
||||
using Game.Guilds;
|
||||
using Game.Loots;
|
||||
using Game.Networking;
|
||||
using Game.Networking.Packets;
|
||||
using Game.Spells;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
@@ -190,11 +190,30 @@ namespace Game
|
||||
{
|
||||
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.SEL_CHARACTER_GIFT_BY_ITEM);
|
||||
stmt.AddValue(0, item.GetGUID().GetCounter());
|
||||
|
||||
var pos = item.GetPos();
|
||||
var itemGuid = item.GetGUID();
|
||||
_queryProcessor.AddCallback(DB.Characters.AsyncQuery(stmt)
|
||||
.WithCallback(result => HandleOpenWrappedItemCallback(item.GetPos(), item.GetGUID(), result)));
|
||||
.WithCallback(result => HandleOpenWrappedItemCallback(pos, itemGuid, result)));
|
||||
}
|
||||
else
|
||||
{
|
||||
// If item doesn't already have loot, attempt to load it. If that
|
||||
// fails then this is first time opening, generate loot
|
||||
if (!item.m_lootGenerated && !Global.LootItemStorage.LoadStoredLoot(item, player))
|
||||
{
|
||||
Loot loot = new(player.GetMap(), item.GetGUID(), LootType.Item, null);
|
||||
item.loot = loot;
|
||||
loot.GenerateMoneyLoot(item.GetTemplate().MinMoneyLoot, item.GetTemplate().MaxMoneyLoot);
|
||||
loot.FillLoot(item.GetEntry(), LootStorage.Items, player, true, loot.gold != 0);
|
||||
|
||||
// Force save the loot and money items that were just rolled
|
||||
// Also saves the container item ID in Loot struct (not to DB)
|
||||
if (loot.gold > 0 || loot.unlootedCount > 0)
|
||||
Global.LootItemStorage.AddNewStoredLoot(item.GetGUID().GetCounter(), loot, player);
|
||||
}
|
||||
player.SendLoot(item.GetGUID(), LootType.Item);
|
||||
}
|
||||
}
|
||||
|
||||
void HandleOpenWrappedItemCallback(ushort pos, ObjectGuid itemGuid, SQLResult result)
|
||||
|
||||
Reference in New Issue
Block a user