public static Character SpawnMobFromTemplate(
            string hash,
            Identity playfieldIdentity,
            Coordinate coord,
            Quaternion heading,
            IController controller,
            int desiredLevel = -1)
        {
            Character mobCharacter = null;

            DBMobTemplate mob = MobTemplateDao.Instance.GetMobTemplateByHash(hash);

            if (mob != null)
            {
                int level = desiredLevel;
                if (level == -1)
                {
                    // Get random inside level range
                    Random rnd = new Random();
                    level = mob.MinLvl + rnd.Next(mob.MaxLvl - mob.MinLvl);
                }
                else
                {
                    // Put it inside level range
                    level = (level < mob.MinLvl ? mob.MinLvl : level);
                    level = level > mob.MaxLvl ? mob.MaxLvl : level;
                }
                mobCharacter = CreateMob(mob, playfieldIdentity, coord, heading, controller, level);
            }
            return(mobCharacter);
        }
        /// <summary>
        /// </summary>
        /// <param name="moveType">
        /// </param>
        /// <param name="newCoordinates">
        /// </param>
        /// <param name="heading">
        /// </param>
        /// <returns>
        /// </returns>
        /// <exception cref="NotImplementedException">
        /// </exception>
        public bool Move(int moveType, Coordinate newCoordinates, Quaternion heading)
        {
            // Procedure:
            // 1. Check if new coordinates are plausible (in range of runspeed since last update)
            // 2. Set coordinates & heading

            // Is this correct? Shouldnt the client input be compared to the prediction and then be overridden to prevent teleportation exploits?
            // - Algorithman

            // give it a bit uncertainty (2.0f)
            LogUtil.Debug(
                DebugInfoDetail.Movement,
                newCoordinates.ToString() + "<->" + this.Character.Coordinates().ToString());
            // if (newCoordinates.Distance2D(this.Character.Coordinates) < 2.0f)
            {
                this.Character.SetCoordinates(newCoordinates, heading);
                this.Character.UpdateMoveType((byte)moveType);
            }

            /*
             * else
             * {
             *  this.Character.StopMovement();
             * }
             */
            return(true);
        }
Example #3
0
        public void StartPatrolling()
        {
            Waypoint next = this.FindNextWaypoint();

            // If a suitable waypoint is found
            if (next != null)
            {
                if (next.Running)
                {
                    this.Run();
                }
                else
                {
                    this.Walk();
                }
                this.followCoordinates = next.Position;
                Vector3 temp = this.Character.Coordinates().coordinate - next.Position;
                temp.y = 0;
                this.Character.Heading = (Quaternion)Quaternion.GenerateRotationFromDirectionVector(temp).Normalize();
                LogUtil.Debug(DebugInfoDetail.Movement, "Direction: " + this.Character.Heading.ToString());
                FollowTargetMessageHandler.Default.Send(
                    this.Character,
                    this.Character.Coordinates().coordinate,
                    next.Position);
                this.StartMovement();
                LogUtil.Debug(DebugInfoDetail.Movement, "Walking to: " + this.followCoordinates);
            }
        }
Example #4
0
        public void MoveTo(SmokeLounge.AOtomation.Messaging.GameData.Vector3 destination)
        {
            FollowTargetMessageHandler.Default.Send(this.Character, this.Character.RawCoordinates, destination);
            Vector3 dest  = destination;
            Vector3 start = this.Character.RawCoordinates;

            dest = start - dest;
            dest = dest.Normalize();
            this.Character.Heading = (Quaternion)Quaternion.GenerateRotationFromDirectionVector(dest);
            this.Run();

            Coordinate c = new Coordinate(destination);

            this.followCoordinates = c.coordinate;

            /*bool arrived = false;
             * double lastDistance = double.MaxValue;
             * while (!arrived)
             * {
             *  Coordinate temp = this.Character.Coordinates;
             *  double distance = this.Character.Coordinates.Distance2D(c);
             *  arrived = (distance < 0.2f) || (lastDistance < distance);
             *  lastDistance = distance;
             *  // LogUtil.Debug(DebugInfoDetail.Movement,"Moving...");
             *  Thread.Sleep(100);
             * }
             * LogUtil.Debug(DebugInfoDetail.Movement, "Arrived at "+this.Character.Coordinates.ToString());
             * this.StopMovement();*/
        }
Example #5
0
        public void DoFollow()
        {
            Coordinate sourceCoord    = this.Character.Coordinates();
            Vector3    targetPosition = this.followCoordinates;

            if (!this.followIdentity.Equals(Identity.None))
            {
                ICharacter targetChar = Pool.Instance.GetObject <ICharacter>(
                    this.Character.Playfield.Identity,
                    this.followIdentity);
                if (targetChar == null)
                {
                    // If target does not longer exist (death or zone or logoff) then stop following
                    this.followIdentity    = Identity.None;
                    this.followCoordinates = new Vector3();
                    return;
                }

                targetPosition = targetChar.Coordinates().coordinate;
            }

            // Do we have coordinates to follow?
            if (targetPosition.Distance2D(new Vector3()) < 0.01f)
            {
                return;
            }

            // /!\ If target flies away, there has to be some kind of adjustment
            Vector3 start = sourceCoord.coordinate;
            Vector3 dest  = targetPosition;

            // Check if we have arrived
            if (start.Distance2D(dest) < 0.3f)
            {
                this.StopMovement();
                this.Character.RawCoordinates = dest;
                FollowTargetMessageHandler.Default.Send(this.Character, dest);
                this.followCoordinates = new Vector3();
                return;
            }

            LogUtil.Debug(DebugInfoDetail.Movement, "Distance to target: " + start.Distance2D(dest).ToString());

            // If target moved or first call, then issue a new follow
            if (targetPosition.Distance2D(this.followCoordinates) > 2.0f)
            {
                this.StopMovement();
                this.Character.Coordinates(start);
                FollowTargetMessageHandler.Default.Send(this.Character, start);
                Vector3 temp = start - dest;
                temp.y = 0;
                this.Character.Heading = (Quaternion)Quaternion.GenerateRotationFromDirectionVector(temp);
                this.followCoordinates = dest;
                FollowTargetMessageHandler.Default.Send(this.Character, start, dest);
                this.StartMovement();
            }
        }
        public override bool Execute(
            INamedEntity self,
            IEntity caller,
            IInstancedEntity target,
            MessagePackObject[] arguments)
        {
            ICharacter character = (ICharacter)self;

            int statelId = (int)((uint)0xC0000000 | arguments[1].AsInt32() | (arguments[2].AsInt32() << 16));

            character.Stats[StatIds.externaldoorinstance].BaseValue      = 0;
            character.Stats[StatIds.externalplayfieldinstance].BaseValue = 0;

            if (arguments[1].AsInt32() > 0)
            {
                StatelData sd = PlayfieldLoader.PFData[arguments[1].AsInt32()].GetDoor(statelId);
                if (sd == null)
                {
                    throw new Exception(
                              "Statel " + arguments[3].AsInt32().ToString("X") + " not found? Check the rdb dammit");
                }

                Vector3 v = new Vector3(sd.X, sd.Y, sd.Z);

                Quaternion q = new Quaternion(sd.HeadingX, sd.HeadingY, sd.HeadingZ, sd.HeadingW);

                Quaternion.Normalize(q);
                Vector3 n = (Vector3)q.RotateVector3(Vector3.AxisZ);

                v.x += n.x * 2.5;
                v.z += n.z * 2.5;
                character.Playfield.Teleport(
                    (Dynel)character,
                    new Coordinate(v),
                    q,
                    new Identity()
                {
                    Type = (IdentityType)arguments[0].AsInt32(), Instance = arguments[1].AsInt32()
                });
            }

            return(true);

            self.Stats[StatIds.externalplayfieldinstance].Value = 0;
            self.Stats[StatIds.externaldoorinstance].Value      = 0;
            self.Playfield.Teleport(
                (Dynel)self,
                new Coordinate(100, 10, 100),
                ((ICharacter)self).Heading,
                new Identity()
            {
                Type = (IdentityType)arguments[0].AsInt32(), Instance = arguments[1].AsInt32()
            });
            return(true);
        }
        /// <summary>
        /// Calculate move vector
        /// </summary>
        /// <returns>Movevector</returns>
        private Vector.Vector3 calculateMoveVector()
        {
            double forwardSpeed;
            double strafeSpeed;

            Vector.Vector3 forwardMove;
            Vector.Vector3 strafeMove;

            if (!this.CanMove())
            {
                return(Vector.Vector3.Origin);
            }

            forwardSpeed = this.calculateForwardSpeed();
            strafeSpeed  = this.calculateStrafeSpeed();

            if ((forwardSpeed == 0) && (strafeSpeed == 0))
            {
                return(Vector.Vector3.Origin);
            }

            if (forwardSpeed != 0)
            {
                forwardMove           = (Vector.Vector3)Quaternion.RotateVector3(this.RawHeading, Vector.Vector3.AxisZ);
                forwardMove.Magnitude = Math.Abs(forwardSpeed);
                if (forwardSpeed < 0)
                {
                    forwardMove = -forwardMove;
                }
            }
            else
            {
                forwardMove = Vector.Vector3.Origin;
            }

            if (strafeSpeed != 0)
            {
                strafeMove           = (Vector.Vector3)Quaternion.RotateVector3(this.RawHeading, Vector.Vector3.AxisX);
                strafeMove.Magnitude = Math.Abs(strafeSpeed);
                if (strafeSpeed < 0)
                {
                    strafeMove = -strafeMove;
                }
            }
            else
            {
                strafeMove = Vector.Vector3.Origin;
            }

            return(forwardMove + strafeMove);
        }
Example #8
0
        /// <summary>
        /// </summary>
        /// <param name="Self">
        /// </param>
        /// <param name="Caller">
        /// </param>
        /// <param name="Target">
        /// </param>
        /// <param name="Arguments">
        /// </param>
        /// <returns>
        /// </returns>
        public bool FunctionExecute(
            INamedEntity Self,
            INamedEntity Caller,
            IInstancedEntity Target,
            MessagePackObject[] Arguments)
        {
            // TODO: Use the arguments!!!!!

            Coordinate  destination = new Coordinate();
            IQuaternion heading     = new Quaternion(0.0, 0.0, 0.0, 0.0);
            Identity    playfield   = new Identity();

            ((Character)Self).Teleport(destination, heading, playfield);
            return(true);
        }
Example #9
0
        public bool Follow(Identity target)
        {
            this.followIdentity = target;
            ICharacter npc = Pool.Instance.GetObject <ICharacter>(this.Character.Playfield.Identity, target);

            if (npc != null)
            {
                Vector3 temp = npc.Coordinates().coordinate - this.Character.Coordinates().coordinate;
                temp.y = 0;
                this.Character.Heading = (Quaternion)Quaternion.GenerateRotationFromDirectionVector(temp).Normalize();
                FollowTargetMessageHandler.Default.Send(
                    this.Character,
                    this.Character.Coordinates().coordinate,
                    npc.Coordinates().coordinate);
                this.Run();
                this.StartMovement();
            }
            return(true);
        }
Example #10
0
        /// <summary>
        /// </summary>
        /// <param name="Self">
        /// </param>
        /// <param name="Caller">
        /// </param>
        /// <param name="Target">
        /// </param>
        /// <param name="Arguments">
        /// </param>
        /// <returns>
        /// </returns>
        public bool FunctionExecute(
            INamedEntity Self,
            IEntity Caller,
            IInstancedEntity Target,
            MessagePackObject[] Arguments)
        {
            // TODO: Use the arguments!!!!!

            Coordinate  destination = new Coordinate(Arguments[0].AsInt32(), Arguments[1].AsInt32(), Arguments[2].AsInt32());
            IQuaternion heading     = new Quaternion(0.0, 0.0, 0.0, 0.0);
            Identity    playfield   = new Identity()
            {
                Type = IdentityType.Playfield, Instance = Arguments[3].AsInt32()
            };

            if (playfield.Instance == 0)
            {
                playfield = Self.Playfield.Identity;
            }
            ((Character)Self).Teleport(destination, heading, playfield);
            return(true);
        }
        public override bool Execute(
            INamedEntity self,
            IEntity caller,
            IInstancedEntity target,
            MessagePackObject[] arguments)
        {
            uint externalDoorInstance = self.Stats[StatIds.externaldoorinstance].BaseValue;
            int  externalPlayfieldId  = self.Stats[StatIds.externalplayfieldinstance].Value;

            StatelData door =
                PlayfieldLoader.PFData[externalPlayfieldId].Statels.FirstOrDefault(
                    x =>
                    (uint)x.Identity.Instance == externalDoorInstance &&
                    (x.Identity.Type == IdentityType.Door /*|| x.Identity.Type==IdentityType.MissionEntrance*/));

            if (door != null)
            {
                Vector3 v = new Vector3(door.X, door.Y, door.Z);

                Quaternion q = new Quaternion(door.HeadingX, door.HeadingY, door.HeadingZ, door.HeadingW);

                Quaternion.Normalize(q);
                Vector3 n = (Vector3)q.RotateVector3(Vector3.AxisZ);

                v.x += n.x * 2.5;
                v.z += n.z * 2.5;
                self.Playfield.Teleport(
                    (Dynel)self,
                    new Coordinate(v),
                    q,
                    new Identity()
                {
                    Type = IdentityType.Playfield, Instance = externalPlayfieldId
                });
            }
            return(door != null);
        }
Example #12
0
        internal Coordinate CalculatePredictedPosition()
        {
            if ((this.moveDirection == MoveDirections.None) && (this.strafeDirection == SpinOrStrafeDirections.None))
            {
                return(new Coordinate(this.RawCoordinates));
            }
            else if (this.spinDirection == SpinOrStrafeDirections.None)
            {
                Vector3 moveVector = this.CalculateMoveVector();

                moveVector = moveVector * this.PredictionDuration.TotalSeconds;

                /*this.RawCoordinates = new Vector3()
                 *                    {
                 *                        x = this.RawCoordinates.X + moveVector.x,
                 *                        y = this.RawCoordinates.Y + moveVector.y,
                 *                        z = this.RawCoordinates.Z + moveVector.z
                 *                    };
                 *
                 * this.PredictionTime = DateTime.UtcNow;*/
                Coordinate result =
                    new Coordinate(
                        new Vector3(
                            this.RawCoordinates.X + moveVector.x,
                            this.RawCoordinates.Y + moveVector.y,
                            this.RawCoordinates.Z + moveVector.z));
                LogUtil.Debug(
                    DebugInfoDetail.Movement,
                    moveVector.ToString().PadRight(40) + "/" + result.ToString() + "/");
                return(result);
            }
            else
            {
                Vector3 moveVector;
                Vector3 positionFromCentreOfTurningCircle;
                double  turnArcAngle;
                double  y;
                double  duration;

                duration = this.PredictionDuration.TotalSeconds;

                moveVector   = this.CalculateMoveVector();
                turnArcAngle = this.calculateTurnArcAngle();

                // This is calculated seperately as height is unaffected by turning
                y = this.RawCoordinates.Y + (moveVector.y * duration);

                if (this.spinDirection == SpinOrStrafeDirections.Left)
                {
                    positionFromCentreOfTurningCircle = new Vector3(moveVector.z, y, -moveVector.x);
                }
                else
                {
                    positionFromCentreOfTurningCircle = new Vector3(-moveVector.z, y, moveVector.x);
                }

                return
                    (new Coordinate(
                         new Vector3(this.RawCoordinates.X, this.RawCoordinates.Y, this.RawCoordinates.Z)
                         + (Vector3)
                         Quaternion.RotateVector3(
                             new Quaternion(Vector3.AxisY, turnArcAngle),
                             positionFromCentreOfTurningCircle) - positionFromCentreOfTurningCircle));
            }
        }
Example #13
0
 public bool Move(int moveType, Coordinate newCoordinates, Quaternion heading)
 {
     throw new NotImplementedException();
 }
        private static Character CreateMob(
            DBMobTemplate mob,
            Identity playfieldIdentity,
            Coordinate coord,
            Quaternion heading,
            IController controller,
            int level)
        {
            IPlayfield playfield = Pool.Instance.GetObject <IPlayfield>(Identity.None, playfieldIdentity);

            if (playfield != null)
            {
                int      newInstanceId = Pool.Instance.GetFreeInstance <Character>(1000000, IdentityType.CanbeAffected);
                Identity newIdentity   = new Identity()
                {
                    Type = IdentityType.CanbeAffected, Instance = newInstanceId
                };
                Character mobCharacter = new Character(playfield.Identity, newIdentity, controller);
                mobCharacter.Read();
                mobCharacter.Coordinates(coord);
                mobCharacter.Playfield  = Pool.Instance.GetObject <IPlayfield>(Identity.None, playfieldIdentity);
                mobCharacter.RawHeading = new Quaternion(heading.xf, heading.yf, heading.zf, heading.wf);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.life, (uint)mob.Health);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.level, (uint)level);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.npcfamily, (uint)mob.NPCFamily);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.side, (uint)mob.Side);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.fatness, (uint)mob.Fatness);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.breed, (uint)mob.Breed);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.sex, (uint)mob.Sex);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.race, (uint)mob.Race);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.flags, (uint)mob.Flags);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.monsterdata, (uint)mob.MonsterData);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.monsterscale, (uint)mob.MonsterScale);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.profession, 15);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.accountflags, 0);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.expansion, 0);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.runspeed, 513);
                mobCharacter.Stats[StatIds.headmesh].BaseValue = (uint)mob.HeadMesh;
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.losheight, 15);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.visualprofession, 15);

                /*
                 * // For testing only, blue trousers and a helmet
                 * IItem trousers = new Item(1, ItemLoader.ItemList[27350].GetLowId(1),ItemLoader.ItemList[27350].GetLowId(1));
                 * IItem helmet = new Item(1, ItemLoader.ItemList[85534].GetLowId(1), ItemLoader.ItemList[85534].GetHighId(1));
                 * mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].Add((int)ArmorSlots.Legs + mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].FirstSlotNumber, trousers);
                 * mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].Add((int)ArmorSlots.Head + mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].FirstSlotNumber, helmet);
                 */

                // Set the MeshLayers correctly ( Head mesh!! )  /!\
                // TODO: This needs to be in StatHeadmesh.cs (somehow)
                mobCharacter.MeshLayer.AddMesh(0, mob.HeadMesh, 0, 4);
                mobCharacter.SocialMeshLayer.AddMesh(0, mob.HeadMesh, 0, 4);

                mobCharacter.Name      = mob.Name;
                mobCharacter.FirstName = "";
                mobCharacter.LastName  = "";
                controller.Character   = mobCharacter;
                return(mobCharacter);
            }
            return(null);
        }
Example #15
0
        /// <summary>
        /// </summary>
        /// <param name="Self">
        /// </param>
        /// <param name="Caller">
        /// </param>
        /// <param name="Target">
        /// </param>
        /// <param name="Arguments">
        /// </param>
        /// <returns>
        /// </returns>
        public bool FunctionExecute(
            INamedEntity Self, 
            INamedEntity Caller, 
            IInstancedEntity Target, 
            MessagePackObject[] Arguments)
        {
            // TODO: Use the arguments!!!!!

            Coordinate destination = new Coordinate();
            IQuaternion heading = new Quaternion(0.0, 0.0, 0.0, 0.0);
            Identity playfield = new Identity();
            ((Character)Self).Teleport(destination, heading, playfield);
            return true;
        }
Example #16
0
        /// <summary>
        /// </summary>
        /// <param name="message">
        /// </param>
        /// <param name="client">
        /// </param>
        public static void Read(CharDCMoveMessage message, ZoneClient client)
        {
            byte moveType = message.MoveType;
            var heading = new Quaternion(message.Heading.X, message.Heading.Y, message.Heading.Z, message.Heading.W);
            Coordinate coordinates = new Coordinate(message.Coordinates);

            // TODO: Find out what these (tmpInt) are and name them
            int tmpInt1 = message.Unknown1;
            int tmpInt2 = message.Unknown2;
            int tmpInt3 = message.Unknown3;

            /*
            if (!client.Character.DoNotDoTimers)
            {
                var teleportPlayfield = WallCollision.WallCollisionCheck(
                    coordinates.x, coordinates.z, client.Character.PlayField);
                if (teleportPlayfield.ZoneToPlayfield >= 1)
                {
                    var coordHeading = WallCollision.GetCoord(
                        teleportPlayfield, coordinates.x, coordinates.z, coordinates);
                    if (teleportPlayfield.Flags != 1337 && client.Character.PlayField != 152
                        || Math.Abs(client.Character.Coordinates.y - teleportPlayfield.Y) <= 2
                        || teleportPlayfield.Flags == 1337
                        && Math.Abs(client.Character.Coordinates.y - teleportPlayfield.Y) <= 6)
                    {
                        client.Teleport(
                            coordHeading.Coordinates, coordHeading.Heading, teleportPlayfield.ZoneToPlayfield);
                        Program.zoneServer.Clients.Remove(client);
                    }

                    return;
                }

                if (client.Character.Stats.LastConcretePlayfieldInstance.Value != 0)
                {
                    var correspondingDoor = DoorHandler.DoorinRange(
                        client.Character.PlayField, client.Character.Coordinates, 1.0f);
                    if (correspondingDoor != null)
                    {
                        correspondingDoor = DoorHandler.FindCorrespondingDoor(correspondingDoor, client.Character);
                        client.Character.Stats.LastConcretePlayfieldInstance.Value = 0;
                        var aoc = correspondingDoor.Coordinates;
                        aoc.x += correspondingDoor.hX * 3;
                        aoc.y += correspondingDoor.hY * 3;
                        aoc.z += correspondingDoor.hZ * 3;
                        client.Teleport(aoc, client.Character.Heading, correspondingDoor.playfield);
                        Program.zoneServer.Clients.Remove(client);
                        return;
                    }
                }
            }
            */

            // Is this correct? Shouldnt the client input be compared to the prediction and then be overridden to prevent teleportation exploits?
            // - Algorithman

            client.Character.RawCoordinates = coordinates.coordinate;
            client.Character.RawHeading = heading;
            client.Character.UpdateMoveType(moveType);

            /* Start NV Heading Testing Code
             * Yaw: 0 to 360 Degrees (North turning clockwise to a complete revolution)
             * Roll: Not sure, but is always 0 cause we can't roll in AO
             * Pitch: 90 to -90 Degrees (90 is nose in the air, 0 is level, -90 is nose to the ground)
             */
            /* Comment this line with a '//' to enable heading testing
            client.SendChatText("Raw Headings: X: " + client.Character.heading.x + " Y: " + client.Character.heading.y + " Z:" + client.Character.heading.z);

            client.SendChatText("Yaw:  " + Math.Round(180 * client.Character.heading.yaw / Math.PI) + " Degrees");
            client.SendChatText("Roll: " + Math.Round(180 * client.Character.heading.roll / Math.PI) + " Degrees");
            client.SendChatText("Pitch:   " + Math.Round(180 * client.Character.heading.pitch / Math.PI) + " Degrees");
            /* End NV Heading testing code */

            /* start of packet */
            var reply = new CharDCMoveMessage
                        {
                            Identity = client.Character.Identity,
                            Unknown = 0x00,
                            MoveType = moveType,
                            Heading =
                                new SmokeLounge.AOtomation.Messaging.GameData.Quaternion
                                {
                                    X =
                                        heading
                                        .xf,
                                    Y =
                                        heading
                                        .yf,
                                    Z =
                                        heading
                                        .zf,
                                    W =
                                        heading
                                        .wf
                                },
                            Coordinates =
                                new Vector3
                                {
                                    X = coordinates.x,
                                    Y = coordinates.y,
                                    Z = coordinates.z
                                },
                            Unknown1 = tmpInt1,
                            Unknown2 = tmpInt2,
                            Unknown3 = tmpInt3
                        };
            client.Playfield.Publish(new IMSendAOtomationMessageToPlayfield { Body = reply });

            // TODO: rewrite statelscheck
            /*
            if (Statels.StatelppfonEnter.ContainsKey(client.Character.PlayField))
            {
                foreach (var s in Statels.StatelppfonEnter[client.Character.PlayField])
                {
                    if (s.onEnter(client))
                    {
                        return;
                    }

                    if (s.onTargetinVicinity(client))
                    {
                        return;
                    }
                }
            }
             */
        }
 /// <summary>
 /// </summary>
 /// <param name="newCoordinates">
 /// </param>
 /// <param name="heading">
 /// </param>
 public void SetCoordinates(Coordinate newCoordinates, Quaternion heading)
 {
     this.Coordinates(newCoordinates);
     this.Heading = heading;
     this.PredictionTime = DateTime.UtcNow;
 }
        /// <summary>
        /// </summary>
        /// <param name="moveType">
        /// </param>
        /// <param name="newCoordinates">
        /// </param>
        /// <param name="heading">
        /// </param>
        /// <returns>
        /// </returns>
        /// <exception cref="NotImplementedException">
        /// </exception>
        public bool Move(int moveType, Coordinate newCoordinates, Quaternion heading)
        {
            // Procedure:
            // 1. Check if new coordinates are plausible (in range of runspeed since last update)
            // 2. Set coordinates & heading

            // Is this correct? Shouldnt the client input be compared to the prediction and then be overridden to prevent teleportation exploits?
            // - Algorithman

            // give it a bit uncertainty (2.0f)
            LogUtil.Debug(
                DebugInfoDetail.Movement,
                newCoordinates.ToString() + "<->" + this.Character.Coordinates().ToString());
            // if (newCoordinates.Distance2D(this.Character.Coordinates) < 2.0f)
            {
                this.Character.SetCoordinates(newCoordinates, heading);
                this.Character.UpdateMoveType((byte)moveType);
            }
            /*
            else
            {
                this.Character.StopMovement();
            }
            */
            return true;
        }
        private static Character CreateMob(
            DBMobTemplate mob,
            Identity playfieldIdentity,
            Coordinate coord,
            Quaternion heading,
            IController controller,
            int level)
        {
            IPlayfield playfield = Pool.Instance.GetObject<IPlayfield>(Identity.None, playfieldIdentity);
            if (playfield != null)
            {
                int newInstanceId = Pool.Instance.GetFreeInstance<Character>(1000000, IdentityType.CanbeAffected);
                Identity newIdentity = new Identity() { Type = IdentityType.CanbeAffected, Instance = newInstanceId };
                Character mobCharacter = new Character(playfield.Identity, newIdentity, controller);
                mobCharacter.Read();
                mobCharacter.Coordinates(coord);
                mobCharacter.Playfield = Pool.Instance.GetObject<IPlayfield>(Identity.None, playfieldIdentity);
                mobCharacter.RawHeading = new Quaternion(heading.xf, heading.yf, heading.zf, heading.wf);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.life, (uint)mob.Health);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.level, (uint)level);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.npcfamily, (uint)mob.NPCFamily);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.side, (uint)mob.Side);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.fatness, (uint)mob.Fatness);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.breed, (uint)mob.Breed);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.sex, (uint)mob.Sex);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.race, (uint)mob.Race);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.flags, (uint)mob.Flags);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.monsterdata, (uint)mob.MonsterData);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.monsterscale, (uint)mob.MonsterScale);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.profession, 15);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.accountflags, 0);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.expansion, 0);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.runspeed, 513);
                mobCharacter.Stats[StatIds.headmesh].BaseValue = (uint)mob.HeadMesh;
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.losheight, 15);
                mobCharacter.Stats.SetBaseValueWithoutTriggering((int)StatIds.visualprofession, 15);

                /*
                // For testing only, blue trousers and a helmet
                IItem trousers = new Item(1, ItemLoader.ItemList[27350].GetLowId(1),ItemLoader.ItemList[27350].GetLowId(1));
                IItem helmet = new Item(1, ItemLoader.ItemList[85534].GetLowId(1), ItemLoader.ItemList[85534].GetHighId(1));
                mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].Add((int)ArmorSlots.Legs + mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].FirstSlotNumber, trousers);
                mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].Add((int)ArmorSlots.Head + mobCharacter.BaseInventory.Pages[(int)IdentityType.ArmorPage].FirstSlotNumber, helmet);
                */

                // Set the MeshLayers correctly ( Head mesh!! )  /!\
                // TODO: This needs to be in StatHeadmesh.cs (somehow)
                mobCharacter.MeshLayer.AddMesh(0, mob.HeadMesh, 0, 4);
                mobCharacter.SocialMeshLayer.AddMesh(0, mob.HeadMesh, 0, 4);

                mobCharacter.Name = mob.Name;
                mobCharacter.FirstName = "";
                mobCharacter.LastName = "";
                controller.Character = mobCharacter;
                return mobCharacter;
            }
            return null;
        }
Example #20
0
 /// <summary>
 /// </summary>
 /// <param name="newCoordinates">
 /// </param>
 /// <param name="heading">
 /// </param>
 public void SetCoordinates(Coordinate newCoordinates, Quaternion heading)
 {
     this.Coordinates(newCoordinates);
     this.Heading        = heading;
     this.PredictionTime = DateTime.UtcNow;
 }
 /// <summary>
 /// Return a Vector representation of a Quaternion (w is dropped)
 /// </summary>
 /// <param name="q1">
 /// Quaternion
 /// </param>
 /// <returns>
 /// </returns>
 public static IVector3 VectorRepresentation(Quaternion q1)
 {
     return new Vector3(q1.x, q1.y, q1.z);
 }
        public static Character SpawnMobFromTemplate(
            string hash,
            Identity playfieldIdentity,
            Coordinate coord,
            Quaternion heading,
            IController controller,
            int desiredLevel = -1)
        {
            Character mobCharacter = null;

            DBMobTemplate mob = MobTemplateDao.Instance.GetMobTemplateByHash(hash);
            if (mob != null)
            {
                int level = desiredLevel;
                if (level == -1)
                {
                    // Get random inside level range
                    Random rnd = new Random();
                    level = mob.MinLvl + rnd.Next(mob.MaxLvl - mob.MinLvl);
                }
                else
                {
                    // Put it inside level range
                    level = (level < mob.MinLvl ? mob.MinLvl : level);
                    level = level > mob.MaxLvl ? mob.MaxLvl : level;
                }
                mobCharacter = CreateMob(mob, playfieldIdentity, coord, heading, controller, level);
            }
            return mobCharacter;
        }
        /// <summary>
        /// Fill this info in
        /// </summary>
        /// <param name="vDirection">
        /// </param>
        /// <returns>
        /// Fill this info in
        /// </returns>
        public static IQuaternion GenerateRotationFromDirectionVector(IVector3 vDirection)
        {
            // Step 1. Setup basis vectors describing the rotation given the input vector and assuming an initial up direction of (0, 1, 0)
            Vector3 vDirNormalized = Vector3.Normalize((Vector3)vDirection);
            Vector3 vUp = new Vector3(0, 1.0f, 0.0f); // Y Up vector
            Vector3 vRight = Vector3.Cross(vUp, vDirNormalized); // The perpendicular vector to Up and Direction
            vUp = Vector3.Cross(vDirNormalized, vRight); // The actual up vector given the direction and the right vector

            // Step 2. Put the three vectors into the matrix to bulid a basis rotation matrix
            // This step isnt necessary, but im adding it because often you would want to convert from matricies to quaternions instead of vectors to quaternions
            // If you want to skip this step, you can use the vector values directly in the quaternion setup below
            Matrix mBasis = new DenseMatrix(4, 4);
            mBasis.SetRow(0, new[] { (float)vRight.x, (float)vRight.y, (float)vRight.z, 0.0f });
            mBasis.SetRow(1, new[] { (float)vUp.x, (float)vUp.y, (float)vUp.z, 0.0f });
            mBasis.SetRow(2, new[] { (float)vDirNormalized.x, (float)vDirNormalized.y, (float)vDirNormalized.z, 0.0f });
            mBasis.SetRow(3, new[] { 0.0f, 0.0f, 0.0f, 1.0f });

            // Step 3. Build a quaternion from the matrix
            double dfWScale = Math.Sqrt(1.0f + mBasis.At(0, 0) + mBasis.At(1, 1) + mBasis.At(2, 2)) / 2.0f * 4.0;
            if (dfWScale == 0.0)
            {
                Quaternion q = new Quaternion(0, 1, 0, 0);
                return q;
            }

            Quaternion qrot = new Quaternion(
                (float)((mBasis.At(3, 2) - mBasis.At(2, 3)) / dfWScale),
                (float)((mBasis.At(0, 2) - mBasis.At(2, 0)) / dfWScale),
                (float)((mBasis.At(1, 0) - mBasis.At(0, 1)) / dfWScale),
                (float)Math.Sqrt(1.0f + mBasis.At(0, 0) + mBasis.At(1, 1) + mBasis.At(2, 2)) / 2.0f);
            var temp = qrot.w;
            qrot.w = qrot.y;
            qrot.y = temp;
            return qrot.Normalize();
        }
 /// <summary>
 /// Return a Vector rotated around the Quaternion
 /// </summary>
 /// <param name="q1">
 /// Quaternion
 /// </param>
 /// <param name="v2">
 /// Vector
 /// </param>
 /// <returns>
 /// </returns>
 public static IVector3 RotateVector3(IQuaternion q1, IVector3 v2)
 {
     Quaternion QuatVect = new Quaternion(v2.x, v2.y, v2.z, 0);
     Quaternion QuatNorm = (Quaternion)q1.Normalize();
     Quaternion Result = Hamilton(Hamilton(QuatNorm, QuatVect), QuatNorm.Conjugate());
     return new Vector3(Result.x, Result.y, Result.z);
 }
 /// <summary>
 /// Return the Conjugate of the Quaternion
 /// </summary>
 /// <param name="q1">
 /// Quaternion
 /// </param>
 /// <returns>
 /// </returns>
 public static Quaternion Conjugate(Quaternion q1)
 {
     return new Quaternion(-q1.x, -q1.y, -q1.z, q1.w);
 }
        public override bool Execute(
            INamedEntity self,
            IEntity caller,
            IInstancedEntity target,
            MessagePackObject[] arguments)
        {
            ICharacter character = (ICharacter)self;

            int statelId = (int)((uint)0xC0000000 | arguments[1].AsInt32() | (arguments[2].AsInt32() << 16));
            character.Stats[StatIds.externaldoorinstance].BaseValue = 0;
            character.Stats[StatIds.externalplayfieldinstance].BaseValue = 0;

            if (arguments[1].AsInt32() > 0)
            {
                StatelData sd = PlayfieldLoader.PFData[arguments[1].AsInt32()].GetDoor(statelId);
                if (sd == null)
                {
                    throw new Exception(
                        "Statel " + arguments[3].AsInt32().ToString("X") + " not found? Check the rdb dammit");
                }

                Vector3 v = new Vector3(sd.X, sd.Y, sd.Z);

                Quaternion q = new Quaternion(sd.HeadingX, sd.HeadingY, sd.HeadingZ, sd.HeadingW);

                Quaternion.Normalize(q);
                Vector3 n = (Vector3)q.RotateVector3(Vector3.AxisZ);

                v.x += n.x * 2.5;
                v.z += n.z * 2.5;
                character.Playfield.Teleport(
                    (Dynel)character,
                    new Coordinate(v),
                    q,
                    new Identity() { Type = (IdentityType)arguments[0].AsInt32(), Instance = arguments[1].AsInt32() });
            }

            return true;

            self.Stats[StatIds.externalplayfieldinstance].Value = 0;
            self.Stats[StatIds.externaldoorinstance].Value = 0;
            self.Playfield.Teleport(
                (Dynel)self,
                new Coordinate(100, 10, 100),
                ((ICharacter)self).Heading,
                new Identity() { Type = (IdentityType)arguments[0].AsInt32(), Instance = arguments[1].AsInt32() });
            return true;
        }
        /// <summary>
        /// </summary>
        /// <param name="Self">
        /// </param>
        /// <param name="Caller">
        /// </param>
        /// <param name="Target">
        /// </param>
        /// <param name="Arguments">
        /// </param>
        /// <returns>
        /// </returns>
        public bool FunctionExecute(
            INamedEntity Self,
            IEntity Caller,
            IInstancedEntity Target,
            MessagePackObject[] Arguments)
        {
            // TODO: Use the arguments!!!!!

            Coordinate destination = new Coordinate(Arguments[0].AsInt32(), Arguments[1].AsInt32(), Arguments[2].AsInt32());
            IQuaternion heading = new Quaternion(0.0, 0.0, 0.0, 0.0);
            Identity playfield = new Identity() { Type = IdentityType.Playfield, Instance = Arguments[3].AsInt32() };
            if (playfield.Instance==0)
            {
                playfield = Self.Playfield.Identity;
            }
            ((Character)Self).Teleport(destination, heading, playfield);
            return true;
        }
 public bool Move(int moveType, Coordinate newCoordinates, Quaternion heading)
 {
     throw new NotImplementedException();
 }
        public override bool Execute(
            INamedEntity self,
            IEntity caller,
            IInstancedEntity target,
            MessagePackObject[] arguments)
        {
            uint externalDoorInstance = self.Stats[StatIds.externaldoorinstance].BaseValue;
            int externalPlayfieldId = self.Stats[StatIds.externalplayfieldinstance].Value;

            StatelData door =
                PlayfieldLoader.PFData[externalPlayfieldId].Statels.FirstOrDefault(
                    x =>
                        (uint)x.Identity.Instance == externalDoorInstance
                        && (x.Identity.Type == IdentityType.Door /*|| x.Identity.Type==IdentityType.MissionEntrance*/));
            if (door != null)
            {
                Vector3 v = new Vector3(door.X, door.Y, door.Z);

                Quaternion q = new Quaternion(door.HeadingX, door.HeadingY, door.HeadingZ, door.HeadingW);

                Quaternion.Normalize(q);
                Vector3 n = (Vector3)q.RotateVector3(Vector3.AxisZ);

                v.x += n.x * 2.5;
                v.z += n.z * 2.5;
                self.Playfield.Teleport(
                    (Dynel)self,
                    new Coordinate(v),
                    q,
                    new Identity() { Type = IdentityType.Playfield, Instance = externalPlayfieldId });
            }
            return door != null;
        }