Core/Spells: don't allow spells with SPELL_EFFECT_CREATE_LOOT to be cast if there isn't enough space in inventory
Port From (https://github.com/TrinityCore/TrinityCore/commit/59da957165ef7d7529db30f90a30dc401d682052)
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
using Framework.Constants;
|
using Framework.Constants;
|
||||||
using Framework.Database;
|
using Framework.Database;
|
||||||
|
using Game.BattleFields;
|
||||||
using Game.BattleGrounds;
|
using Game.BattleGrounds;
|
||||||
using Game.DataStorage;
|
using Game.DataStorage;
|
||||||
using Game.Groups;
|
using Game.Groups;
|
||||||
@@ -30,7 +31,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using Game.BattleFields;
|
|
||||||
|
|
||||||
namespace Game.Entities
|
namespace Game.Entities
|
||||||
{
|
{
|
||||||
@@ -1796,25 +1796,25 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
case InventoryResult.CantEquipLevelI:
|
case InventoryResult.CantEquipLevelI:
|
||||||
case InventoryResult.PurchaseLevelTooLow:
|
case InventoryResult.PurchaseLevelTooLow:
|
||||||
{
|
{
|
||||||
failure.Level = (item1 ? item1.GetRequiredLevel() : 0);
|
failure.Level = (item1 ? item1.GetRequiredLevel() : 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InventoryResult.EventAutoequipBindConfirm: // no idea about this one...
|
case InventoryResult.EventAutoequipBindConfirm: // no idea about this one...
|
||||||
{
|
{
|
||||||
//failure.SrcContainer
|
//failure.SrcContainer
|
||||||
//failure.SrcSlot
|
//failure.SrcSlot
|
||||||
//failure.DstContainer
|
//failure.DstContainer
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InventoryResult.ItemMaxLimitCategoryCountExceededIs:
|
case InventoryResult.ItemMaxLimitCategoryCountExceededIs:
|
||||||
case InventoryResult.ItemMaxLimitCategorySocketedExceededIs:
|
case InventoryResult.ItemMaxLimitCategorySocketedExceededIs:
|
||||||
case InventoryResult.ItemMaxLimitCategoryEquippedExceededIs:
|
case InventoryResult.ItemMaxLimitCategoryEquippedExceededIs:
|
||||||
{
|
{
|
||||||
ItemTemplate proto = item1 ? item1.GetTemplate() : Global.ObjectMgr.GetItemTemplate(itemId);
|
ItemTemplate proto = item1 ? item1.GetTemplate() : Global.ObjectMgr.GetItemTemplate(itemId);
|
||||||
failure.LimitCategory = (int)(proto != null ? proto.GetItemLimitCategory() : 0u);
|
failure.LimitCategory = (int)(proto != null ? proto.GetItemLimitCategory() : 0u);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -3480,7 +3480,7 @@ namespace Game.Entities
|
|||||||
if (itemTemplate != null)
|
if (itemTemplate != null)
|
||||||
if (itemTemplate.GetFlags().HasAnyFlag(ItemFlags.HasLoot))
|
if (itemTemplate.GetFlags().HasAnyFlag(ItemFlags.HasLoot))
|
||||||
Global.LootItemStorage.RemoveStoredLootForContainer(pItem.GetGUID().GetCounter());
|
Global.LootItemStorage.RemoveStoredLootForContainer(pItem.GetGUID().GetCounter());
|
||||||
|
|
||||||
pItem.SetState(ItemUpdateState.Removed, this);
|
pItem.SetState(ItemUpdateState.Removed, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3566,7 +3566,7 @@ namespace Game.Entities
|
|||||||
ApplyItemEquipSpell(item, apply);
|
ApplyItemEquipSpell(item, apply);
|
||||||
|
|
||||||
if (updateItemAuras)
|
if (updateItemAuras)
|
||||||
{
|
{
|
||||||
ApplyItemDependentAuras(item, apply);
|
ApplyItemDependentAuras(item, apply);
|
||||||
WeaponAttackType attackType = Player.GetAttackBySlot(slot, item.GetTemplate().GetInventoryType());
|
WeaponAttackType attackType = Player.GetAttackBySlot(slot, item.GetTemplate().GetInventoryType());
|
||||||
if (attackType != WeaponAttackType.Max)
|
if (attackType != WeaponAttackType.Max)
|
||||||
@@ -3622,9 +3622,9 @@ namespace Game.Entities
|
|||||||
UpdateStatBuffMod(Stats.Intellect);
|
UpdateStatBuffMod(Stats.Intellect);
|
||||||
break;
|
break;
|
||||||
//case ItemModType.Spirit: //modify spirit
|
//case ItemModType.Spirit: //modify spirit
|
||||||
//HandleStatModifier(UnitMods.StatSpirit, UnitModifierType.BaseValue, (float)val, apply);
|
//HandleStatModifier(UnitMods.StatSpirit, UnitModifierType.BaseValue, (float)val, apply);
|
||||||
//ApplyStatBuffMod(Stats.Spirit, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatSpirit, UnitModifierType.BasePCTExcludeCreate)), apply);
|
//ApplyStatBuffMod(Stats.Spirit, MathFunctions.CalculatePct(val, GetModifierValue(UnitMods.StatSpirit, UnitModifierType.BasePCTExcludeCreate)), apply);
|
||||||
//break;
|
//break;
|
||||||
case ItemModType.Stamina: //modify stamina
|
case ItemModType.Stamina: //modify stamina
|
||||||
GtGenericMultByILvlRecord staminaMult = CliDB.StaminaMultByILvlGameTable.GetRow(itemLevel);
|
GtGenericMultByILvlRecord staminaMult = CliDB.StaminaMultByILvlGameTable.GetRow(itemLevel);
|
||||||
if (staminaMult != null)
|
if (staminaMult != null)
|
||||||
@@ -4514,7 +4514,30 @@ namespace Game.Entities
|
|||||||
|
|
||||||
return freeSlotCount;
|
return freeSlotCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public uint GetFreeInventorySpace()
|
||||||
|
{
|
||||||
|
uint freeSpace = 0;
|
||||||
|
|
||||||
|
// Check backpack
|
||||||
|
for (byte slot = InventorySlots.ItemStart; slot < InventorySlots.ItemEnd; ++slot)
|
||||||
|
{
|
||||||
|
Item item = GetItemByPos(InventorySlots.Bag0, slot);
|
||||||
|
if (item == null)
|
||||||
|
freeSpace += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check bags
|
||||||
|
for (byte i = InventorySlots.BagStart; i < InventorySlots.BagEnd; i++)
|
||||||
|
{
|
||||||
|
Bag bag = GetBagByPos(i);
|
||||||
|
if (bag != null)
|
||||||
|
freeSpace += bag.GetFreeSlots();
|
||||||
|
}
|
||||||
|
|
||||||
|
return freeSpace;
|
||||||
|
}
|
||||||
|
|
||||||
//Bags
|
//Bags
|
||||||
public Bag GetBagByPos(byte bag)
|
public Bag GetBagByPos(byte bag)
|
||||||
{
|
{
|
||||||
@@ -4681,15 +4704,15 @@ namespace Game.Entities
|
|||||||
slots[0] = EquipmentSlot.Cloak;
|
slots[0] = EquipmentSlot.Cloak;
|
||||||
break;
|
break;
|
||||||
case InventoryType.Weapon:
|
case InventoryType.Weapon:
|
||||||
{
|
{
|
||||||
slots[0] = EquipmentSlot.MainHand;
|
slots[0] = EquipmentSlot.MainHand;
|
||||||
|
|
||||||
// suggest offhand slot only if know dual wielding
|
// suggest offhand slot only if know dual wielding
|
||||||
// (this will be replace mainhand weapon at auto equip instead unwonted "you don't known dual wielding" ...
|
// (this will be replace mainhand weapon at auto equip instead unwonted "you don't known dual wielding" ...
|
||||||
if (CanDualWield())
|
if (CanDualWield())
|
||||||
slots[1] = EquipmentSlot.OffHand;
|
slots[1] = EquipmentSlot.OffHand;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case InventoryType.Shield:
|
case InventoryType.Shield:
|
||||||
slots[0] = EquipmentSlot.OffHand;
|
slots[0] = EquipmentSlot.OffHand;
|
||||||
break;
|
break;
|
||||||
@@ -5462,7 +5485,7 @@ namespace Game.Entities
|
|||||||
// equipment visual show
|
// equipment visual show
|
||||||
SetVisibleItemSlot(slot, null);
|
SetVisibleItemSlot(slot, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_items[slot] = null;
|
m_items[slot] = null;
|
||||||
}
|
}
|
||||||
else if ((pBag = GetBagByPos(bag)) != null)
|
else if ((pBag = GetBagByPos(bag)) != null)
|
||||||
@@ -5802,7 +5825,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte GetInventorySlotCount() { return m_activePlayerData.NumBackpackSlots; }
|
public byte GetInventorySlotCount() { return m_activePlayerData.NumBackpackSlots; }
|
||||||
public void SetInventorySlotCount(byte slots)
|
public void SetInventorySlotCount(byte slots)
|
||||||
{
|
{
|
||||||
//ASSERT(slots <= (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START));
|
//ASSERT(slots <= (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START));
|
||||||
@@ -5951,7 +5974,7 @@ namespace Game.Entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Dictionary<ObjectGuid, ObjectGuid> GetAELootView() { return m_AELootView; }
|
public Dictionary<ObjectGuid, ObjectGuid> GetAELootView() { return m_AELootView; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// if in a Battleground a player dies, and an enemy removes the insignia, the player's bones is lootable
|
/// if in a Battleground a player dies, and an enemy removes the insignia, the player's bones is lootable
|
||||||
/// Called by remove insignia spell effect
|
/// Called by remove insignia spell effect
|
||||||
@@ -6559,7 +6582,7 @@ namespace Game.Entities
|
|||||||
{
|
{
|
||||||
if (oldSlot >= SharedConst.VoidStorageMaxSlot || newSlot >= SharedConst.VoidStorageMaxSlot || oldSlot == newSlot)
|
if (oldSlot >= SharedConst.VoidStorageMaxSlot || newSlot >= SharedConst.VoidStorageMaxSlot || oldSlot == newSlot)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_voidStorageItems.Swap(newSlot, oldSlot);
|
_voidStorageItems.Swap(newSlot, oldSlot);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-17
@@ -6094,33 +6094,49 @@ namespace Game.Spells
|
|||||||
case SpellEffectName.CreateLoot:
|
case SpellEffectName.CreateLoot:
|
||||||
{
|
{
|
||||||
// m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
|
// m_targets.GetUnitTarget() means explicit cast, otherwise we dont check for possible equip error
|
||||||
Unit target = m_targets.GetUnitTarget() ? m_targets.GetUnitTarget() : player;
|
Unit target = m_targets.GetUnitTarget() ?? player;
|
||||||
if (target.IsPlayer() && !IsTriggered() && spellEffectInfo.ItemType != 0)
|
if (target.IsPlayer() && !IsTriggered())
|
||||||
{
|
{
|
||||||
List<ItemPosCount> dest = new();
|
|
||||||
InventoryResult msg = target.ToPlayer().CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, spellEffectInfo.ItemType, 1);
|
// SPELL_EFFECT_CREATE_ITEM_2 differs from SPELL_EFFECT_CREATE_ITEM in that it picks the random item to create from a pool of potential items,
|
||||||
if (msg != InventoryResult.Ok)
|
// so we need to make sure there is at least one free space in the player's inventory
|
||||||
|
if (spellEffectInfo.Effect == SpellEffectName.CreateLoot)
|
||||||
{
|
{
|
||||||
ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(spellEffectInfo.ItemType);
|
if (target.ToPlayer().GetFreeInventorySpace() == 0)
|
||||||
// @todo Needs review
|
|
||||||
if (itemTemplate != null && itemTemplate.GetItemLimitCategory() == 0)
|
|
||||||
{
|
{
|
||||||
player.SendEquipError(msg, null, null, spellEffectInfo.ItemType);
|
player.SendEquipError(InventoryResult.InvFull, null, null, spellEffectInfo.ItemType);
|
||||||
return SpellCastResult.DontReport;
|
return SpellCastResult.DontReport;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (spellEffectInfo.ItemType != 0)
|
||||||
|
{
|
||||||
|
List<ItemPosCount> dest = new();
|
||||||
|
InventoryResult msg = target.ToPlayer().CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, spellEffectInfo.ItemType, 1);
|
||||||
|
if (msg != InventoryResult.Ok)
|
||||||
{
|
{
|
||||||
// Conjure Food/Water/Refreshment spells
|
ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(spellEffectInfo.ItemType);
|
||||||
if (!(m_spellInfo.SpellFamilyName == SpellFamilyNames.Mage && m_spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x40000000u)))
|
/// @todo Needs review
|
||||||
return SpellCastResult.TooManyOfItem;
|
if (itemTemplate != null && itemTemplate.GetItemLimitCategory() == 0)
|
||||||
else if (!target.ToPlayer().HasItemCount(spellEffectInfo.ItemType))
|
|
||||||
{
|
{
|
||||||
player.SendEquipError(msg, null, null, spellEffectInfo.ItemType);
|
player.SendEquipError(msg, null, null, spellEffectInfo.ItemType);
|
||||||
return SpellCastResult.DontReport;
|
return SpellCastResult.DontReport;
|
||||||
}
|
}
|
||||||
else if (m_spellInfo.GetEffects().Count > 1)
|
else
|
||||||
player.CastSpell(m_caster, (uint)m_spellInfo.GetEffect(1).CalcValue(), new CastSpellExtraArgs().SetOriginalCastId(m_castId)); // move this to anywhere
|
{
|
||||||
return SpellCastResult.DontReport;
|
// Conjure Food/Water/Refreshment spells
|
||||||
|
if (m_spellInfo.SpellFamilyName != SpellFamilyNames.Mage || (!m_spellInfo.SpellFamilyFlags[0].HasAnyFlag(0x40000000u)))
|
||||||
|
return SpellCastResult.TooManyOfItem;
|
||||||
|
else if (!(target.ToPlayer().HasItemCount(spellEffectInfo.ItemType)))
|
||||||
|
{
|
||||||
|
player.SendEquipError(msg, null, null, spellEffectInfo.ItemType);
|
||||||
|
return SpellCastResult.DontReport;
|
||||||
|
}
|
||||||
|
else if (m_spellInfo.GetEffects().Count > 1)
|
||||||
|
player.CastSpell(player, (uint)m_spellInfo.GetEffect(1).CalcValue(), new CastSpellExtraArgs()
|
||||||
|
.SetOriginalCastId(m_castId)); // move this to anywhere
|
||||||
|
return SpellCastResult.DontReport;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1098,32 +1098,21 @@ namespace Game.Spells
|
|||||||
|
|
||||||
Player player = unitTarget.ToPlayer();
|
Player player = unitTarget.ToPlayer();
|
||||||
|
|
||||||
uint item_id = effectInfo.ItemType;
|
|
||||||
ItemContext context = m_spellInfo.HasAttribute(SpellAttr0.Tradespell) ? ItemContext.TradeSkill : ItemContext.None;
|
ItemContext context = m_spellInfo.HasAttribute(SpellAttr0.Tradespell) ? ItemContext.TradeSkill : ItemContext.None;
|
||||||
|
|
||||||
if (item_id != 0)
|
// Pick a random item from spell_loot_template
|
||||||
DoCreateItem(item_id, context);
|
|
||||||
|
|
||||||
// special case: fake item replaced by generate using spell_loot_template
|
|
||||||
if (m_spellInfo.IsLootCrafting())
|
if (m_spellInfo.IsLootCrafting())
|
||||||
{
|
{
|
||||||
if (item_id != 0)
|
player.AutoStoreLoot(m_spellInfo.Id, LootStorage.Spell, context, false, true);
|
||||||
{
|
|
||||||
if (!player.HasItemCount(item_id))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// remove reagent
|
|
||||||
uint count = 1;
|
|
||||||
player.DestroyItemCount(item_id, count, true);
|
|
||||||
|
|
||||||
// create some random items
|
|
||||||
player.AutoStoreLoot(m_spellInfo.Id, LootStorage.Spell, context);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
player.AutoStoreLoot(m_spellInfo.Id, LootStorage.Spell, context); // create some random items
|
|
||||||
|
|
||||||
player.UpdateCraftSkill(m_spellInfo.Id);
|
player.UpdateCraftSkill(m_spellInfo.Id);
|
||||||
}
|
}
|
||||||
|
else // If there's no random loot entries for this spell, pick the item associated with this spell
|
||||||
|
{
|
||||||
|
uint itemId = effectInfo.ItemType;
|
||||||
|
if (itemId != 0)
|
||||||
|
DoCreateItem(itemId, context);
|
||||||
|
}
|
||||||
|
|
||||||
// @todo ExecuteLogEffectCreateItem(i, GetEffect(i].ItemType);
|
// @todo ExecuteLogEffectCreateItem(i, GetEffect(i].ItemType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user