Ejemplo n.º 1
0
        private void HandleGameAction(QueuedGameAction action, Player player)
        {
            switch (action.ActionType)
            {
            case GameActionType.TalkDirect:
            {
                // TODO: remove this hack (using TalkDirect) ASAP
                var         g   = new ObjectGuid(action.ObjectId);
                WorldObject obj = (WorldObject)player;
                if (worldObjects.ContainsKey(g))
                {
                    obj = worldObjects[g];
                }
                DeathMessageArgs d = new DeathMessageArgs(action.ActionBroadcastMessage, new ObjectGuid(action.ObjectId), new ObjectGuid(action.SecondaryObjectId));
                HandleDeathMessage(obj, d);
                break;
            }

            case GameActionType.TeleToHouse:
            case GameActionType.TeleToLifestone:
            case GameActionType.TeleToMansion:
            case GameActionType.TeleToMarketPlace:
            case GameActionType.TeleToPkArena:
            case GameActionType.TeleToPklArena:
            {
                player.Teleport(action.ActionLocation);
                break;
            }

            case GameActionType.ApplyVisualEffect:
            {
                var         g   = new ObjectGuid(action.ObjectId);
                WorldObject obj = (WorldObject)player;
                if (worldObjects.ContainsKey(g))
                {
                    obj = worldObjects[g];
                }
                var particleEffect = (PlayScript)action.SecondaryObjectId;
                HandleParticleEffectEvent(obj, particleEffect);
                break;
            }

            case GameActionType.ApplySoundEffect:
            {
                var         g   = new ObjectGuid(action.ObjectId);
                WorldObject obj = (WorldObject)player;
                if (worldObjects.ContainsKey(g))
                {
                    obj = worldObjects[g];
                }
                var soundEffect = (Sound)action.SecondaryObjectId;
                HandleSoundEvent(obj, soundEffect);
                break;
            }

            case GameActionType.PutItemInContainer:
            {
                var playerId    = new ObjectGuid(action.ObjectId);
                var inventoryId = new ObjectGuid(action.SecondaryObjectId);
                if (playerId.IsPlayer())
                {
                    Player      aPlayer       = null;
                    WorldObject inventoryItem = null;

                    if (worldObjects.ContainsKey(playerId) && worldObjects.ContainsKey(inventoryId))
                    {
                        aPlayer       = (Player)worldObjects[playerId];
                        inventoryItem = worldObjects[inventoryId];
                    }

                    if ((aPlayer != null) && (inventoryItem != null))
                    {
                        var motion = new GeneralMotion(MotionStance.Standing);
                        motion.MovementData.ForwardCommand = (ushort)MotionCommand.Pickup;
                        aPlayer.Session.Network.EnqueueSend(new GameMessageUpdatePosition(aPlayer),
                                                            new GameMessageUpdateMotion(aPlayer, aPlayer.Session, motion),
                                                            new GameMessageSound(aPlayer.Guid, Sound.PickUpItem, (float)1.0));

                        // Add to the inventory list.
                        aPlayer.AddToInventory(inventoryItem);
                        LandblockManager.RemoveObject(inventoryItem);

                        motion = new GeneralMotion(MotionStance.Standing);
                        aPlayer.Session.Network.EnqueueSend(new GameMessagePrivateUpdatePropertyInt(aPlayer.Session,
                                                                                                    PropertyInt.EncumbVal,
                                                                                                    aPlayer.GameData.Burden),
                                                            new GameMessagePutObjectInContainer(aPlayer.Session, aPlayer, inventoryId),
                                                            new GameMessageUpdateMotion(aPlayer, aPlayer.Session, motion),
                                                            new GameMessageUpdateInstanceId(inventoryId, playerId),
                                                            new GameMessagePickupEvent(aPlayer.Session, inventoryItem));

                        aPlayer.TrackObject(inventoryItem);
                    }
                }
                break;
            }

            case GameActionType.DropItem:
            {
                var g = new ObjectGuid(action.ObjectId);
                // ReSharper disable once InconsistentlySynchronizedField
                if (worldObjects.ContainsKey(g))
                {
                    var playerId    = new ObjectGuid(action.ObjectId);
                    var inventoryId = new ObjectGuid(action.SecondaryObjectId);
                    if (playerId.IsPlayer())
                    {
                        Player      aPlayer       = null;
                        WorldObject inventoryItem = null;

                        if (worldObjects.ContainsKey(playerId))
                        {
                            aPlayer       = (Player)worldObjects[playerId];
                            inventoryItem = aPlayer.GetInventoryItem(inventoryId);
                            aPlayer.RemoveFromInventory(inventoryId);
                        }

                        if ((aPlayer != null) && (inventoryItem != null))
                        {
                            var targetContainer = new ObjectGuid(0);
                            aPlayer.Session.Network.EnqueueSend(
                                new GameMessagePrivateUpdatePropertyInt(
                                    aPlayer.Session,
                                    PropertyInt.EncumbVal,
                                    (uint)aPlayer.Session.Player.GameData.Burden));

                            var motion = new GeneralMotion(MotionStance.Standing);
                            motion.MovementData.ForwardCommand = (ushort)MotionCommand.Pickup;
                            aPlayer.Session.Network.EnqueueSend(
                                new GameMessageUpdateMotion(aPlayer, aPlayer.Session, motion),
                                new GameMessageUpdateInstanceId(inventoryId, targetContainer));

                            motion = new GeneralMotion(MotionStance.Standing);
                            aPlayer.Session.Network.EnqueueSend(
                                new GameMessageUpdateMotion(aPlayer, aPlayer.Session, motion),
                                new GameMessagePutObjectIn3d(aPlayer.Session, aPlayer, inventoryId),
                                new GameMessageSound(aPlayer.Guid, Sound.DropItem, (float)1.0),
                                new GameMessageUpdateInstanceId(inventoryId, targetContainer));

                            // This is the sequence magic - adds back into 3d space seem to be treated like teleport.
                            inventoryItem.Sequences.GetNextSequence(SequenceType.ObjectTeleport);
                            inventoryItem.Sequences.GetNextSequence(SequenceType.ObjectVector);
                            LandblockManager.AddObject(inventoryItem);
                            aPlayer.Session.Network.EnqueueSend(new GameMessageUpdatePosition(inventoryItem));
                        }
                    }
                }
                break;
            }

            case GameActionType.MovementEvent:
            {
                var         g   = new ObjectGuid(action.ObjectId);
                WorldObject obj = (WorldObject)player;
                if (worldObjects.ContainsKey(g))
                {
                    obj = worldObjects[g];
                }
                var motion = action.Motion;
                HandleMovementEvent(obj, motion);
                break;
            }

            case GameActionType.ObjectCreate:
            {
                this.AddWorldObject(action.WorldObject);
                break;
            }

            case GameActionType.ObjectDelete:
            {
                this.RemoveWorldObject(action.WorldObject.Guid, false);
                break;
            }

            case GameActionType.QueryHealth:
            {
                if (action.ObjectId == 0)
                {
                    // Deselect the formerly selected Target
                    player.SelectedTarget = 0;
                    break;
                }

                object target   = null;
                var    targetId = new ObjectGuid(action.ObjectId);

                // Remember the selected Target
                player.SelectedTarget = action.ObjectId;

                // TODO: once items are implemented check if there are items that can trigger
                //       the QueryHealth event. So far I believe it only gets triggered for players and creatures
                if (targetId.IsPlayer() || targetId.IsCreature())
                {
                    if (this.worldObjects.ContainsKey(targetId))
                    {
                        target = this.worldObjects[targetId];
                    }

                    if (target == null)
                    {
                        // check adjacent landblocks for the targetId
                        foreach (var block in adjacencies)
                        {
                            if (block.Value != null)
                            {
                                if (block.Value.worldObjects.ContainsKey(targetId))
                                {
                                    target = block.Value.worldObjects[targetId];
                                }
                            }
                        }
                    }
                    if (target != null)
                    {
                        float healthPercentage = 0;

                        if (targetId.IsPlayer())
                        {
                            Player tmpTarget = (Player)target;
                            healthPercentage = (float)tmpTarget.Health.Current / (float)tmpTarget.Health.MaxValue;
                        }
                        if (targetId.IsCreature())
                        {
                            Creature tmpTarget = (Creature)target;
                            healthPercentage = (float)tmpTarget.Health.Current / (float)tmpTarget.Health.MaxValue;
                        }
                        var updateHealth = new GameEventUpdateHealth(player.Session, targetId.Full, healthPercentage);
                        player.Session.Network.EnqueueSend(updateHealth);
                    }
                }

                break;
            }

            case GameActionType.Use:
            {
                var g = new ObjectGuid(action.ObjectId);
                if (worldObjects.ContainsKey(g))
                {
                    WorldObject obj = worldObjects[g];

                    switch (obj.Type)
                    {
                    case Enum.ObjectType.Portal:
                    {
                        // validate within use range :: set to a fixed value as static Portals are normally OnCollide usage
                        float rangeCheck = 5.0f;

                        if (player.Location.SquaredDistanceTo(obj.Location) < rangeCheck)
                        {
                            PortalDestination portalDestination = DatabaseManager.World.GetPortalDestination(obj.WeenieClassid);

                            if (portalDestination != null)
                            {
                                player.Session.Player.Teleport(portalDestination.Position);
                                // always send useDone event
                                var sendUseDoneEvent = new GameEventUseDone(player.Session);
                                player.Session.Network.EnqueueSend(sendUseDoneEvent);
                            }
                            else
                            {
                                string serverMessage    = "Portal destination for portal ID " + obj.WeenieClassid + " not yet implemented!";
                                var    usePortalMessage = new GameMessageSystemChat(serverMessage, ChatMessageType.System);
                                // always send useDone event
                                var sendUseDoneEvent = new GameEventUseDone(player.Session);
                                player.Session.Network.EnqueueSend(usePortalMessage, sendUseDoneEvent);
                            }
                        }
                        else
                        {
                            // always send useDone event
                            var sendUseDoneEvent = new GameEventUseDone(player.Session);
                            player.Session.Network.EnqueueSend(sendUseDoneEvent);
                        }

                        break;
                    }

                    case Enum.ObjectType.LifeStone:
                    {
                        string serverMessage = null;
                        // validate within use range
                        float radiusSquared = obj.GameData.UseRadius * obj.GameData.UseRadius;

                        var motionSanctuary = new GeneralMotion(MotionStance.Standing, new MotionItem(MotionCommand.Sanctuary));

                        var animationEvent = new GameMessageUpdateMotion(player, player.Session, motionSanctuary);

                        // This event was present for a pcap in the training dungeon.. Why? The sound comes with animationEvent...
                        var soundEvent = new GameMessageSound(obj.Guid, Sound.LifestoneOn, 1);

                        if (player.Location.SquaredDistanceTo(obj.Location) >= radiusSquared)
                        {
                            serverMessage = "You wandered too far to attune with the Lifestone!";
                        }
                        else
                        {
                            player.SetCharacterPosition(PositionType.Sanctuary, player.Location);

                            // create the outbound server message
                            serverMessage = "You have attuned your spirit to this Lifestone. You will resurrect here after you die.";
                            player.EnqueueMovementEvent(motionSanctuary, player.Guid);
                            player.Session.Network.EnqueueSend(soundEvent);
                        }

                        var lifestoneBindMessage = new GameMessageSystemChat(serverMessage, ChatMessageType.Magic);
                        // always send useDone event
                        var sendUseDoneEvent = new GameEventUseDone(player.Session);
                        player.Session.Network.EnqueueSend(lifestoneBindMessage, sendUseDoneEvent);

                        break;
                    }
                    }
                }
                break;
            }
            }
        }
Ejemplo n.º 2
0
        public override void OnCollide(Player player)
        {
            // validate within use range :: set to a fixed value as static Portals are normally OnCollide usage
            float rangeCheck = 5.0f;

            if (player.Location.SquaredDistanceTo(this.Location) < rangeCheck)
            {
                PortalDestination portalDestination = DatabaseManager.World.GetPortalDestination(this.WeenieClassid);

                if (portalDestination != null)
                {
                    if ((player.Level >= portalDestination.MinLvl) && ((player.Level <= portalDestination.MaxLvl) || (portalDestination.MaxLvl == 0)))
                    {
                        Position portalDest = portalDestination.Position;
                        switch (this.WeenieClassid)
                        {
                        /// <summary>
                        /// Setup correct racial portal destination for the Central Courtyard in the Training Academy
                        /// </summary>
                        case (ushort)SpecialPortalWCID.CentralCourtyard:
                        {
                            uint playerLandblockId = player.Location.LandblockId.Raw;
                            switch (playerLandblockId)
                            {
                            case (uint)SpecialPortalLandblockID.ShoushiCCLaunch:                // Shoushi
                            {
                                portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.ShoushiCCLanding);
                                break;
                            }

                            case (uint)SpecialPortalLandblockID.YaraqCCLaunch:                // Yaraq
                            {
                                portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.YaraqCCLanding);
                                break;
                            }

                            case (uint)SpecialPortalLandblockID.SanamarCCLaunch:                // Sanamar
                            {
                                portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.SanamarCCLanding);
                                break;
                            }

                            default:                        // Holtburg
                            {
                                portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.HoltburgCCLanding);
                                break;
                            }
                            }

                            portalDest.PositionX = portalDestination.PosX;
                            portalDest.PositionY = portalDestination.PosY;
                            portalDest.PositionZ = portalDestination.PosZ;
                            portalDest.RotationX = portalDestination.QX;
                            portalDest.RotationY = portalDestination.QY;
                            portalDest.RotationZ = portalDestination.QZ;
                            portalDest.RotationW = portalDestination.QW;
                            break;
                        }

                        /// <summary>
                        /// Setup correct racial portal destination for the Outer Courtyard in the Training Academy
                        /// </summary>
                        case (ushort)SpecialPortalWCID.OuterCourtyard:
                        {
                            uint playerLandblockId = player.Location.LandblockId.Raw;
                            switch (playerLandblockId)
                            {
                            case (uint)SpecialPortalLandblockID.ShoushiOCLaunch:                // Shoushi
                            {
                                portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.ShoushiOCLanding);
                                break;
                            }

                            case (uint)SpecialPortalLandblockID.YaraqOCLaunch:                // Yaraq
                            {
                                portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.YaraqOCLanding);
                                break;
                            }

                            case (uint)SpecialPortalLandblockID.SanamarOCLaunch:                // Sanamar
                            {
                                portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.SanamarOCLanding);
                                break;
                            }

                            default:                        // Holtburg
                            {
                                portalDest.LandblockId = new LandblockId((uint)SpecialPortalLandblockID.HoltburgOCLanding);
                                break;
                            }
                            }

                            portalDest.PositionX = portalDestination.PosX;
                            portalDest.PositionY = portalDestination.PosY;
                            portalDest.PositionZ = portalDestination.PosZ;
                            portalDest.RotationX = portalDestination.QX;
                            portalDest.RotationY = portalDestination.QY;
                            portalDest.RotationZ = portalDestination.QZ;
                            portalDest.RotationW = portalDestination.QW;
                            break;
                        }

                        /// <summary>
                        /// All other portals don't need adjustments.
                        /// </summary>
                        default:
                        {
                            break;
                        }
                        }

                        player.Session.Player.Teleport(portalDest);
                        // always send useDone event
                        var sendUseDoneEvent = new GameEventUseDone(player.Session);
                        player.Session.Network.EnqueueSend(sendUseDoneEvent);
                    }
                    else if ((player.Level > portalDestination.MaxLvl) && (portalDestination.MaxLvl != 0))
                    {
                        // You are too powerful to interact with that portal!
                        var usePortalMessage = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_04AC);
                        // always send useDone event
                        var sendUseDoneEvent = new GameEventUseDone(player.Session);
                        player.Session.Network.EnqueueSend(usePortalMessage, sendUseDoneEvent);
                    }
                    else
                    {
                        // You are not powerful enough to interact with that portal!
                        var usePortalMessage = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_04AB);
                        // always send useDone event
                        var sendUseDoneEvent = new GameEventUseDone(player.Session);
                        player.Session.Network.EnqueueSend(usePortalMessage, sendUseDoneEvent);
                    }
                }
                else
                {
                    string serverMessage    = "Portal destination for portal ID " + this.WeenieClassid + " not yet implemented!";
                    var    usePortalMessage = new GameMessageSystemChat(serverMessage, ChatMessageType.System);
                    // always send useDone event
                    var sendUseDoneEvent = new GameEventUseDone(player.Session);
                    player.Session.Network.EnqueueSend(usePortalMessage, sendUseDoneEvent);
                }
            }
            else
            {
                // always send useDone event
                var sendUseDoneEvent = new GameEventUseDone(player.Session);
                player.Session.Network.EnqueueSend(sendUseDoneEvent);
            }
        }