예제 #1
0
        public void SendTaxiMenu(Creature unit)
        {
            // find current node
            uint curloc = Global.ObjectMgr.GetNearestTaxiNode(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ(), unit.GetMapId(), GetPlayer().GetTeam());

            if (curloc == 0)
            {
                return;
            }

            bool lastTaxiCheaterState = GetPlayer().isTaxiCheater();

            if (unit.GetEntry() == 29480)
            {
                GetPlayer().SetTaxiCheater(true); // Grimwing in Ebon Hold, special case. NOTE: Not perfect, Zul'Aman should not be included according to WoWhead, and I think taxicheat includes it.
            }
            ShowTaxiNodes data = new ShowTaxiNodes();

            data.WindowInfo.HasValue          = true;
            data.WindowInfo.Value.UnitGUID    = unit.GetGUID();
            data.WindowInfo.Value.CurrentNode = (int)curloc;

            GetPlayer().m_taxi.AppendTaximaskTo(data, lastTaxiCheaterState);

            SendPacket(data);

            GetPlayer().SetTaxiCheater(lastTaxiCheaterState);
        }
예제 #2
0
        public bool SendLearnNewTaxiNode(Creature unit)
        {
            // find current node
            uint curloc = Global.ObjectMgr.GetNearestTaxiNode(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ(), unit.GetMapId(), GetPlayer().GetTeam());

            if (curloc == 0)
            {
                return(true);
            }

            if (GetPlayer().m_taxi.SetTaximaskNode(curloc))
            {
                SendPacket(new NewTaxiPath());

                TaxiNodeStatusPkt data = new TaxiNodeStatusPkt();
                data.Unit   = unit.GetGUID();
                data.Status = TaxiNodeStatus.Learned;
                SendPacket(data);

                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #3
0
        void SendSound(Creature source, uint sound, ChatMsg msgType, WorldObject whisperTarget = null, CreatureTextRange range = CreatureTextRange.Normal, Team team = Team.Other, bool gmOnly = false)
        {
            if (sound == 0 || !source)
                return;

            SendNonChatPacket(source, new PlaySound(source.GetGUID(), sound), msgType, whisperTarget, range, team, gmOnly);
        }
예제 #4
0
        public void SendSound(Creature source, uint sound, ChatMsg msgType, WorldObject whisperTarget = null, CreatureTextRange range = CreatureTextRange.Normal, Team team = Team.Other, bool gmOnly = false, uint keyBroadcastTextId = 0, SoundKitPlayType playType = SoundKitPlayType.Normal)
        {
            if (sound == 0 || !source)
            {
                return;
            }

            if (playType == SoundKitPlayType.ObjectSound)
            {
                PlayObjectSound pkt = new();
                pkt.TargetObjectGUID = whisperTarget.GetGUID();
                pkt.SourceObjectGUID = source.GetGUID();
                pkt.SoundKitID       = sound;
                pkt.Position         = whisperTarget.GetWorldLocation();
                pkt.BroadcastTextID  = (int)keyBroadcastTextId;
                SendNonChatPacket(source, pkt, msgType, whisperTarget, range, team, gmOnly);
            }
            else if (playType == SoundKitPlayType.Normal)
            {
                SendNonChatPacket(source, new PlaySound(source.GetGUID(), sound, keyBroadcastTextId), msgType, whisperTarget, range, team, gmOnly);
            }
        }
예제 #5
0
        void HandleGossipHello(Hello packet)
        {
            Creature unit = GetPlayer().GetNPCIfCanInteractWith(packet.Unit, NPCFlags.Gossip);

            if (unit == null)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleGossipHello - {0} not found or you can not interact with him.", packet.Unit.ToString());
                return;
            }

            // set faction visible if needed
            var factionTemplateEntry = CliDB.FactionTemplateStorage.LookupByKey(unit.getFaction());

            if (factionTemplateEntry != null)
            {
                GetPlayer().GetReputationMgr().SetVisible(factionTemplateEntry);
            }

            GetPlayer().RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Talk);

            if (unit.IsArmorer() || unit.IsCivilian() || unit.IsQuestGiver() || unit.IsServiceProvider() || unit.IsGuard())
            {
                unit.StopMoving();
            }

            // If spiritguide, no need for gossip menu, just put player into resurrect queue
            if (unit.IsSpiritGuide())
            {
                Battleground bg = GetPlayer().GetBattleground();
                if (bg)
                {
                    bg.AddPlayerToResurrectQueue(unit.GetGUID(), GetPlayer().GetGUID());
                    Global.BattlegroundMgr.SendAreaSpiritHealerQuery(GetPlayer(), bg, unit.GetGUID());
                    return;
                }
            }

            if (!Global.ScriptMgr.OnGossipHello(GetPlayer(), unit))
            {
                GetPlayer().PrepareGossipMenu(unit, unit.GetCreatureTemplate().GossipMenuId, true);
                GetPlayer().SendPreparedGossip(unit);
            }
            unit.GetAI().sGossipHello(GetPlayer());
        }
예제 #6
0
        void HandleGossipHello(Hello packet)
        {
            Creature unit = GetPlayer().GetNPCIfCanInteractWith(packet.Unit, NPCFlags.Gossip, NPCFlags2.None);

            if (unit == null)
            {
                Log.outDebug(LogFilter.Network, "WORLD: HandleGossipHello - {0} not found or you can not interact with him.", packet.Unit.ToString());
                return;
            }

            // set faction visible if needed
            var factionTemplateEntry = CliDB.FactionTemplateStorage.LookupByKey(unit.GetFaction());

            if (factionTemplateEntry != null)
            {
                GetPlayer().GetReputationMgr().SetVisible(factionTemplateEntry);
            }

            GetPlayer().RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags.Interacting);

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

            // If spiritguide, no need for gossip menu, just put player into resurrect queue
            if (unit.IsSpiritGuide())
            {
                Battleground bg = GetPlayer().GetBattleground();
                if (bg)
                {
                    bg.AddPlayerToResurrectQueue(unit.GetGUID(), GetPlayer().GetGUID());
                    Global.BattlegroundMgr.SendAreaSpiritHealerQuery(GetPlayer(), bg, unit.GetGUID());
                    return;
                }
            }

            _player.PlayerTalkClass.ClearMenus();
            if (!unit.GetAI().GossipHello(_player))
            {
                GetPlayer().PrepareGossipMenu(unit, unit.GetCreatureTemplate().GossipMenuId, true);
                GetPlayer().SendPreparedGossip(unit);
            }
        }
예제 #7
0
        public void SendTrainerList(Creature npc, uint trainerId)
        {
            // remove fake death
            if (GetPlayer().HasUnitState(UnitState.Died))
            {
                GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
            }

            Trainer trainer = Global.ObjectMgr.GetTrainer(trainerId);

            if (trainer == null)
            {
                Log.outDebug(LogFilter.Network, $"WORLD: SendTrainerList - trainer spells not found for trainer {npc.GetGUID().ToString()} id {trainerId}");
                return;
            }

            _player.PlayerTalkClass.GetInteractionData().Reset();
            _player.PlayerTalkClass.GetInteractionData().SourceGuid = npc.GetGUID();
            _player.PlayerTalkClass.GetInteractionData().TrainerId  = trainerId;
            trainer.SendSpells(npc, _player, GetSessionDbLocaleIndex());
        }
예제 #8
0
        void HandlePetAbandon(PetAbandon packet)
        {
            if (!GetPlayer().IsInWorld)
            {
                return;
            }

            Creature pet = ObjectAccessor.GetCreatureOrPetOrVehicle(GetPlayer(), packet.Pet);

            if (pet)
            {
                if (pet.IsPet())
                {
                    GetPlayer().RemovePet(pet.ToPet(), PetSaveMode.AsDeleted);
                }
                else if (pet.GetGUID() == GetPlayer().GetCharmGUID())
                {
                    GetPlayer().StopCastingCharm();
                }
            }
        }
예제 #9
0
        public void SendTaxiMenu(Creature unit)
        {
            // find current node
            uint curloc = Global.ObjectMgr.GetNearestTaxiNode(unit.GetPositionX(), unit.GetPositionY(), unit.GetPositionZ(), unit.GetMapId(), GetPlayer().GetTeam());

            if (curloc == 0)
            {
                return;
            }

            bool lastTaxiCheaterState = GetPlayer().isTaxiCheater();

            if (unit.GetEntry() == 29480)
            {
                GetPlayer().SetTaxiCheater(true); // Grimwing in Ebon Hold, special case. NOTE: Not perfect, Zul'Aman should not be included according to WoWhead, and I think taxicheat includes it.
            }
            ShowTaxiNodes data = new ShowTaxiNodes();

            data.WindowInfo.HasValue          = true;
            data.WindowInfo.Value.UnitGUID    = unit.GetGUID();
            data.WindowInfo.Value.CurrentNode = (int)curloc;

            GetPlayer().m_taxi.AppendTaximaskTo(data, lastTaxiCheaterState);

            byte[] reachableNodes = new byte[PlayerConst.TaxiMaskSize];
            Global.TaxiPathGraph.GetReachableNodesMask(CliDB.TaxiNodesStorage.LookupByKey(curloc), reachableNodes);
            for (var i = 0; i < PlayerConst.TaxiMaskSize; ++i)
            {
                data.CanLandNodes[i] &= reachableNodes[i];
                data.CanUseNodes[i]  &= reachableNodes[i];
            }


            SendPacket(data);

            GetPlayer().SetTaxiCheater(lastTaxiCheaterState);
        }
예제 #10
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 => 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.SoundEntriesID[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);
        }
예제 #11
0
        public void SendListInventory(ObjectGuid vendorGuid)
        {
            Creature vendor = GetPlayer().GetNPCIfCanInteractWith(vendorGuid, NPCFlags.Vendor);

            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
            if (vendor.HasUnitState(UnitState.Moving))
            {
                vendor.StopMoving();
            }

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

            VendorInventory packet = new VendorInventory();

            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 VendorItemPkt();

                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.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);
        }
예제 #12
0
        void HandlePetSpellAutocast(PetSpellAutocast packet)
        {
            Creature pet = ObjectAccessor.GetCreatureOrPetOrVehicle(GetPlayer(), packet.PetGUID);

            if (!pet)
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocast: {0} not found.", packet.PetGUID.ToString());
                return;
            }

            if (pet != GetPlayer().GetGuardianPet() && pet != GetPlayer().GetCharm())
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocast: {0} isn't pet of player {1} ({2}).",
                             packet.PetGUID.ToString(), GetPlayer().GetName(), GetPlayer().GetGUID().ToString());
                return;
            }

            SpellInfo spellInfo = Global.SpellMgr.GetSpellInfo(packet.SpellID);

            if (spellInfo == null)
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocast: Unknown spell id {0} used by {1}.", packet.SpellID, packet.PetGUID.ToString());
                return;
            }

            // do not add not learned spells/ passive spells
            if (!pet.HasSpell(packet.SpellID) || !spellInfo.IsAutocastable())
            {
                return;
            }

            CharmInfo charmInfo = pet.GetCharmInfo();

            if (charmInfo == null)
            {
                Log.outError(LogFilter.Network, "WorldSession.HandlePetSpellAutocastOpcod: object {0} is considered pet-like but doesn't have a charminfo!", pet.GetGUID().ToString());
                return;
            }

            if (pet.IsPet())
            {
                pet.ToPet().ToggleAutocast(spellInfo, packet.AutocastEnabled);
            }
            else
            {
                charmInfo.ToggleCreatureAutocast(spellInfo, packet.AutocastEnabled);
            }

            charmInfo.SetSpellAutocast(spellInfo, packet.AutocastEnabled);
        }