Beispiel #1
0
        void HandleLootMasterGive(MasterLootItem masterLootItem)
        {
            AELootResult aeResult = new();

            if (GetPlayer().GetGroup() == null || GetPlayer().GetGroup().GetLooterGuid() != GetPlayer().GetGUID() || GetPlayer().GetGroup().GetLootMethod() != LootMethod.MasterLoot)
            {
                GetPlayer().SendLootError(ObjectGuid.Empty, ObjectGuid.Empty, LootError.DidntKill);
                return;
            }

            // player on other map
            Player target = Global.ObjAccessor.GetPlayer(_player, masterLootItem.Target);

            if (!target)
            {
                GetPlayer().SendLootError(ObjectGuid.Empty, ObjectGuid.Empty, LootError.PlayerNotFound);
                return;
            }

            foreach (LootRequest req in masterLootItem.Loot)
            {
                Loot       loot     = null;
                ObjectGuid lootguid = _player.GetLootWorldObjectGUID(req.Object);

                if (!_player.IsInRaidWith(target) || !_player.IsInMap(target))
                {
                    _player.SendLootError(req.Object, ObjectGuid.Empty, LootError.MasterOther);
                    Log.outInfo(LogFilter.Cheat, $"MasterLootItem: Player {GetPlayer().GetName()} tried to give an item to ineligible player {target.GetName()} !");
                    return;
                }

                if (GetPlayer().GetLootGUID().IsCreatureOrVehicle())
                {
                    Creature creature = GetPlayer().GetMap().GetCreature(lootguid);
                    if (!creature)
                    {
                        return;
                    }

                    loot = creature.loot;
                }
                else if (GetPlayer().GetLootGUID().IsGameObject())
                {
                    GameObject pGO = GetPlayer().GetMap().GetGameObject(lootguid);
                    if (!pGO)
                    {
                        return;
                    }

                    loot = pGO.loot;
                }

                if (loot == null)
                {
                    return;
                }

                byte slotid = (byte)(req.LootListID - 1);
                if (slotid >= loot.items.Count + loot.quest_items.Count)
                {
                    Log.outDebug(LogFilter.Loot, $"MasterLootItem: Player {GetPlayer().GetName()} might be using a hack! (slot {slotid}, size {loot.items.Count})");
                    return;
                }

                LootItem item = slotid >= loot.items.Count ? loot.quest_items[slotid - loot.items.Count] : loot.items[slotid];

                List <ItemPosCount> dest = new();
                InventoryResult     msg  = target.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, item.itemid, item.count);
                if (item.follow_loot_rules && !item.AllowedForPlayer(target))
                {
                    msg = InventoryResult.CantEquipEver;
                }
                if (msg != InventoryResult.Ok)
                {
                    if (msg == InventoryResult.ItemMaxCount)
                    {
                        _player.SendLootError(req.Object, ObjectGuid.Empty, LootError.MasterUniqueItem);
                    }
                    else if (msg == InventoryResult.InvFull)
                    {
                        _player.SendLootError(req.Object, ObjectGuid.Empty, LootError.MasterInvFull);
                    }
                    else
                    {
                        _player.SendLootError(req.Object, ObjectGuid.Empty, LootError.MasterOther);
                    }

                    target.SendEquipError(msg, null, null, item.itemid);
                    return;
                }

                // now move item from loot to target inventory
                Item newitem = target.StoreNewItem(dest, item.itemid, true, item.randomBonusListId, item.GetAllowedLooters(), item.context, item.BonusListIDs);
                aeResult.Add(newitem, item.count, loot.loot_type);

                // mark as looted
                item.count     = 0;
                item.is_looted = true;

                loot.NotifyItemRemoved(slotid);
                --loot.unlootedCount;
            }

            foreach (var resultValue in aeResult.GetByOrder())
            {
                target.SendNewItem(resultValue.item, resultValue.count, false, false, true);
                target.UpdateCriteria(CriteriaTypes.LootItem, resultValue.item.GetEntry(), resultValue.count);
                target.UpdateCriteria(CriteriaTypes.LootType, resultValue.item.GetEntry(), resultValue.count, (ulong)resultValue.lootType);
                target.UpdateCriteria(CriteriaTypes.LootEpicItem, resultValue.item.GetEntry(), resultValue.count);
            }
        }
Beispiel #2
0
        public uint SendChat(Creature source, byte textGroup, WorldObject whisperTarget = null, ChatMsg msgType = ChatMsg.Addon, Language language = Language.Addon,
                             CreatureTextRange range = CreatureTextRange.Normal, uint sound = 0, Team team = Team.Other, bool gmOnly = false, Player srcPlr = null)
        {
            if (source == null)
            {
                return(0);
            }

            var sList = mTextMap.LookupByKey(source.GetEntry());

            if (sList == null)
            {
                Log.outError(LogFilter.Sql, "GossipManager: Could not find Text for Creature({0}) Entry {1} in 'creature_text' table. Ignoring.", source.GetName(), source.GetEntry());
                return(0);
            }

            var textGroupContainer = sList.LookupByKey(textGroup);

            if (textGroupContainer.Empty())
            {
                Log.outError(LogFilter.ChatSystem, "GossipManager: Could not find TextGroup {0} for Creature({1}) GuidLow {2} Entry {3}. Ignoring.", textGroup, source.GetName(), source.GetGUID().ToString(), source.GetEntry());
                return(0);
            }

            List <CreatureTextEntry> tempGroup = new List <CreatureTextEntry>();
            var repeatGroup = source.GetTextRepeatGroup(textGroup);

            foreach (var entry in textGroupContainer)
            {
                if (!repeatGroup.Contains(entry.id))
                {
                    tempGroup.Add(entry);
                }
            }

            if (tempGroup.Empty())
            {
                source.ClearTextRepeatGroup(textGroup);
                tempGroup = textGroupContainer;
            }

            var textEntry = tempGroup.SelectRandomElementByWeight(t => { return(t.probability); });

            ChatMsg  finalType  = (msgType == ChatMsg.Addon) ? textEntry.type : msgType;
            Language finalLang  = (language == Language.Addon) ? textEntry.lang : language;
            uint     finalSound = textEntry.sound;

            if (sound != 0)
            {
                finalSound = sound;
            }
            else
            {
                BroadcastTextRecord bct = CliDB.BroadcastTextStorage.LookupByKey(textEntry.BroadcastTextId);
                if (bct != null)
                {
                    uint broadcastTextSoundId = bct.SoundID[source.GetGender() == Gender.Female ? 1 : 0];
                    if (broadcastTextSoundId != 0)
                    {
                        finalSound = broadcastTextSoundId;
                    }
                }
            }

            if (range == CreatureTextRange.Normal)
            {
                range = textEntry.TextRange;
            }

            if (finalSound != 0)
            {
                SendSound(source, finalSound, finalType, whisperTarget, range, team, gmOnly);
            }

            Unit finalSource = source;

            if (srcPlr)
            {
                finalSource = srcPlr;
            }

            if (textEntry.emote != 0)
            {
                SendEmote(finalSource, textEntry.emote);
            }

            if (srcPlr)
            {
                PlayerTextBuilder builder = new PlayerTextBuilder(source, finalSource, finalSource.GetGender(), finalType, textEntry.groupId, textEntry.id, finalLang, whisperTarget);
                SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly);
            }
            else
            {
                CreatureTextBuilder builder = new CreatureTextBuilder(finalSource, finalSource.GetGender(), finalType, textEntry.groupId, textEntry.id, finalLang, whisperTarget);
                SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly);
            }

            source.SetTextRepeatId(textGroup, textEntry.id);
            return(textEntry.duration);
        }
Beispiel #3
0
        void HandleAutostoreLootItem(LootItemPkt packet)
        {
            Player       player   = GetPlayer();
            AELootResult aeResult = player.GetAELootView().Count > 1 ? new AELootResult() : null;

            // @todo Implement looting by LootObject guid
            foreach (LootRequest req in packet.Loot)
            {
                Loot       loot  = null;
                ObjectGuid lguid = player.GetLootWorldObjectGUID(req.Object);

                if (lguid.IsGameObject())
                {
                    GameObject go = player.GetMap().GetGameObject(lguid);

                    // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
                    if (!go || ((go.GetOwnerGUID() != player.GetGUID() && go.GetGoType() != GameObjectTypes.FishingHole) && !go.IsWithinDistInMap(player, SharedConst.InteractionDistance)))
                    {
                        player.SendLootRelease(lguid);
                        continue;
                    }

                    loot = go.loot;
                }
                else if (lguid.IsItem())
                {
                    Item pItem = player.GetItemByGuid(lguid);

                    if (!pItem)
                    {
                        player.SendLootRelease(lguid);
                        continue;
                    }

                    loot = pItem.loot;
                }
                else if (lguid.IsCorpse())
                {
                    Corpse bones = ObjectAccessor.GetCorpse(player, lguid);
                    if (!bones)
                    {
                        player.SendLootRelease(lguid);
                        continue;
                    }

                    loot = bones.loot;
                }
                else
                {
                    Creature creature = player.GetMap().GetCreature(lguid);

                    bool lootAllowed = creature && creature.IsAlive() == (player.GetClass() == Class.Rogue && creature.loot.loot_type == LootType.Pickpocketing);
                    if (!lootAllowed || !creature.IsWithinDistInMap(player, AELootCreatureCheck.LootDistance))
                    {
                        player.SendLootError(req.Object, lguid, lootAllowed ? LootError.TooFar : LootError.DidntKill);
                        continue;
                    }

                    loot = creature.loot;
                }

                player.StoreLootItem((byte)(req.LootListID - 1), loot, aeResult);

                // If player is removing the last LootItem, delete the empty container.
                if (loot.IsLooted() && lguid.IsItem())
                {
                    player.GetSession().DoLootRelease(lguid);
                }
            }

            if (aeResult != null)
            {
                foreach (var resultValue in aeResult.GetByOrder())
                {
                    player.SendNewItem(resultValue.item, resultValue.count, false, false, true);
                    player.UpdateCriteria(CriteriaTypes.LootItem, resultValue.item.GetEntry(), resultValue.count);
                    player.UpdateCriteria(CriteriaTypes.LootType, resultValue.item.GetEntry(), resultValue.count, (ulong)resultValue.lootType);
                    player.UpdateCriteria(CriteriaTypes.LootEpicItem, resultValue.item.GetEntry(), resultValue.count);
                }
            }
        }
Beispiel #4
0
        public void DoLootRelease(ObjectGuid lguid)
        {
            Player player = GetPlayer();
            Loot   loot;

            if (player.GetLootGUID() == lguid)
            {
                player.SetLootGUID(ObjectGuid.Empty);
            }

            player.SendLootRelease(lguid);
            player.RemoveAELootedWorldObject(lguid);

            player.RemoveUnitFlag(UnitFlags.Looting);

            if (!player.IsInWorld)
            {
                return;
            }

            if (lguid.IsGameObject())
            {
                GameObject go = player.GetMap().GetGameObject(lguid);

                // not check distance for GO in case owned GO (fishing bobber case, for example) or Fishing hole GO
                if (!go || ((go.GetOwnerGUID() != player.GetGUID() && go.GetGoType() != GameObjectTypes.FishingHole) && !go.IsWithinDistInMap(player, SharedConst.InteractionDistance)))
                {
                    return;
                }

                loot = go.loot;

                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 (go.GetGoType() == GameObjectTypes.FishingHole)
                    {                                              // The fishing hole used once more
                        go.AddUse();                               // if the max usage is reached, will be despawned in next tick
                        if (go.GetUseCount() >= go.GetGoValue().FishingHole.MaxOpens)
                        {
                            go.SetLootState(LootState.JustDeactivated);
                        }
                        else
                        {
                            go.SetLootState(LootState.Ready);
                        }
                    }
                    else
                    {
                        go.SetLootState(LootState.JustDeactivated);
                    }

                    loot.Clear();
                }
                else
                {
                    // 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
            {
                Corpse corpse = ObjectAccessor.GetCorpse(player, lguid);
                if (!corpse || !corpse.IsWithinDistInMap(player, SharedConst.InteractionDistance))
                {
                    return;
                }

                loot = corpse.loot;

                if (loot.IsLooted())
                {
                    loot.Clear();
                    corpse.RemoveCorpseDynamicFlag(CorpseDynFlags.Lootable);
                }
            }
            else if (lguid.IsItem())
            {
                Item pItem = player.GetItemByGuid(lguid);
                if (!pItem)
                {
                    return;
                }

                ItemTemplate proto = pItem.GetTemplate();

                // destroy only 5 items from stack in case prospecting and milling
                if (pItem.loot.loot_type == LootType.Prospecting || pItem.loot.loot_type == LootType.Milling)
                {
                    pItem.m_lootGenerated = false;
                    pItem.loot.Clear();

                    uint count = pItem.GetCount();

                    // >=5 checked in spell code, but will work for cheating cases also with removing from another stacks.
                    if (count > 5)
                    {
                        count = 5;
                    }

                    player.DestroyItemCount(pItem, ref count, true);
                }
                else
                {
                    if (pItem.loot.IsLooted() || !proto.GetFlags().HasAnyFlag(ItemFlags.HasLoot)) // Only delete item if no loot or money (unlooted loot is saved to db)
                    {
                        player.DestroyItem(pItem.GetBagSlot(), pItem.GetSlot(), true);
                    }
                }
                return;                                             // item can be looted only single player
            }
            else
            {
                Creature creature = player.GetMap().GetCreature(lguid);

                bool lootAllowed = creature && creature.IsAlive() == (player.GetClass() == Class.Rogue && creature.loot.loot_type == LootType.Pickpocketing);
                if (!lootAllowed || !creature.IsWithinDistInMap(player, AELootCreatureCheck.LootDistance))
                {
                    return;
                }

                loot = creature.loot;
                if (loot.IsLooted())
                {
                    creature.RemoveDynamicFlag(UnitDynFlags.Lootable);

                    // skip pickpocketing loot for speed, skinning timer reduction is no-op in fact
                    if (!creature.IsAlive())
                    {
                        creature.AllLootRemovedFromCorpse();
                    }

                    loot.Clear();
                }
                else
                {
                    // if the round robin player release, reset it.
                    if (player.GetGUID() == loot.roundRobinPlayer)
                    {
                        loot.roundRobinPlayer.Clear();

                        Group group = player.GetGroup();
                        if (group)
                        {
                            if (group.GetLootMethod() != LootMethod.MasterLoot)
                            {
                                group.SendLooter(creature, null);
                            }
                        }
                        // force dynflag update to update looter and lootable info
                        creature.m_values.ModifyValue(creature.m_objectData).ModifyValue(creature.m_objectData.DynamicFlags);
                        creature.ForceUpdateFieldChange();
                    }
                }
            }

            //Player is not looking at loot list, he doesn't need to see updates on the loot list
            loot.RemoveLooter(player.GetGUID());
        }
        void HandleVoidStorageTransfer(VoidStorageTransfer voidStorageTransfer)
        {
            Player player = GetPlayer();

            Creature unit = player.GetNPCIfCanInteractWith(voidStorageTransfer.Npc, NPCFlags.VaultKeeper);

            if (!unit)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} not found or player can't interact with it.", voidStorageTransfer.Npc.ToString());
                return;
            }

            if (!player.IsVoidStorageUnlocked())
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - Player ({0}, name: {1}) queried void storage without unlocking it.", player.GetGUID().ToString(), player.GetName());
                return;
            }

            if (voidStorageTransfer.Deposits.Length > player.GetNumOfVoidStorageFreeSlots())
            {
                SendVoidStorageTransferResult(VoidTransferError.Full);
                return;
            }

            uint freeBagSlots = 0;

            if (!voidStorageTransfer.Withdrawals.Empty())
            {
                // make this a Player function
                for (byte i = InventorySlots.BagStart; i < InventorySlots.BagEnd; i++)
                {
                    Bag bag = player.GetBagByPos(i);
                    if (bag)
                    {
                        freeBagSlots += bag.GetFreeSlots();
                    }
                }
                int inventoryEnd = InventorySlots.ItemStart + _player.GetInventorySlotCount();
                for (byte i = InventorySlots.ItemStart; i < inventoryEnd; i++)
                {
                    if (!player.GetItemByPos(InventorySlots.Bag0, i))
                    {
                        ++freeBagSlots;
                    }
                }
            }

            if (voidStorageTransfer.Withdrawals.Length > freeBagSlots)
            {
                SendVoidStorageTransferResult(VoidTransferError.InventoryFull);
                return;
            }

            if (!player.HasEnoughMoney((voidStorageTransfer.Deposits.Length * SharedConst.VoidStorageStoreItemCost)))
            {
                SendVoidStorageTransferResult(VoidTransferError.NotEnoughMoney);
                return;
            }

            VoidStorageTransferChanges voidStorageTransferChanges = new VoidStorageTransferChanges();

            byte depositCount = 0;

            for (int i = 0; i < voidStorageTransfer.Deposits.Length; ++i)
            {
                Item item = player.GetItemByGuid(voidStorageTransfer.Deposits[i]);
                if (!item)
                {
                    Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} {1} wants to deposit an invalid item ({2}).", player.GetGUID().ToString(), player.GetName(), voidStorageTransfer.Deposits[i].ToString());
                    continue;
                }

                VoidStorageItem itemVS = new VoidStorageItem(Global.ObjectMgr.GenerateVoidStorageItemId(), item.GetEntry(), item.GetGuidValue(ItemFields.Creator),
                                                             item.GetItemRandomEnchantmentId(), item.GetItemSuffixFactor(), item.GetModifier(ItemModifier.UpgradeId),
                                                             item.GetModifier(ItemModifier.ScalingStatDistributionFixedLevel), item.GetModifier(ItemModifier.ArtifactKnowledgeLevel),
                                                             (byte)item.GetUInt32Value(ItemFields.Context), item.GetDynamicValues(ItemDynamicFields.BonusListIds));

                VoidItem voidItem;
                voidItem.Guid    = ObjectGuid.Create(HighGuid.Item, itemVS.ItemId);
                voidItem.Creator = item.GetGuidValue(ItemFields.Creator);
                voidItem.Item    = new ItemInstance(itemVS);
                voidItem.Slot    = _player.AddVoidStorageItem(itemVS);

                voidStorageTransferChanges.AddedItems.Add(voidItem);

                player.DestroyItem(item.GetBagSlot(), item.GetSlot(), true);
                ++depositCount;
            }

            long cost = depositCount * SharedConst.VoidStorageStoreItemCost;

            player.ModifyMoney(-cost);

            for (int i = 0; i < voidStorageTransfer.Withdrawals.Length; ++i)
            {
                byte            slot;
                VoidStorageItem itemVS = player.GetVoidStorageItem(voidStorageTransfer.Withdrawals[i].GetCounter(), out slot);
                if (itemVS == null)
                {
                    Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} {1} tried to withdraw an invalid item ({2})", player.GetGUID().ToString(), player.GetName(), voidStorageTransfer.Withdrawals[i].ToString());
                    continue;
                }

                List <ItemPosCount> dest = new List <ItemPosCount>();
                InventoryResult     msg  = player.CanStoreNewItem(ItemConst.NullBag, ItemConst.NullSlot, dest, itemVS.ItemEntry, 1);
                if (msg != InventoryResult.Ok)
                {
                    SendVoidStorageTransferResult(VoidTransferError.InventoryFull);
                    Log.outDebug(LogFilter.Network, "WORLD: HandleVoidStorageTransfer - {0} {1} couldn't withdraw {2} because inventory was full.", player.GetGUID().ToString(), player.GetName(), voidStorageTransfer.Withdrawals[i].ToString());
                    return;
                }

                Item item = player.StoreNewItem(dest, itemVS.ItemEntry, true, itemVS.ItemRandomPropertyId, null, itemVS.Context, itemVS.BonusListIDs);
                item.SetUInt32Value(ItemFields.PropertySeed, itemVS.ItemSuffixFactor);
                item.SetGuidValue(ItemFields.Creator, itemVS.CreatorGuid);
                item.SetModifier(ItemModifier.UpgradeId, itemVS.ItemUpgradeId);
                item.SetBinding(true);
                GetCollectionMgr().AddItemAppearance(item);

                voidStorageTransferChanges.RemovedItems.Add(ObjectGuid.Create(HighGuid.Item, itemVS.ItemId));

                player.DeleteVoidStorageItem(slot);
            }

            SendPacket(voidStorageTransferChanges);
            SendVoidStorageTransferResult(VoidTransferError.Ok);
        }
Beispiel #6
0
        void HandleLootMoney(LootMoney lootMoney)
        {
            Player player = GetPlayer();

            foreach (var lootView in player.GetAELootView())
            {
                ObjectGuid guid       = lootView.Value;
                Loot       loot       = null;
                bool       shareMoney = true;

                switch (guid.GetHigh())
                {
                case HighGuid.GameObject:
                {
                    GameObject go = player.GetMap().GetGameObject(guid);

                    // do not check distance for GO if player is the owner of it (ex. fishing bobber)
                    if (go && ((go.GetOwnerGUID() == player.GetGUID() || go.IsWithinDistInMap(player, SharedConst.InteractionDistance))))
                    {
                        loot = go.loot;
                    }

                    break;
                }

                case HighGuid.Corpse:                                   // remove insignia ONLY in BG
                {
                    Corpse bones = ObjectAccessor.GetCorpse(player, guid);

                    if (bones && bones.IsWithinDistInMap(player, SharedConst.InteractionDistance))
                    {
                        loot       = bones.loot;
                        shareMoney = false;
                    }

                    break;
                }

                case HighGuid.Item:
                {
                    Item item = player.GetItemByGuid(guid);
                    if (item)
                    {
                        loot       = item.loot;
                        shareMoney = false;
                    }
                    break;
                }

                case HighGuid.Creature:
                case HighGuid.Vehicle:
                {
                    Creature creature    = player.GetMap().GetCreature(guid);
                    bool     lootAllowed = creature && creature.IsAlive() == (player.GetClass() == Class.Rogue && creature.loot.loot_type == LootType.Pickpocketing);
                    if (lootAllowed && creature.IsWithinDistInMap(player, AELootCreatureCheck.LootDistance))
                    {
                        loot = creature.loot;
                        if (creature.IsAlive())
                        {
                            shareMoney = false;
                        }
                    }
                    else
                    {
                        player.SendLootError(lootView.Key, guid, lootAllowed ? LootError.TooFar : LootError.DidntKill);
                    }
                    break;
                }

                default:
                    continue;                                             // unlootable type
                }

                if (loot == null)
                {
                    continue;
                }

                loot.NotifyMoneyRemoved();
                if (shareMoney && player.GetGroup() != null)      //item, pickpocket and players can be looted only single player
                {
                    Group group = player.GetGroup();

                    List <Player> playersNear = new();
                    for (GroupReference refe = group.GetFirstMember(); refe != null; refe = refe.Next())
                    {
                        Player member = refe.GetSource();
                        if (!member)
                        {
                            continue;
                        }

                        if (player.IsAtGroupRewardDistance(member))
                        {
                            playersNear.Add(member);
                        }
                    }

                    ulong goldPerPlayer = (ulong)(loot.gold / playersNear.Count);

                    foreach (var pl in playersNear)
                    {
                        ulong goldMod = MathFunctions.CalculatePct(goldPerPlayer, pl.GetTotalAuraModifierByMiscValue(AuraType.ModMoneyGain, 1));

                        pl.ModifyMoney((long)(goldPerPlayer + goldMod));
                        pl.UpdateCriteria(CriteriaTypes.LootMoney, goldPerPlayer);

                        LootMoneyNotify packet = new();
                        packet.Money      = goldPerPlayer;
                        packet.MoneyMod   = goldMod;
                        packet.SoleLooter = playersNear.Count <= 1 ? true : false;
                        pl.SendPacket(packet);
                    }
                }
                else
                {
                    ulong goldMod = MathFunctions.CalculatePct(loot.gold, player.GetTotalAuraModifierByMiscValue(AuraType.ModMoneyGain, 1));

                    player.ModifyMoney((long)(loot.gold + goldMod));
                    player.UpdateCriteria(CriteriaTypes.LootMoney, loot.gold);

                    LootMoneyNotify packet = new();
                    packet.Money      = loot.gold;
                    packet.MoneyMod   = goldMod;
                    packet.SoleLooter = true; // "You loot..."
                    SendPacket(packet);
                }

                loot.gold = 0;

                // Delete the money loot record from the DB
                if (!loot.containerID.IsEmpty())
                {
                    Global.LootItemStorage.RemoveStoredMoneyForContainer(loot.containerID.GetCounter());
                }

                // Delete container if empty
                if (loot.IsLooted() && guid.IsItem())
                {
                    player.GetSession().DoLootRelease(guid);
                }
            }
        }
Beispiel #7
0
        void HandleActivateTaxi(ActivateTaxi activateTaxi)
        {
            Creature unit = GetPlayer().GetNPCIfCanInteractWith(activateTaxi.Vendor, NPCFlags.FlightMaster);

            if (unit == null)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleActivateTaxiOpcode - {0} not found or you can't interact with it.", activateTaxi.Vendor.ToString());
                return;
            }

            uint curloc = Global.ObjectMgr.GetNearestTaxiNode(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ(), unit.GetMapId(), GetPlayer().GetTeam());

            if (curloc == 0)
            {
                return;
            }

            TaxiNodesRecord from = CliDB.TaxiNodesStorage.LookupByKey(curloc);
            TaxiNodesRecord to   = CliDB.TaxiNodesStorage.LookupByKey(activateTaxi.Node);

            if (to == null)
            {
                return;
            }

            if (!GetPlayer().isTaxiCheater())
            {
                if (!GetPlayer().m_taxi.IsTaximaskNodeKnown(curloc) || !GetPlayer().m_taxi.IsTaximaskNodeKnown(activateTaxi.Node))
                {
                    SendActivateTaxiReply(ActivateTaxiReply.NotVisited);
                    return;
                }
            }

            uint        preferredMountDisplay = 0;
            MountRecord mount = CliDB.MountStorage.LookupByKey(activateTaxi.FlyingMountID);

            if (mount != null)
            {
                if (GetPlayer().HasSpell(mount.SpellId))
                {
                    var mountDisplays = Global.DB2Mgr.GetMountDisplays(mount.Id);
                    if (mountDisplays != null)
                    {
                        List <MountXDisplayRecord> usableDisplays = mountDisplays.Where(mountDisplay =>
                        {
                            PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(mountDisplay.PlayerConditionID);
                            if (playerCondition != null)
                            {
                                return(ConditionManager.IsPlayerMeetingCondition(GetPlayer(), playerCondition));
                            }

                            return(true);
                        }).ToList();

                        if (!usableDisplays.Empty())
                        {
                            preferredMountDisplay = usableDisplays.SelectRandom().DisplayID;
                        }
                    }
                }
            }

            List <uint> nodes = new List <uint>();

            Global.TaxiPathGraph.GetCompleteNodeRoute(from, to, GetPlayer(), nodes);
            GetPlayer().ActivateTaxiPathTo(nodes, unit, 0, preferredMountDisplay);
        }
Beispiel #8
0
        void HandlePetCastSpell(PetCastSpell petCastSpell)
        {
            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(petCastSpell.Cast.SpellID);

            if (spellInfo == null)
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: unknown spell id {0} tried to cast by {1}", petCastSpell.Cast.SpellID, petCastSpell.PetGUID.ToString());
                return;
            }

            Unit caster = Global.ObjAccessor.GetUnit(GetPlayer(), petCastSpell.PetGUID);

            if (!caster)
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: Caster {0} not found.", petCastSpell.PetGUID.ToString());
                return;
            }

            // This opcode is also sent from charmed and possessed units (players and creatures)
            if (caster != GetPlayer().GetGuardianPet() && caster != GetPlayer().GetCharm())
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetCastSpell: {0} isn't pet of player {1} ({2}).", petCastSpell.PetGUID.ToString(), GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
                return;
            }

            // do not cast not learned spells
            if (!caster.HasSpell(spellInfo.Id) || spellInfo.IsPassive())
            {
                return;
            }

            SpellCastTargets targets = new SpellCastTargets(caster, petCastSpell.Cast);

            caster.ClearUnitState(UnitState.Follow);

            Spell spell = new Spell(caster, spellInfo, TriggerCastFlags.None);

            spell.m_fromClient = true;
            spell.m_misc.Data0 = petCastSpell.Cast.Misc[0];
            spell.m_misc.Data1 = petCastSpell.Cast.Misc[1];
            spell.m_targets    = targets;

            SpellCastResult result = spell.CheckPetCast(null);

            if (result == SpellCastResult.SpellCastOk)
            {
                Creature creature = caster.ToCreature();
                if (creature)
                {
                    Pet pet = creature.ToPet();
                    if (pet)
                    {
                        // 10% chance to play special pet attack talk, else growl
                        // actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
                        if (pet.GetPetType() == PetType.Summon && (RandomHelper.IRand(0, 100) < 10))
                        {
                            pet.SendPetTalk(PetTalk.SpecialSpell);
                        }
                        else
                        {
                            pet.SendPetAIReaction(petCastSpell.PetGUID);
                        }
                    }
                }

                SpellPrepare spellPrepare = new SpellPrepare();
                spellPrepare.ClientCastID = petCastSpell.Cast.CastID;
                spellPrepare.ServerCastID = spell.m_castId;
                SendPacket(spellPrepare);

                spell.Prepare(targets);
            }
            else
            {
                spell.SendPetCastResult(result);

                if (!caster.GetSpellHistory().HasCooldown(spellInfo.Id))
                {
                    caster.GetSpellHistory().ResetCooldown(spellInfo.Id, true);
                }

                spell.Finish(false);
                spell.Dispose();
            }
        }
Beispiel #9
0
        void HandleAuctionRemoveItem(AuctionRemoveItem packet)
        {
            Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer, NPCFlags2.None);

            if (!creature)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionRemoveItem - {0} not found or you can't interact with him.", packet.Auctioneer.ToString());
                return;
            }

            // remove fake death
            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.GetFaction());

            AuctionEntry auction = auctionHouse.GetAuction((uint)packet.AuctionItemID);
            Player       player  = GetPlayer();

            SQLTransaction trans = new SQLTransaction();

            if (auction != null && auction.owner == player.GetGUID().GetCounter())
            {
                Item pItem = Global.AuctionMgr.GetAItem(auction.itemGUIDLow);
                if (pItem)
                {
                    if (auction.bidder > 0)                        // If we have a bidder, we have to send him the money he paid
                    {
                        ulong auctionCut = auction.GetAuctionCut();
                        if (!player.HasEnoughMoney(auctionCut))          //player doesn't have enough money, maybe message needed
                        {
                            return;
                        }
                        Global.AuctionMgr.SendAuctionCancelledToBidderMail(auction, trans);
                        player.ModifyMoney(-(long)auctionCut);
                    }

                    // item will deleted or added to received mail list
                    new MailDraft(auction.BuildAuctionMailSubject(MailAuctionAnswers.Canceled), AuctionEntry.BuildAuctionMailBody(0, 0, auction.buyout, auction.deposit, 0))
                    .AddItem(pItem)
                    .SendMailTo(trans, new MailReceiver(player), new MailSender(auction), MailCheckMask.Copied);
                }
                else
                {
                    Log.outError(LogFilter.Network, "Auction id: {0} got non existing item (item guid : {1})!", auction.Id, auction.itemGUIDLow);
                    SendAuctionCommandResult(null, AuctionAction.Cancel, AuctionError.DatabaseError);
                    return;
                }
            }
            else
            {
                SendAuctionCommandResult(null, AuctionAction.Cancel, AuctionError.DatabaseError);
                //this code isn't possible ... maybe there should be assert
                Log.outError(LogFilter.Network, "CHEATER: {0} tried to cancel auction (id: {1}) of another player or auction is null", player.GetGUID().ToString(), packet.AuctionItemID);
                return;
            }

            //inform player, that auction is removed
            SendAuctionCommandResult(auction, AuctionAction.Cancel, AuctionError.Ok);

            // Now remove the auction
            player.SaveInventoryAndGoldToDB(trans);
            auction.DeleteFromDB(trans);
            DB.Characters.CommitTransaction(trans);

            Global.AuctionMgr.RemoveAItem(auction.itemGUIDLow);
            auctionHouse.RemoveAuction(auction);
        }
Beispiel #10
0
        void HandleAuctionPlaceBid(AuctionPlaceBid packet)
        {
            if (packet.AuctionItemID == 0 || packet.BidAmount == 0)
            {
                return; // check for cheaters
            }
            Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer, NPCFlags2.None);

            if (!creature)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionPlaceBid - {0} not found or you can't interact with him.", packet.Auctioneer.ToString());
                return;
            }

            // remove fake death
            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.GetFaction());

            AuctionEntry auction = auctionHouse.GetAuction(packet.AuctionItemID);
            Player       player  = GetPlayer();

            if (auction == null || auction.owner == player.GetGUID().GetCounter())
            {
                //you cannot bid your own auction:
                SendAuctionCommandResult(null, AuctionAction.PlaceBid, AuctionError.BidOwn);
                return;
            }

            // impossible have online own another character (use this for speedup check in case online owner)
            ObjectGuid ownerGuid     = ObjectGuid.Create(HighGuid.Player, auction.owner);
            Player     auction_owner = Global.ObjAccessor.FindPlayer(ownerGuid);

            if (!auction_owner && Global.CharacterCacheStorage.GetCharacterAccountIdByGuid(ownerGuid) == player.GetSession().GetAccountId())
            {
                //you cannot bid your another character auction:
                SendAuctionCommandResult(null, AuctionAction.PlaceBid, AuctionError.BidOwn);
                return;
            }

            // cheating
            if (packet.BidAmount <= auction.bid || packet.BidAmount < auction.startbid)
            {
                return;
            }

            // price too low for next bid if not buyout
            if ((packet.BidAmount < auction.buyout || auction.buyout == 0) && packet.BidAmount < auction.bid + auction.GetAuctionOutBid())
            {
                // client already test it but just in case ...
                SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.HigherBid);
                return;
            }

            if (!player.HasEnoughMoney(packet.BidAmount))
            {
                // client already test it but just in case ...
                SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.NotEnoughtMoney);
                return;
            }

            SQLTransaction trans = new SQLTransaction();

            if (packet.BidAmount < auction.buyout || auction.buyout == 0)
            {
                if (auction.bidder > 0)
                {
                    if (auction.bidder == player.GetGUID().GetCounter())
                    {
                        player.ModifyMoney(-(long)(packet.BidAmount - auction.bid));
                    }
                    else
                    {
                        // mail to last bidder and return money
                        Global.AuctionMgr.SendAuctionOutbiddedMail(auction, packet.BidAmount, GetPlayer(), trans);
                        player.ModifyMoney(-(long)packet.BidAmount);
                    }
                }
                else
                {
                    player.ModifyMoney(-(long)packet.BidAmount);
                }

                auction.bidder = player.GetGUID().GetCounter();
                auction.bid    = (uint)packet.BidAmount;
                GetPlayer().UpdateCriteria(CriteriaTypes.HighestAuctionBid, packet.BidAmount);

                PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_AUCTION_BID);
                stmt.AddValue(0, auction.bidder);
                stmt.AddValue(1, auction.bid);
                stmt.AddValue(2, auction.Id);
                trans.Append(stmt);

                SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.Ok);

                // Not sure if we must send this now.
                Player owner = Global.ObjAccessor.FindConnectedPlayer(ObjectGuid.Create(HighGuid.Player, auction.owner));
                Item   item  = Global.AuctionMgr.GetAItem(auction.itemGUIDLow);
                if (owner && item)
                {
                    owner.GetSession().SendAuctionOwnerBidNotification(auction, item);
                }
            }
            else
            {
                //buyout:
                if (player.GetGUID().GetCounter() == auction.bidder)
                {
                    player.ModifyMoney(-(long)(auction.buyout - auction.bid));
                }
                else
                {
                    player.ModifyMoney(-(long)auction.buyout);
                    if (auction.bidder != 0)                          //buyout for bidded auction ..
                    {
                        Global.AuctionMgr.SendAuctionOutbiddedMail(auction, auction.buyout, GetPlayer(), trans);
                    }
                }
                auction.bidder = player.GetGUID().GetCounter();
                auction.bid    = auction.buyout;
                GetPlayer().UpdateCriteria(CriteriaTypes.HighestAuctionBid, auction.buyout);

                SendAuctionCommandResult(auction, AuctionAction.PlaceBid, AuctionError.Ok);

                //- Mails must be under transaction control too to prevent data loss
                Global.AuctionMgr.SendAuctionSalePendingMail(auction, trans);
                Global.AuctionMgr.SendAuctionSuccessfulMail(auction, trans);
                Global.AuctionMgr.SendAuctionWonMail(auction, trans);

                auction.DeleteFromDB(trans);

                Global.AuctionMgr.RemoveAItem(auction.itemGUIDLow);
                auctionHouse.RemoveAuction(auction);
            }

            player.SaveInventoryAndGoldToDB(trans);
            DB.Characters.CommitTransaction(trans);
        }
Beispiel #11
0
        void HandleAuctionSellItem(AuctionSellItem packet)
        {
            foreach (var aitem in packet.Items)
            {
                if (aitem.Guid.IsEmpty() || aitem.UseCount == 0 || aitem.UseCount > 1000)
                {
                    return;
                }
            }

            if (packet.MinBid == 0 || packet.RunTime == 0)
            {
                return;
            }

            if (packet.MinBid > PlayerConst.MaxMoneyAmount || packet.BuyoutPrice > PlayerConst.MaxMoneyAmount)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - Player {0} ({1}) attempted to sell item with higher price than max gold amount.", GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
                SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                return;
            }

            Creature creature = GetPlayer().GetNPCIfCanInteractWith(packet.Auctioneer, NPCFlags.Auctioneer, NPCFlags2.None);

            if (!creature)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - {0} not found or you can't interact with him.", packet.Auctioneer.ToString());
                return;
            }

            uint houseId = 0;
            AuctionHouseRecord auctionHouseEntry = Global.AuctionMgr.GetAuctionHouseEntry(creature.GetFaction(), ref houseId);

            if (auctionHouseEntry == null)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleAuctionSellItem - {0} has wrong faction.", packet.Auctioneer.ToString());
                return;
            }

            packet.RunTime *= Time.Minute;
            switch (packet.RunTime)
            {
            case 1 * SharedConst.MinAuctionTime:
            case 2 * SharedConst.MinAuctionTime:
            case 4 * SharedConst.MinAuctionTime:
                break;

            default:
                return;
            }

            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            uint finalCount = 0;

            Item[] items = new Item[packet.Items.Count];
            for (var i = 0; i < packet.Items.Count; ++i)
            {
                items[i] = GetPlayer().GetItemByGuid(packet.Items[i].Guid);
                if (!items[i])
                {
                    SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.ItemNotFound);
                    return;
                }

                if (Global.AuctionMgr.GetAItem(items[i].GetGUID().GetCounter()) || !items[i].CanBeTraded() || items[i].IsNotEmptyBag() ||
                    items[i].GetTemplate().GetFlags().HasAnyFlag(ItemFlags.Conjured) || items[i].m_itemData.Expiration != 0 ||
                    items[i].GetCount() < packet.Items[i].UseCount)
                {
                    SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                    return;
                }

                finalCount += packet.Items[i].UseCount;
            }

            if (packet.Items.Empty())
            {
                SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                return;
            }

            if (finalCount == 0)
            {
                SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                return;
            }

            // check if there are 2 identical guids, in this case user is most likely cheating
            for (int i = 0; i < packet.Items.Count; ++i)
            {
                for (int j = i + 1; j < packet.Items.Count; ++j)
                {
                    if (packet.Items[i].Guid == packet.Items[j].Guid)
                    {
                        SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                        return;
                    }
                    if (items[i].GetEntry() != items[j].GetEntry())
                    {
                        SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.ItemNotFound);
                        return;
                    }
                }
            }

            for (var i = 0; i < packet.Items.Count; ++i)
            {
                if (items[i].GetMaxStackCount() < finalCount)
                {
                    SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                    return;
                }
            }

            Item item = items[0];

            uint auctionTime = (uint)(packet.RunTime * WorldConfig.GetFloatValue(WorldCfg.RateAuctionTime));
            AuctionHouseObject auctionHouse = Global.AuctionMgr.GetAuctionsMap(creature.GetFaction());

            ulong deposit = Global.AuctionMgr.GetAuctionDeposit(auctionHouseEntry, packet.RunTime, item, finalCount);

            if (!GetPlayer().HasEnoughMoney(deposit))
            {
                SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.NotEnoughtMoney);
                return;
            }

            AuctionEntry   AH = new AuctionEntry();
            SQLTransaction trans;

            if (WorldConfig.GetBoolValue(WorldCfg.AllowTwoSideInteractionAuction))
            {
                AH.auctioneer = 23442;     //@TODO - HARDCODED DB GUID, BAD BAD BAD
            }
            else
            {
                AH.auctioneer = creature.GetSpawnId();
            }

            // Required stack size of auction matches to current item stack size, just move item to auctionhouse
            if (packet.Items.Count == 1 && item.GetCount() == packet.Items[0].UseCount)
            {
                if (HasPermission(RBACPermissions.LogGmTrade))
                {
                    Log.outCommand(GetAccountId(), "GM {0} (Account: {1}) create auction: {2} (Entry: {3} Count: {4})",
                                   GetPlayerName(), GetAccountId(), item.GetTemplate().GetName(), item.GetEntry(), item.GetCount());
                }

                AH.Id                = Global.ObjectMgr.GenerateAuctionID();
                AH.itemGUIDLow       = item.GetGUID().GetCounter();
                AH.itemEntry         = item.GetEntry();
                AH.itemCount         = item.GetCount();
                AH.owner             = GetPlayer().GetGUID().GetCounter();
                AH.startbid          = (uint)packet.MinBid;
                AH.bidder            = 0;
                AH.bid               = 0;
                AH.buyout            = (uint)packet.BuyoutPrice;
                AH.expire_time       = Time.UnixTime + auctionTime;
                AH.deposit           = deposit;
                AH.etime             = packet.RunTime;
                AH.auctionHouseEntry = auctionHouseEntry;

                Log.outInfo(LogFilter.Network, "CMSG_AUCTION_SELL_ITEM: {0} {1} is selling item {2} {3} to auctioneer {4} with count {5} with initial bid {6} with buyout {7} and with time {8} (in sec) in auctionhouse {9}",
                            GetPlayer().GetGUID().ToString(), GetPlayer().GetName(), item.GetGUID().ToString(), item.GetTemplate().GetName(), AH.auctioneer, item.GetCount(), packet.MinBid, packet.BuyoutPrice, auctionTime, AH.GetHouseId());
                Global.AuctionMgr.AddAItem(item);
                auctionHouse.AddAuction(AH);

                GetPlayer().MoveItemFromInventory(item.GetBagSlot(), item.GetSlot(), true);

                trans = new SQLTransaction();
                item.DeleteFromInventoryDB(trans);
                item.SaveToDB(trans);
                AH.SaveToDB(trans);
                GetPlayer().SaveInventoryAndGoldToDB(trans);
                DB.Characters.CommitTransaction(trans);

                SendAuctionCommandResult(AH, AuctionAction.SellItem, AuctionError.Ok);

                GetPlayer().UpdateCriteria(CriteriaTypes.CreateAuction, 1);
            }
            else // Required stack size of auction does not match to current item stack size, clone item and set correct stack size
            {
                Item newItem = item.CloneItem(finalCount, GetPlayer());
                if (!newItem)
                {
                    Log.outError(LogFilter.Network, "CMSG_AuctionAction.SellItem: Could not create clone of item {0}", item.GetEntry());
                    SendAuctionCommandResult(null, AuctionAction.SellItem, AuctionError.DatabaseError);
                    return;
                }

                if (HasPermission(RBACPermissions.LogGmTrade))
                {
                    Log.outCommand(GetAccountId(), "GM {0} (Account: {1}) create auction: {2} (Entry: {3} Count: {4})",
                                   GetPlayerName(), GetAccountId(), newItem.GetTemplate().GetName(), newItem.GetEntry(), newItem.GetCount());
                }

                AH.Id                = Global.ObjectMgr.GenerateAuctionID();
                AH.itemGUIDLow       = newItem.GetGUID().GetCounter();
                AH.itemEntry         = newItem.GetEntry();
                AH.itemCount         = newItem.GetCount();
                AH.owner             = GetPlayer().GetGUID().GetCounter();
                AH.startbid          = (uint)packet.MinBid;
                AH.bidder            = 0;
                AH.bid               = 0;
                AH.buyout            = (uint)packet.BuyoutPrice;
                AH.expire_time       = Time.UnixTime + auctionTime;
                AH.deposit           = deposit;
                AH.etime             = packet.RunTime;
                AH.auctionHouseEntry = auctionHouseEntry;

                Log.outInfo(LogFilter.Network, "CMSG_AuctionAction.SellItem: {0} {1} is selling {2} {3} to auctioneer {4} with count {5} with initial bid {6} with buyout {7} and with time {8} (in sec) in auctionhouse {9}",
                            GetPlayer().GetGUID().ToString(), GetPlayer().GetName(), newItem.GetGUID().ToString(), newItem.GetTemplate().GetName(), AH.auctioneer, newItem.GetCount(), packet.MinBid, packet.BuyoutPrice, auctionTime, AH.GetHouseId());
                Global.AuctionMgr.AddAItem(newItem);
                auctionHouse.AddAuction(AH);

                for (var i = 0; i < packet.Items.Count; ++i)
                {
                    Item item2 = items[i];

                    // Item stack count equals required count, ready to delete item - cloned item will be used for auction
                    if (item2.GetCount() == packet.Items[i].UseCount)
                    {
                        GetPlayer().MoveItemFromInventory(item2.GetBagSlot(), item2.GetSlot(), true);

                        trans = new SQLTransaction();
                        item2.DeleteFromInventoryDB(trans);
                        item2.DeleteFromDB(trans);
                        DB.Characters.CommitTransaction(trans);
                    }
                    else // Item stack count is bigger than required count, update item stack count and save to database - cloned item will be used for auction
                    {
                        item2.SetCount(item2.GetCount() - packet.Items[i].UseCount);
                        item2.SetState(ItemUpdateState.Changed, GetPlayer());
                        GetPlayer().ItemRemovedQuestCheck(item2.GetEntry(), packet.Items[i].UseCount);
                        item2.SendUpdateToPlayer(GetPlayer());

                        trans = new SQLTransaction();
                        item2.SaveToDB(trans);
                        DB.Characters.CommitTransaction(trans);
                    }
                }

                trans = new SQLTransaction();
                newItem.SaveToDB(trans);
                AH.SaveToDB(trans);
                GetPlayer().SaveInventoryAndGoldToDB(trans);
                DB.Characters.CommitTransaction(trans);

                SendAuctionCommandResult(AH, AuctionAction.SellItem, AuctionError.Ok);

                GetPlayer().UpdateCriteria(CriteriaTypes.CreateAuction, 1);
            }

            GetPlayer().ModifyMoney(-(long)deposit);
        }
Beispiel #12
0
        public void SendListInventory(ObjectGuid vendorGuid)
        {
            Creature vendor = GetPlayer().GetNPCIfCanInteractWith(vendorGuid, NPCFlags.Vendor, NPCFlags2.None);

            if (vendor == null)
            {
                Log.outDebug(LogFilter.Network, "WORLD: SendListInventory - {0} not found or you can not interact with him.", vendorGuid.ToString());
                GetPlayer().SendSellError(SellResult.CantFindVendor, null, ObjectGuid.Empty);
                return;
            }

            // remove fake death
            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            // Stop the npc if moving
            vendor.PauseMovement(WorldConfig.GetUIntValue(WorldCfg.CreatureStopForPlayer));
            vendor.SetHomePosition(vendor.GetPosition());

            VendorItemData vendorItems  = vendor.GetVendorItems();
            int            rawItemCount = vendorItems != null?vendorItems.GetItemCount() : 0;

            VendorInventory packet = new();

            packet.Vendor = vendor.GetGUID();

            float discountMod = GetPlayer().GetReputationPriceDiscount(vendor);
            byte  count       = 0;

            for (uint slot = 0; slot < rawItemCount; ++slot)
            {
                VendorItem vendorItem = vendorItems.GetItem(slot);
                if (vendorItem == null)
                {
                    continue;
                }

                VendorItemPkt item = new();

                PlayerConditionRecord playerCondition = CliDB.PlayerConditionStorage.LookupByKey(vendorItem.PlayerConditionId);
                if (playerCondition != null)
                {
                    if (!ConditionManager.IsPlayerMeetingCondition(_player, playerCondition))
                    {
                        item.PlayerConditionFailed = (int)playerCondition.Id;
                    }
                }

                if (vendorItem.Type == ItemVendorType.Item)
                {
                    ItemTemplate itemTemplate = Global.ObjectMgr.GetItemTemplate(vendorItem.item);
                    if (itemTemplate == null)
                    {
                        continue;
                    }

                    int leftInStock = vendorItem.maxcount == 0 ? -1 : (int)vendor.GetVendorItemCurrentCount(vendorItem);
                    if (!GetPlayer().IsGameMaster())
                    {
                        if (!Convert.ToBoolean(itemTemplate.GetAllowableClass() & GetPlayer().GetClassMask()) && itemTemplate.GetBonding() == ItemBondingType.OnAcquire)
                        {
                            continue;
                        }

                        if ((itemTemplate.GetFlags2().HasAnyFlag(ItemFlags2.FactionHorde) && GetPlayer().GetTeam() == Team.Alliance) ||
                            (itemTemplate.GetFlags2().HasAnyFlag(ItemFlags2.FactionAlliance) && GetPlayer().GetTeam() == Team.Horde))
                        {
                            continue;
                        }

                        if (leftInStock == 0)
                        {
                            continue;
                        }
                    }

                    if (!Global.ConditionMgr.IsObjectMeetingVendorItemConditions(vendor.GetEntry(), vendorItem.item, _player, vendor))
                    {
                        Log.outDebug(LogFilter.Condition, "SendListInventory: conditions not met for creature entry {0} item {1}", vendor.GetEntry(), vendorItem.item);
                        continue;
                    }

                    int price = (int)(vendorItem.IsGoldRequired(itemTemplate) ? Math.Floor(itemTemplate.GetBuyPrice() * discountMod) : 0);

                    int priceMod = GetPlayer().GetTotalAuraModifier(AuraType.ModVendorItemsPrices);
                    if (priceMod != 0)
                    {
                        price -= MathFunctions.CalculatePct(price, priceMod);
                    }

                    item.MuID                = (int)slot + 1;
                    item.Durability          = (int)itemTemplate.MaxDurability;
                    item.ExtendedCostID      = (int)vendorItem.ExtendedCost;
                    item.Type                = (int)vendorItem.Type;
                    item.Quantity            = leftInStock;
                    item.StackCount          = (int)itemTemplate.GetBuyCount();
                    item.Price               = (ulong)price;
                    item.DoNotFilterOnVendor = vendorItem.IgnoreFiltering;
                    item.Refundable          = (itemTemplate.GetFlags() & ItemFlags.ItemPurchaseRecord) != 0 && vendorItem.ExtendedCost != 0 && itemTemplate.GetMaxStackSize() == 1;

                    item.Item.ItemID = vendorItem.item;
                    if (!vendorItem.BonusListIDs.Empty())
                    {
                        item.Item.ItemBonus.HasValue           = true;
                        item.Item.ItemBonus.Value.BonusListIDs = vendorItem.BonusListIDs;
                    }

                    packet.Items.Add(item);
                }
                else if (vendorItem.Type == ItemVendorType.Currency)
                {
                    CurrencyTypesRecord currencyTemplate = CliDB.CurrencyTypesStorage.LookupByKey(vendorItem.item);
                    if (currencyTemplate == null)
                    {
                        continue;
                    }

                    if (vendorItem.ExtendedCost == 0)
                    {
                        continue;                             // there's no price defined for currencies, only extendedcost is used
                    }
                    item.MuID                = (int)slot + 1; // client expects counting to start at 1
                    item.ExtendedCostID      = (int)vendorItem.ExtendedCost;
                    item.Item.ItemID         = vendorItem.item;
                    item.Type                = (int)vendorItem.Type;
                    item.StackCount          = (int)vendorItem.maxcount;
                    item.DoNotFilterOnVendor = vendorItem.IgnoreFiltering;

                    packet.Items.Add(item);
                }
                else
                {
                    continue;
                }

                if (++count >= SharedConst.MaxVendorItems)
                {
                    break;
                }
            }

            SendPacket(packet);
        }
Beispiel #13
0
        void HandleGossipSelectOption(GossipSelectOption packet)
        {
            if (GetPlayer().PlayerTalkClass.GetGossipMenu().GetItem(packet.GossipIndex) == null)
            {
                return;
            }

            // Prevent cheating on C# scripted menus
            if (GetPlayer().PlayerTalkClass.GetInteractionData().SourceGuid != packet.GossipUnit)
            {
                return;
            }

            Creature   unit = null;
            GameObject go   = null;

            if (packet.GossipUnit.IsCreatureOrVehicle())
            {
                unit = GetPlayer().GetNPCIfCanInteractWith(packet.GossipUnit, NPCFlags.Gossip, NPCFlags2.None);
                if (unit == null)
                {
                    Log.outDebug(LogFilter.Network, "WORLD: HandleGossipSelectOption - {0} not found or you can't interact with him.", packet.GossipUnit.ToString());
                    return;
                }
            }
            else if (packet.GossipUnit.IsGameObject())
            {
                go = GetPlayer().GetGameObjectIfCanInteractWith(packet.GossipUnit);
                if (go == null)
                {
                    Log.outDebug(LogFilter.Network, "WORLD: HandleGossipSelectOption - {0} not found or you can't interact with it.", packet.GossipUnit.ToString());
                    return;
                }
            }
            else
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleGossipSelectOption - unsupported {0}.", packet.GossipUnit.ToString());
                return;
            }

            // remove fake death
            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            if ((unit && unit.GetScriptId() != unit.LastUsedScriptID) || (go != null && go.GetScriptId() != go.LastUsedScriptID))
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleGossipSelectOption - Script reloaded while in use, ignoring and set new scipt id");
                if (unit != null)
                {
                    unit.LastUsedScriptID = unit.GetScriptId();
                }

                if (go != null)
                {
                    go.LastUsedScriptID = go.GetScriptId();
                }
                GetPlayer().PlayerTalkClass.SendCloseGossip();
                return;
            }
            if (!string.IsNullOrEmpty(packet.PromotionCode))
            {
                if (unit != null)
                {
                    if (!unit.GetAI().GossipSelectCode(_player, packet.GossipID, packet.GossipIndex, packet.PromotionCode))
                    {
                        GetPlayer().OnGossipSelect(unit, packet.GossipIndex, packet.GossipID);
                    }
                }
                else
                {
                    if (!go.GetAI().GossipSelectCode(_player, packet.GossipID, packet.GossipIndex, packet.PromotionCode))
                    {
                        _player.OnGossipSelect(go, packet.GossipIndex, packet.GossipID);
                    }
                }
            }
            else
            {
                if (unit != null)
                {
                    if (!unit.GetAI().GossipSelect(_player, packet.GossipID, packet.GossipIndex))
                    {
                        GetPlayer().OnGossipSelect(unit, packet.GossipIndex, packet.GossipID);
                    }
                }
                else
                {
                    if (!go.GetAI().GossipSelect(_player, packet.GossipID, packet.GossipIndex))
                    {
                        GetPlayer().OnGossipSelect(go, packet.GossipIndex, packet.GossipID);
                    }
                }
            }
        }