Пример #1
0
        //private static readonly MotionState motionStateOpen = new UniversalMotion(MotionStance.Standing, new MotionItem(MotionCommand.On));
        //private static readonly MotionState motionStateClosed = new UniversalMotion(MotionStance.Standing, new MotionItem(MotionCommand.Off));

        /// <summary>
        /// This is raised by Player.HandleActionUseItem, and is wrapped in ActionChain.<para />
        /// The actor of the ActionChain is the item being used.<para />
        /// The item does not exist in the players possession.<para />
        /// If the item was outside of range, the player will have been commanded to move using DoMoveTo before ActOnUse is called.<para />
        /// When this is called, it should be assumed that the player is within range.
        /// </summary>
        public override void ActOnUse(WorldObject worldObject)
        {
            if (worldObject is Player)
            {
                var player = worldObject as Player;
                ////if (playerDistanceTo >= 2500)
                ////{
                ////    var sendTooFarMsg = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_0037);
                ////    player.Session.Network.EnqueueSend(sendTooFarMsg, sendUseDoneEvent);
                ////    return;
                ////}

                if (!(IsLocked ?? false))
                {
                    if (!(IsOpen ?? false))
                    {
                        var turnToMotion = new UniversalMotion(MotionStance.Standing, Location, Guid);
                        turnToMotion.MovementTypes = MovementTypes.TurnToObject;

                        ActionChain turnToTimer = new ActionChain();
                        turnToTimer.AddAction(this, () => player.CurrentLandblock.EnqueueBroadcastMotion(player, turnToMotion));
                        turnToTimer.AddDelaySeconds(1);
                        turnToTimer.AddAction(this, () => Open(player));
                        turnToTimer.EnqueueChain();

                        return;
                    }

                    if (Viewer == player.Guid.Full)
                    {
                        Close(player);
                    }

                    // else error msg?
                }
                else
                {
                    CurrentLandblock.EnqueueBroadcastSound(this, Sound.OpenFailDueToLock);
                }

                player.SendUseDoneEvent();
            }
        }
Пример #2
0
        // Called by the Landblock for books that are WorldObjects (some notes pinned to the ground, statues, pedestals and tips in training academy, etc
        public override void ActOnUse(ObjectGuid playerId)
        {
            Player player = CurrentLandblock.GetObject(playerId) as Player;

            if (player == null)
            {
                return;
            }

            // Make sure player is within the use radius of the item.
            if (!player.IsWithinUseRadiusOf(this))
            {
                player.DoMoveTo(this);
            }
            else
            {
                BookUseHandler(player.Session);
            }
        }
Пример #3
0
        /// <summary>
        ///  Sends object description if the client requests it
        /// </summary>
        /// <param name="item"></param>
        public void HandleActionForceObjDescSend(ObjectGuid item)
        {
            ActionChain objDescChain = new ActionChain();

            objDescChain.AddAction(this, () =>
            {
                WorldObject wo = GetInventoryItem(item);
                if (wo != null)
                {
                    CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange,
                                                      new GameMessageObjDescEvent(wo));
                }
                else
                {
                    log.Debug($"Error - requested object description for an item I do not know about - {item.Full:X}");
                }
            });
            objDescChain.EnqueueChain();
        }
Пример #4
0
        /// <summary>
        /// Called by network packet handler 0xA - GameActionTargetedMissileAttack
        /// </summary>
        /// <param name="guid">The target guid</param>
        /// <param name="attackHeight">The attack height 1-3</param>
        /// <param name="accuracyLevel">The 0-1 accuracy bar level</param>
        public void HandleActionTargetedMissileAttack(ObjectGuid guid, uint attackHeight, float accuracyLevel)
        {
            var weapon = GetEquippedMissileWeapon();
            var ammo   = GetEquippedAmmo();

            // sanity check
            accuracyLevel = Math.Clamp(accuracyLevel, 0.0f, 1.0f);

            if (weapon == null || weapon.IsAmmoLauncher && ammo == null)
            {
                return;
            }

            AttackHeight  = (AttackHeight)attackHeight;
            AccuracyLevel = accuracyLevel;

            // get world object of target guid
            var target = CurrentLandblock?.GetObject(guid);

            if (target == null)
            {
                log.Warn("Unknown target guid " + guid.Full.ToString("X8"));
                return;
            }
            if (MissileTarget == null)
            {
                MissileTarget = target;
            }
            else
            {
                return;
            }

            // turn if required
            var rotateTime  = Rotate(target);
            var actionChain = new ActionChain();

            actionChain.AddDelaySeconds(rotateTime);

            // do missile attack
            actionChain.AddAction(this, () => LaunchMissile(target));
            actionChain.EnqueueChain();
        }
Пример #5
0
        public override void HandleActionOnUse(ObjectGuid playerId)
        {
            ActionChain chain = new ActionChain();

            CurrentLandblock.ChainOnObject(chain, playerId, (WorldObject wo) =>
            {
                Player player = wo as Player;
                if (player == null)
                {
                    return;
                }

                ////if (playerDistanceTo >= 2500)
                ////{
                ////    var sendTooFarMsg = new GameEventDisplayStatusMessage(player.Session, StatusMessageType1.Enum_0037);
                ////    player.Session.Network.EnqueueSend(sendTooFarMsg, sendUseDoneEvent);
                ////    return;
                ////}

                if (!player.IsWithinUseRadiusOf(this))
                {
                    player.DoMoveTo(this);
                }
                else
                {
                    ActionChain useObjectChain = new ActionChain();

                    useObjectChain.AddAction(this, () =>
                    {
                        if (AllowedActivator == null)
                        {
                            Activate(playerId);
                        }

                        var sendUseDoneEvent = new GameEventUseDone(player.Session);
                        player.Session.Network.EnqueueSend(sendUseDoneEvent);
                    });

                    useObjectChain.EnqueueChain();
                }
            });
            chain.EnqueueChain();
        }
Пример #6
0
        /// <summary>
        /// Launches a missile attack from player to target
        /// </summary>
        public void LaunchMissile(WorldObject target)
        {
            if (GetEquippedAmmo() == null || CombatMode == CombatMode.NonCombat)
            {
                return;
            }

            var creature = target as Creature;

            if (MissileTarget == null || creature.Health.Current <= 0)
            {
                MissileTarget = null;
                return;
            }

            var weapon = GetEquippedWeapon();
            var sound  = weapon.DefaultCombatStyle == CombatStyle.Crossbow ? Sound.CrossbowRelease : Sound.BowRelease;

            CurrentLandblock.EnqueueBroadcast(Location, new GameMessageSound(Guid, sound, 1.0f));

            float targetTime   = 0.0f;
            var   damageSource = LaunchProjectile(target, out targetTime);

            // todo: get correct animlengths for shoot + reload + aim
            var animLength = ReloadMotion() * 2.5f;

            var actionChain = new ActionChain();

            //actionChain.AddDelaySeconds(targetTime);
            //actionChain.AddAction(this, () => DamageTarget(target, damageSource));

            if (creature.Health.Current > 0 && GetCharacterOption(CharacterOption.AutoRepeatAttacks))
            {
                // reload animation, accuracy bar refill
                actionChain.AddDelaySeconds(animLength + AccuracyLevel);
                actionChain.AddAction(this, () => { LaunchMissile(target); });
                actionChain.EnqueueChain();
            }
            else
            {
                MissileTarget = null;
            }
        }
Пример #7
0
        private void Activate(ObjectGuid activator = new ObjectGuid())
        {
            AllowedActivator = activator.Full;

            CurrentLandblock?.EnqueueBroadcastMotion(this, motionTipRight);

            // Stamp Cow tipping quest here;

            ActionChain autoResetTimer = new ActionChain();

            autoResetTimer.AddDelaySeconds(4);
            autoResetTimer.AddAction(this, () => ResetCow());
            autoResetTimer.EnqueueChain();

            if (activator.Full > 0)
            {
                UseTimestamp++;
            }
        }
Пример #8
0
        /// <summary>
        ///  Learns spells in bulk, without notification, filtered by school and level
        /// </summary>
        public void LearnSpellsInBulk(uint magicSchool, uint spellLevel)
        {
            var    spells = DatManager.PortalDat.SpellTable.Spells;
            Player player = CurrentLandblock.GetObject(Guid) as Player;

            if (Enum.IsDefined(typeof(SpellLevel), (int)WorldObject.CalculateSpellLevel(spellLevel)))
            {
                foreach (var spell in spells)
                {
                    if ((magicSchool == (uint)spell.Value.School) & ((uint)WorldObject.CalculateSpellLevel(spellLevel) == spell.Value.Power))
                    {
                        if (Enum.IsDefined(typeof(Network.Enum.Spell), spell.Key))
                        {
                            player.LearnSpellWithNetworking((uint)spell.Key, false);
                        }
                    }
                }
            }
        }
Пример #9
0
        /// <summary>
        /// Fired when Client clicks on the Vendor World Object
        /// </summary>
        /// <param name="playerId"></param>
        public override void ActOnUse(ObjectGuid playerId)
        {
            Player player = CurrentLandblock.GetObject(playerId) as Player;

            if (player == null)
            {
                return;
            }

            if (!player.IsWithinUseRadiusOf(this))
            {
                player.DoMoveTo(this);
            }
            else
            {
                LoadInventory();
                ApproachVendor(player);
            }
        }
Пример #10
0
        /// <summary>
        /// This method will remove a worldobject if we have consumed all of the amount in the merge.
        /// This checks inventory or wielded items (you could be pulling stackable ammo out of a wielded slot and into a stack in your pack
        /// It then creates and sends the remove object message.   Lastly, if the wo has ever been saved to the db, we clean up after ourselves.
        /// </summary>
        /// <param name="session">Session is used for sequence and target</param>
        /// <param name="fromWo">World object of the item are we merging from that needs to be destroyed.</param>
        public void RemoveWorldObject(Session session, WorldObject fromWo)
        {
            if (HasItem(fromWo.Guid))
            {
                session.Player.RemoveWorldObjectFromInventory(fromWo.Guid);
            }
            else
            {
                session.Player.RemoveFromWieldedObjects(fromWo.Guid);
            }
            GameMessageRemoveObject msgRemoveFrom = new GameMessageRemoveObject(fromWo);

            CurrentLandblock.EnqueueBroadcast(Location, MaxObjectTrackingRange, msgRemoveFrom);

            if (fromWo.SnapShotOfAceObject().HasEverBeenSavedToDatabase)
            {
                DatabaseManager.Shard.DeleteObject(fromWo.SnapShotOfAceObject(), null);
            }
        }
Пример #11
0
        public override void OnCollideEnvironment()
        {
            if (!PhysicsObj.is_active())
            {
                return;
            }

            //Console.WriteLine("Projectile.OnCollideEnvironment(" + Guid.Full.ToString("X8") + ")");

            CurrentLandblock.RemoveWorldObject(Guid, false);
            PhysicsObj.set_active(false);

            var player = ProjectileSource as Player;

            if (player != null)
            {
                player.Session.Network.EnqueueSend(new GameMessageSystemChat("Your missile attack hit the environment.", ChatMessageType.Broadcast));
            }
        }
Пример #12
0
        public virtual void ActivateLinks(List <LandblockInstance> sourceObjects)
        {
            if (LinkedInstances.Count == 0)
            {
                return;
            }

            if (IsGenerator)
            {
                AddGeneratorLinks();
                return;
            }

            foreach (var link in LinkedInstances)
            {
                var wo = WorldObjectFactory.CreateWorldObject(DatabaseManager.World.GetCachedWeenie(link.WeenieClassId), new ObjectGuid(link.Guid));
                if (wo == null)
                {
                    continue;
                }

                wo.Location         = new Position(link.ObjCellId, link.OriginX, link.OriginY, link.OriginZ, link.AnglesX, link.AnglesY, link.AnglesZ, link.AnglesW);
                wo.ActivationTarget = Guid.Full;
                CurrentLandblock?.AddWorldObject(wo);

                // process nested links recursively
                foreach (var subLink in link.LandblockInstanceLink)
                {
                    var linkInstance = sourceObjects.FirstOrDefault(x => x.Guid == subLink.ChildGuid);

                    if (linkInstance != null)
                    {
                        wo.LinkedInstances.Add(linkInstance);
                    }
                }

                if (wo.LinkedInstances.Count > 0)
                {
                    wo.ActivateLinks(sourceObjects);
                }
            }
        }
Пример #13
0
        /// <summary>
        /// Handles player targeted casting message
        /// </summary>
        public void HandleActionCastTargetedSpell(ObjectGuid guidTarget, uint spellId)
        {
            Player         player         = CurrentLandblock.GetObject(Guid) as Player;
            WorldObject    target         = CurrentLandblock.GetObject(guidTarget) as WorldObject;
            TargetCategory targetCategory = TargetCategory.WorldObject;

            if (guidTarget == Guid)
            {
                targetCategory = TargetCategory.Self;
            }
            if (target == null)
            {
                target         = GetWieldedItem(guidTarget);
                targetCategory = TargetCategory.Wielded;
            }
            if (target == null)
            {
                target         = GetInventoryItem(guidTarget);
                targetCategory = TargetCategory.Inventory;
            }
            if (target == null)
            {
                player.Session.Network.EnqueueSend(new GameEventUseDone(player.Session, errorType: WeenieError.TargetNotAcquired));
                targetCategory = TargetCategory.UnDef;
                return;
            }

            if (targetCategory != TargetCategory.WorldObject)
            {
                CreatePlayerSpell(guidTarget, spellId);
            }
            else
            {
                // turn if required
                var rotateTime  = Rotate(target) - 0.25f;
                var actionChain = new ActionChain();
                actionChain.AddDelaySeconds(rotateTime);

                actionChain.AddAction(this, () => CreatePlayerSpell(guidTarget, spellId));
                actionChain.EnqueueChain();
            }
        }
Пример #14
0
        /// <summary>
        /// This is raised by Player.HandleActionUseItem.<para />
        /// The item does not exist in the players possession.<para />
        /// If the item was outside of range, the player will have been commanded to move using DoMoveTo before ActOnUse is called.<para />
        /// When this is called, it should be assumed that the player is within range.
        /// </summary>
        public override void ActOnUse(WorldObject wo)
        {
            if (!(wo is Player player))
            {
                return;
            }

            // If we have a previous container open, let's close it
            if (player.LastOpenedContainerId != ObjectGuid.Invalid && player.LastOpenedContainerId != Guid)
            {
                var lastOpenedContainer = CurrentLandblock?.GetObject(player.LastOpenedContainerId) as Container;

                if (lastOpenedContainer != null && lastOpenedContainer.IsOpen && lastOpenedContainer.Viewer == player.Guid.Full)
                {
                    lastOpenedContainer.Close(player);
                }
            }

            if ((OwnerId.HasValue && OwnerId.Value > 0) || (ContainerId.HasValue && ContainerId.Value > 0))
            {
                return; // Do nothing else if container is owned by something.
            }
            if (!IsOpen)
            {
                Open(player);
            }
            else
            {
                if (Viewer == 0)
                {
                    Close(null);
                }
                else if (Viewer == player.Guid.Full)
                {
                    Close(player);
                }
                else
                {
                    player.SendTransientError(InUseMessage);
                }
            }
        }
Пример #15
0
        /// <summary>
        /// This is raised by Player.HandleActionUseItem.<para />
        /// The item does not exist in the players possession.<para />
        /// If the item was outside of range, the player will have been commanded to move using DoMoveTo before ActOnUse is called.<para />
        /// When this is called, it should be assumed that the player is within range.
        /// </summary>
        public override void ActOnUse(WorldObject wo)
        {
            if (!(wo is Player player))
            {
                return;
            }

            // If we have a previous container open, let's close it
            if (player.LastOpenedContainerId != ObjectGuid.Invalid && player.LastOpenedContainerId != Guid)
            {
                var lastOpenedContainer = CurrentLandblock?.GetObject(player.LastOpenedContainerId) as Container;

                if (lastOpenedContainer != null && lastOpenedContainer.IsOpen && lastOpenedContainer.Viewer == player.Guid.Full)
                {
                    lastOpenedContainer.Close(player);
                }
            }

            if ((OwnerId.HasValue && OwnerId.Value > 0) || (ContainerId.HasValue && ContainerId.Value > 0))
            {
                return; // Do nothing else if container is owned by something.
            }
            if (!IsOpen)
            {
                Open(player);
            }
            else
            {
                if (Viewer == 0)
                {
                    Close(null);
                }
                else if (Viewer == player.Guid.Full)
                {
                    Close(player);
                }
                else
                {
                    player.Session.Network.EnqueueSend(new GameEventCommunicationTransientString(player.Session, $"The {Name} is already in use by someone else!"));
                }
            }
        }
Пример #16
0
        public void HandleActionQueryHealth(ObjectGuid queryId)
        {
            if (queryId.Full == 0)
            {
                // Deselect the formerly selected Target
                selectedTarget    = ObjectGuid.Invalid;
                HealthQueryTarget = null;
                return;
            }

            // Remember the selected Target
            selectedTarget    = queryId;
            HealthQueryTarget = queryId.Full;
            var obj = CurrentLandblock.GetObject(queryId);

            if (obj != null)
            {
                obj.QueryHealth(Session);
            }
        }
Пример #17
0
        /// <summary>
        /// This will remove the Wielder and CurrentWieldedLocation properties on the item and will remove it from the EquippedObjects dictionary.<para />
        /// It does not add it to inventory as you could be unwielding to the ground or a chest. Og II<para />
        /// It will also decrease the EncumbranceVal and Value.
        /// </summary>
        public bool TryDequipObject(ObjectGuid objectGuid, out WorldObject worldObject)
        {
            if (EquippedObjects.Remove(objectGuid, out worldObject))
            {
                worldObject.RemoveProperty(PropertyInt.CurrentWieldedLocation);
                worldObject.RemoveProperty(PropertyInstanceId.Wielder);

                EncumbranceVal -= worldObject.EncumbranceVal;
                Value          -= worldObject.Value;

                if (CurrentLandblock != null)
                {
                    CurrentLandblock.EnqueueActionBroadcast(Location, Landblock.MaxObjectRange, (Player p) => p.TrackObject(this));
                }

                return(true);
            }

            return(false);
        }
Пример #18
0
        /*public AceObject SnapShotOfAceObject(bool clearDirtyFlags = false)
         * {
         *  AceObject snapshot = (AceObject)AceObject.Clone();
         *  if (clearDirtyFlags)
         *      AceObject.ClearDirtyFlags();
         *  return snapshot;
         * }*/


        public virtual void ActOnUse(ObjectGuid playerId)
        {
            // Do Nothing by default
            if (CurrentLandblock != null)
            {
                Player player = CurrentLandblock.GetObject(playerId) as Player;
                if (player == null)
                {
                    return;
                }

#if DEBUG
                var errorMessage = new GameMessageSystemChat($"Default HandleActionOnUse reached, this object ({Name}) not programmed yet.", ChatMessageType.System);
                player.Session.Network.EnqueueSend(errorMessage);
#endif

                var sendUseDoneEvent = new GameEventUseDone(player.Session);
                player.Session.Network.EnqueueSend(sendUseDoneEvent);
            }
        }
Пример #19
0
        /// <summary>
        /// This method is called if we unwield missle ammo.   It will check to see if I have arrows wielded
        /// send the message to "hide" the arrow.
        /// </summary>
        /// <param name="oldCombatMode"></param>
        public void HandleUnloadMissileAmmo(CombatMode oldCombatMode)
        {
            // Before I can switch to any non missile mode, do I have missile ammo I need to remove?
            WorldObject ammo         = null;
            HeldItem    mEquipedAmmo = Children.Find(s => s.EquipMask == EquipMask.MissileAmmo);

            if (mEquipedAmmo != null)
            {
                ammo = GetInventoryItem(new ObjectGuid(mEquipedAmmo.Guid));
            }

            if (oldCombatMode == CombatMode.Missile)
            {
                if (ammo != null)
                {
                    ammo.Location = null;
                    CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessagePickupEvent(ammo));
                }
            }
        }
Пример #20
0
        /// <summary>
        /// This method sets us into peace mode.   It checks our current state to see if we have missle ammo equipped
        /// it will make the call to hid the "ammo" as we switch to peace mode.   It will then send the message switch our stance. Og II
        /// </summary>
        /// <param name="oldCombatMode"></param>
        /// <param name="isAutonomous"></param>
        public void HandleSwitchToPeaceMode(CombatMode oldCombatMode, bool isAutonomous = false)
        {
            HandleUnloadMissileAmmo(oldCombatMode);

            // FIXME: (Og II)<this is a hack for now to be removed.> Placement has an issue we have not figured out.   It has to do with animation frame. Og II
            PositionFlag &= ~UpdatePositionFlag.Placement;
            // End hack
            CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessageUpdatePosition(this));
            UniversalMotion mm = new UniversalMotion(MotionStance.Standing);

            mm.MovementData.CurrentStyle = (uint)MotionStance.Standing;
            SetMotionState(this, mm);
            var mEquipedAmmo = WieldedObjects.FirstOrDefault(s => s.Value.CurrentWieldedLocation == EquipMask.MissileAmmo).Value;

            CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectRange, new GameMessagePrivateUpdatePropertyInt(Sequences, PropertyInt.CombatMode, (uint)CombatMode.NonCombat));
            if (mEquipedAmmo != null)
            {
                CurrentLandblock.EnqueueBroadcast(Location, Landblock.MaxObjectGhostRange, new GameMessagePickupEvent(mEquipedAmmo));
            }
        }
Пример #21
0
        public void HandleActionQueryHealth(uint objectGuid)
        {
            if (objectGuid == 0)
            {
                // Deselect the formerly selected Target
                selectedTarget    = ObjectGuid.Invalid;
                HealthQueryTarget = null;
                return;
            }

            // Remember the selected Target
            selectedTarget    = new ObjectGuid(objectGuid);
            HealthQueryTarget = objectGuid;
            var obj = CurrentLandblock?.GetObject(objectGuid);

            if (obj != null)
            {
                obj.QueryHealth(Session);
            }
        }
Пример #22
0
        public override void ActOnUse(ObjectGuid playerId)
        {
            var player = CurrentLandblock.GetObject(playerId) as Player;

            if (player == null)
            {
                return;
            }

            if (!player.IsWithinUseRadiusOf(this))
            {
                player.DoMoveTo(this);
            }
            else
            {
                ActionChain sancTimer = new ActionChain();
                sancTimer.AddAction(player, () =>
                {
                    CurrentLandblock.EnqueueBroadcastMotion(player, sanctuary);
                    CurrentLandblock.EnqueueBroadcastSound(player, Sound.LifestoneOn, 1);
                });
                sancTimer.AddDelaySeconds(DatManager.PortalDat.ReadFromDat <MotionTable>(player.MotionTableId).GetAnimationLength(MotionCommand.Sanctuary));
                sancTimer.AddAction(player, () =>
                {
                    if (player.IsWithinUseRadiusOf(this))
                    {
                        player.Session.Network.EnqueueSend(new GameMessageSystemChat(GetProperty(PropertyString.UseMessage), ChatMessageType.Magic));
                        player.Sanctuary = player.Location;
                    }
                    // Unsure if there was a fail message...
                    //else
                    //{
                    //    var serverMessage = "You wandered too far to attune with the Lifestone!";
                    //    player.Session.Network.EnqueueSend(new GameMessageSystemChat(serverMessage, ChatMessageType.Magic));
                    //}

                    player.SendUseDoneEvent();
                });
                sancTimer.EnqueueChain();
            }
        }
Пример #23
0
        /// <summary>
        /// Launches a missile attack from monster to target
        /// </summary>
        public void RangeAttack()
        {
            var dist = GetDistanceToTarget();

            //Console.WriteLine("RangeAttack: " + dist);

            NextAttackTime = Timer.CurrentTime + MissileDelay;

            var weapon = GetEquippedWeapon();
            var sound  = weapon.DefaultCombatStyle == CombatStyle.Crossbow ? Sound.CrossbowRelease : Sound.BowRelease;

            CurrentLandblock.EnqueueBroadcast(Location, new GameMessageSound(Guid, sound, 1.0f));

            var player   = AttackTarget as Player;
            var bodyPart = GetBodyPart();

            float targetTime   = 0.0f;
            var   damageSource = LaunchProjectile(AttackTarget, out targetTime);
            var   animLength   = ReloadMotion();

            var actionChain = new ActionChain();

            actionChain.AddDelaySeconds(targetTime);
            actionChain.AddAction(this, () =>
            {
                var critical   = false;
                var damageType = DamageType.Undef;
                var damage     = CalculateDamage(ref damageType, bodyPart, ref critical);

                if (damage > 0.0f)
                {
                    player.TakeDamage(this, damageType, damage, bodyPart, critical);
                }
                else
                {
                    player.Session.Network.EnqueueSend(new GameMessageSystemChat($"You evaded {Name}!", ChatMessageType.CombatEnemy));
                }
            });

            actionChain.EnqueueChain();
        }
Пример #24
0
        // FIXME(ddevec): I broke vendors -- I need to think about how to reimplement this cleanly
        public override void OnUse(ObjectGuid playerId)
        {
            ActionChain chain = new ActionChain();

            CurrentLandblock.ChainOnObject(chain, playerId, (WorldObject wo) =>
            {
                Player player = wo as Player;
                if (player == null)
                {
                    return;
                }

                string serverMessage = null;
                // validate within use range, taking into account the radius of the model itself, as well
                SetupModel csetup   = SetupModel.ReadFromDat(PhysicsData.CSetup);
                float radiusSquared = (GameData.UseRadius + csetup.Radius) * (GameData.UseRadius + csetup.Radius);

                // We're static, so this is safe -- our Location is never written
                if (player.Location.SquaredDistanceTo(Location) >= radiusSquared)
                {
                    serverMessage = "Your way to far away to trust, come closer and buy something or leave me alone!";
                }
                else
                {
                    // create the outbound server message
                    serverMessage = "You Break it, you bought it!";
                }

                // give player starting money
                var money = new GameMessagePrivateUpdatePropertyInt(player.Session, PropertyInt.CoinValue, 5000);
                player.Session.Network.EnqueueSend(money);

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

                player.Session.Network.EnqueueSend(new GameEventApproachVendor(player.Session, Guid));
            });
            chain.EnqueueChain();
        }
Пример #25
0
        public void MoveTo(WorldObject target, float runRate = 1.0f)
        {
            if (this is Player)
            {
                return;
            }

            var motion = new UniversalMotion(CurrentMotionState.Stance, target.Location, target.Guid);

            motion.MovementTypes    = MovementTypes.MoveToObject;
            motion.Flag            |= MovementParams.CanCharge | MovementParams.FailWalk | MovementParams.UseFinalHeading | MovementParams.Sticky | MovementParams.MoveAway;
            motion.WalkRunThreshold = 1.0f;
            motion.RunRate          = runRate;

            CurrentMotionState = motion;

            if (CurrentLandblock != null)
            {
                CurrentLandblock.EnqueueBroadcastMotion(this, motion);
            }
        }
Пример #26
0
        /// <summary>
        /// Perform the melee attack swing animation
        /// </summary>
        public virtual ActionChain DoSwingMotion(WorldObject target, out float animLength)
        {
            var swingAnimation = new MotionItem(GetSwingAnimation(), 1.25f);

            animLength = MotionTable.GetAnimationLength(MotionTableId, CurrentMotionState.Stance, swingAnimation);

            var motion = new UniversalMotion(CurrentMotionState.Stance, swingAnimation);

            motion.MovementData.CurrentStyle = (uint)CurrentMotionState.Stance;
            motion.MovementData.TurnSpeed    = 2.25f;
            motion.HasTarget   = true;
            motion.TargetGuid  = target.Guid;
            CurrentMotionState = motion;

            if (CurrentLandblock != null)
            {
                CurrentLandblock.EnqueueBroadcastMotion(this, motion);
            }

            return(null);
        }
Пример #27
0
        public void HandleActionTeleToMarketPlace()
        {
            var updateCombatMode = new GameMessagePrivateUpdatePropertyInt(this, PropertyInt.CombatMode, (int)CombatMode.NonCombat);

            CurrentLandblock.EnqueueBroadcastSystemChat(this, $"{Name} is recalling to the marketplace.", ChatMessageType.Recall);
            Session.Network.EnqueueSend(updateCombatMode); // this should be handled by a different thing, probably a function that forces player into peacemode
            CurrentLandblock.EnqueueBroadcastMotion(this, motionMarketplaceRecall);

            // TODO: (OptimShi): Actual animation length is longer than in retail. 18.4s
            // float mpAnimationLength = MotionTable.GetAnimationLength((uint)MotionTableId, MotionCommand.MarketplaceRecall);
            // mpChain.AddDelaySeconds(mpAnimationLength);
            ActionChain mpChain = new ActionChain();

            mpChain.AddDelaySeconds(14);

            // Then do teleport
            mpChain.AddChain(GetTeleportChain(MarketplaceDrop));

            // Set the chain to run
            mpChain.EnqueueChain();
        }
Пример #28
0
        /// <summary>
        /// This will set the CurrentWieldedLocation property to wieldedLocation and the Wielder property to this guid and will add it to the EquippedObjects dictionary.<para />
        /// It will also increase the EncumbranceVal and Value.
        /// </summary>
        public bool TryEquipObject(WorldObject worldObject, int wieldedLocation)
        {
            if (!WieldedLocationIsAvailable(wieldedLocation))
            {
                return(false);
            }

            worldObject.CurrentWieldedLocation = (EquipMask)wieldedLocation;
            worldObject.WielderId             = Biota.Id;
            EquippedObjects[worldObject.Guid] = worldObject;

            EncumbranceVal += worldObject.EncumbranceVal;
            Value          += worldObject.Value;

            if (CurrentLandblock != null)
            {
                CurrentLandblock.EnqueueActionBroadcast(Location, Landblock.MaxObjectRange, (Player p) => p.TrackObject(this));
            }

            return(true);
        }
Пример #29
0
 /// <summary>
 /// Called when the Player's stamina has recently changed to 0
 /// </summary>
 public void OnExhausted()
 {
     // adjust player speed if running
     if (CurrentMotionCommand == (uint)MotionCommand.RunForward)
     {
         var motion = new UniversalMotion(CurrentMotionState.Stance);
         // this should be autonomous, like retail, but if it's set to autonomous here, the desired effect doesn't happen
         // motion.IsAutonomous = true;
         motion.MovementData = new MovementData()
         {
             CurrentStyle   = (uint)CurrentMotionState.Stance,
             ForwardCommand = (uint)MotionCommand.RunForward
         };
         CurrentMotionState = motion;
         if (CurrentLandblock != null)
         {
             CurrentLandblock?.EnqueueBroadcastMotion(this, motion);
         }
     }
     Session.Network.EnqueueSend(new GameEventCommunicationTransientString(Session, "You're Exhausted!"));
 }
Пример #30
0
        /// <summary>
        /// This is the OnUse method.   This is just an initial implemention.   I have put in the turn to action at this point.
        /// If we are out of use radius, move to the object.   Once in range, let's turn the creature toward us and get started.
        /// Note - we may need to make an NPC class vs monster as using a monster does not make them turn towrad you as I recall. Og II
        ///  Also, once we are reading in the emotes table by weenie - this will automatically customize the behavior for creatures.
        /// </summary>
        /// <param name="playerId">Identity of the player we are interacting with</param>
        public override void ActOnUse(ObjectGuid playerId)
        {
            Player player = CurrentLandblock.GetObject(playerId) as Player;

            if (player == null)
            {
                return;
            }

            if (!player.IsWithinUseRadiusOf(this))
            {
                player.DoMoveTo(this);
            }
            else
            {
                OnAutonomousMove(player.Location, this.Sequences, MovementTypes.TurnToObject, playerId);

                GameEventUseDone sendUseDoneEvent = new GameEventUseDone(player.Session);
                player.Session.Network.EnqueueSend(sendUseDoneEvent);
            }
        }