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>
        /// 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());
        }
        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);
        }
        /// <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();
        }