示例#1
0
        int turn_obj_away_from_steep_floor(TriangleDataModel objFloor, float floorY, float objVelX, float objVelZ)
        {
            float floor_nX, floor_nY, floor_nZ, objVelXCopy, objVelZCopy, objYawX, objYawZ;

            if (objFloor == null)
            {
                Yaw = MoreMath.NormalizeAngleUshort(Yaw + 32767);
                return(0);
            }

            floor_nX = objFloor.NormX;
            floor_nY = objFloor.NormY;
            floor_nZ = objFloor.NormZ;

            if (floor_nY < 0.5 && floorY > Y)
            {
                objVelXCopy = objVelX;
                objVelZCopy = objVelZ;
                turn_obj_away_from_surface(
                    objVelXCopy, objVelZCopy, floor_nX, floor_nY, floor_nZ, out objYawX, out objYawZ);
                Yaw = InGameTrigUtilities.InGameATan(objYawZ, objYawX);
                return(0);
            }

            return(1);
        }
示例#2
0
        protected override double GetYaw()
        {
            uint globalTimer = Config.Stream.GetUInt32(MiscConfig.GlobalTimerAddress);
            int  targetAngle = Config.Stream.GetInt32(_objAddress + ObjectConfig.SwooperTargetYawOffset);

            return(targetAngle + (short)(3000 * InGameTrigUtilities.InGameCosine(4000 * (int)globalTimer)));
        }
示例#3
0
        // push_mario_out_of_object
        public static (float newMarioX, float newMarioZ) GetHardObjectDisplacement(
            float marioX, float marioZ, float marioRadius, ushort marioAngle,
            float objectX, float objectZ, float objectRadius, float padding)
        {
            float minDistance = objectRadius + marioRadius + padding;

            float offsetX  = marioX - objectX;
            float offsetZ  = marioZ - objectZ;
            float distance = (float)Math.Sqrt(offsetX * offsetX + offsetZ * offsetZ);

            if (distance < minDistance)
            {
                short pushAngle;
                float newMarioX;
                float newMarioZ;

                if (distance == 0.0f)
                {
                    pushAngle = (short)marioAngle;
                }
                else
                {
                    pushAngle = (short)InGameTrigUtilities.InGameATan(offsetZ, offsetX);
                }

                newMarioX = objectX + minDistance * InGameTrigUtilities.InGameSine(pushAngle);
                newMarioZ = objectZ + minDistance * InGameTrigUtilities.InGameCosine(pushAngle);

                return(newMarioX, newMarioZ);
            }
            return(marioX, marioZ);
        }
示例#4
0
        void calc_new_obj_vel_and_pos_y(TriangleDataModel objFloor, float objFloorY, float objVelX, float objVelZ)
        {
            float floor_nX = objFloor.NormX;
            float floor_nY = objFloor.NormY;
            float floor_nZ = objFloor.NormZ;
            float objFriction;

            YSpeed -= Gravity;
            if (YSpeed > 75.0)
            {
                YSpeed = 75.0f;
            }
            if (YSpeed < -75.0)
            {
                YSpeed = -75.0f;
            }

            Y += YSpeed;

            if (Y < objFloorY)
            {
                Y = objFloorY;

                if (YSpeed < -17.5)
                {
                    YSpeed = -(YSpeed / 2);
                }
                else
                {
                    YSpeed = 0;
                }
            }

            if ((int)Y >= (int)objFloorY && (int)Y < (int)objFloorY + 37)
            {
                objVelX += floor_nX * (floor_nX * floor_nX + floor_nZ * floor_nZ)
                           / (floor_nX * floor_nX + floor_nY * floor_nY + floor_nZ * floor_nZ) * Gravity
                           * 2;
                objVelZ += floor_nZ * (floor_nX * floor_nX + floor_nZ * floor_nZ)
                           / (floor_nX * floor_nX + floor_nY * floor_nY + floor_nZ * floor_nZ) * Gravity
                           * 2;

                if (objVelX < 0.000001 && objVelX > -0.000001)
                {
                    objVelX = 0;
                }
                if (objVelZ < 0.000001 && objVelZ > -0.000001)
                {
                    objVelZ = 0;
                }

                if (objVelX != 0 || objVelZ != 0)
                {
                    Yaw = InGameTrigUtilities.InGameATan(objVelZ, objVelX);
                }

                calc_obj_friction(out objFriction, floor_nY);
                HSpeed = (float)Math.Sqrt(objVelX * objVelX + objVelZ * objVelZ) * objFriction;
            }
        }
        protected override List <(float x, float y, float z)> GetVerticesTopDownView()
        {
            List <(float x, float y, float z)> vertices = new List <(float x, float y, float z)>();

            (double x1, double y1, double z1, double a) = _posAngle.GetValues();
            int startingAngle = _useRelativeAngles ? MoreMath.NormalizeAngleTruncated(a) : 0;

            void addPointUsingAngle(int angle)
            {
                (double x2, double z2) = MoreMath.AddVectorToPoint(Size, angle, x1, z1);
                vertices.Add(((float)x1, (float)y1, (float)z1));
                vertices.Add(((float)x2, (float)y1, (float)z2));
            }

            if (_useInGameAngles)
            {
                foreach (int angle in InGameTrigUtilities.GetInGameAngles())
                {
                    addPointUsingAngle(MoreMath.NormalizeAngleTruncated(angle));
                }
            }
            else
            {
                for (int angle = startingAngle; angle < startingAngle + 65536; angle += _angleDiff)
                {
                    addPointUsingAngle(angle);
                }
            }
            return(vertices);
        }
示例#6
0
        void obj_update_pos_vel_xz()
        {
            float xVel = HSpeed * InGameTrigUtilities.InGameSine(Yaw);
            float zVel = HSpeed * InGameTrigUtilities.InGameCosine(Yaw);

            X += xVel;
            Z += zVel;
        }
示例#7
0
        public void object_step()
        {
            float objVelX = HSpeed * InGameTrigUtilities.InGameSine(Yaw);
            float objVelZ = HSpeed * InGameTrigUtilities.InGameCosine(Yaw);

            calc_new_obj_vel_and_pos_y(objVelX, objVelZ);
            obj_update_pos_vel_xz();
        }
示例#8
0
        public void obj_return_home_if_safe()
        {
            float homeDistX        = HomeX - X;
            float homeDistZ        = HomeZ - Z;
            short angleTowardsHome = (short)InGameTrigUtilities.InGameATan(homeDistZ, homeDistX);

            Yaw = (ushort)approach_s16_symmetric((short)Yaw, angleTowardsHome, 320);
        }
示例#9
0
        // cur_obj_set_pos_relative
        public static (float objectX, float objectY, float objectZ) GetRelativePosition(
            float marioX, float marioY, float marioZ, ushort marioAngle,
            float dleft, float dy, float dforward)
        {
            float facingZ = InGameTrigUtilities.InGameCosine(marioAngle);
            float facingX = InGameTrigUtilities.InGameSine(marioAngle);

            float dz = dforward * facingZ - dleft * facingX;
            float dx = dforward * facingX + dleft * facingZ;

            return(marioX + dx, marioY + dy, marioZ + dz);
        }
示例#10
0
        // update_air_without_turn
        private static MarioState ComputeAirHSpeed(MarioState initialState, Input input)
        {
            bool longJump = false;
            int  maxSpeed = longJump ? 48 : 32;

            ushort marioAngle  = initialState.MarioAngle;
            ushort yawIntended = MoreMath.CalculateAngleFromInputs(input.X, input.Y, initialState.CameraAngle);
            int    deltaAngleIntendedFacing = yawIntended - marioAngle;
            float  inputScaledMagnitude     = input.GetScaledMagnitude();

            float perpSpeed = 0;
            float newHSpeed = ApproachHSpeed(initialState.HSpeed, 0, 0.35f, 0.35f);

            if (inputScaledMagnitude > 0)
            {
                newHSpeed += (inputScaledMagnitude / 32) * 1.5f * InGameTrigUtilities.InGameCosine(deltaAngleIntendedFacing);
                perpSpeed  = InGameTrigUtilities.InGameSine(deltaAngleIntendedFacing) * (inputScaledMagnitude / 32) * 10;
            }

            if (newHSpeed > maxSpeed)
            {
                newHSpeed -= 1;
            }
            if (newHSpeed < -16)
            {
                newHSpeed += 2;
            }

            float newSlidingXSpeed = InGameTrigUtilities.InGameSine(marioAngle) * newHSpeed;
            float newSlidingZSpeed = InGameTrigUtilities.InGameCosine(marioAngle) * newHSpeed;

            newSlidingXSpeed += perpSpeed * InGameTrigUtilities.InGameSine(marioAngle + 0x4000);
            newSlidingZSpeed += perpSpeed * InGameTrigUtilities.InGameCosine(marioAngle + 0x4000);
            float newXSpeed = newSlidingXSpeed;
            float newZSpeed = newSlidingZSpeed;

            return(new MarioState(
                       initialState.X,
                       initialState.Y,
                       initialState.Z,
                       newXSpeed,
                       initialState.YSpeed,
                       newZSpeed,
                       newHSpeed,
                       initialState.SlidingSpeedX,
                       initialState.SlidingSpeedZ,
                       initialState.SlidingAngle,
                       initialState.MarioAngle,
                       initialState.CameraAngle,
                       initialState,
                       input,
                       initialState.Index + 1));
        }
示例#11
0
        private short object_step()
        {
            float objX = X;
            float objY = Y;
            float objZ = Z;

            float waterY = FLOOR_LOWER_LIMIT_MISC;

            float objVelX = HSpeed * InGameTrigUtilities.InGameSine(Yaw);
            float objVelZ = HSpeed * InGameTrigUtilities.InGameCosine(Yaw);

            short collisionFlags = 0;

            if (obj_find_wall(objX + objVelX, objY, objZ + objVelZ, objVelX, objVelZ) == 0)
            {
                Dead = true;
            }

            (TriangleDataModel staticFloor, float floorY) = CellSnapshot.FindFloorAndY(objX + objVelX, objY, objZ + objVelZ);
            StaticFloor = staticFloor;

            if (turn_obj_away_from_steep_floor(StaticFloor, floorY, objVelX, objVelZ) == 1)
            {
                waterY = CellSnapshot.GetWaterAtPos(objX + objVelX, objZ + objVelZ);
                if (waterY > objY)
                {
                    calc_new_obj_vel_and_pos_y_underwater(StaticFloor, floorY, objVelX, objVelZ, waterY);
                    collisionFlags += OBJ_COL_FLAG_UNDERWATER;
                }
                else
                {
                    calc_new_obj_vel_and_pos_y(StaticFloor, floorY, objVelX, objVelZ);
                }
            }
            else
            {
                collisionFlags = (short)(collisionFlags + ((collisionFlags & OBJ_COL_FLAG_HIT_WALL) ^ OBJ_COL_FLAG_HIT_WALL));
            }

            obj_update_pos_vel_xz();
            if ((int)Y == (int)floorY)
            {
                collisionFlags += OBJ_COL_FLAG_GROUNDED;
            }

            if ((int)YSpeed == 0)
            {
                collisionFlags += OBJ_COL_FLAG_NO_Y_VEL;
            }

            return(collisionFlags);
        }
示例#12
0
 // apply_slope_accel
 private static void ApplySlopeAccel(MutableMarioState marioState)
 {
     marioState.XSpeed = marioState.HSpeed * InGameTrigUtilities.InGameSine(marioState.MarioAngle);
     marioState.YSpeed = 0.0f;
     marioState.ZSpeed = marioState.HSpeed * InGameTrigUtilities.InGameCosine(marioState.MarioAngle);
 }
示例#13
0
        private static void update_sliding_angle(MutableMarioState marioState, float accel, float lossFactor, TriangleDataModel floor, List <TriangleDataModel> walls)
        {
            short slopeAngle = MoreMath.NormalizeAngleShort(InGameTrigUtilities.InGameATan(floor.NormZ, floor.NormX));
            float steepness  = (float)Math.Sqrt(floor.NormX * floor.NormX + floor.NormZ * floor.NormZ);

            marioState.SlidingSpeedX += accel * steepness * InGameTrigUtilities.InGameSine(slopeAngle);
            marioState.SlidingSpeedZ += accel * steepness * InGameTrigUtilities.InGameCosine(slopeAngle);

            marioState.SlidingSpeedX *= lossFactor;
            marioState.SlidingSpeedZ *= lossFactor;

            marioState.SlidingAngle = InGameTrigUtilities.InGameATan(marioState.SlidingSpeedZ, marioState.SlidingSpeedX);

            short facingDYaw    = MoreMath.NormalizeAngleShort(marioState.MarioAngle - marioState.SlidingAngle);
            int   newFacingDYaw = facingDYaw;

            //! -0x4000 not handled - can slide down a slope while facing perpendicular to it
            if (newFacingDYaw > 0 && newFacingDYaw <= 0x4000)
            {
                if ((newFacingDYaw -= 0x200) < 0)
                {
                    newFacingDYaw = 0;
                }
            }
            else if (newFacingDYaw > -0x4000 && newFacingDYaw < 0)
            {
                if ((newFacingDYaw += 0x200) > 0)
                {
                    newFacingDYaw = 0;
                }
            }
            else if (newFacingDYaw > 0x4000 && newFacingDYaw < 0x8000)
            {
                if ((newFacingDYaw += 0x200) > 0x8000)
                {
                    newFacingDYaw = 0x8000;
                }
            }
            else if (newFacingDYaw > -0x8000 && newFacingDYaw < -0x4000)
            {
                if ((newFacingDYaw -= 0x200) < -0x8000)
                {
                    newFacingDYaw = -0x8000;
                }
            }

            marioState.MarioAngle = MoreMath.NormalizeAngleUshort(marioState.SlidingAngle + newFacingDYaw);

            marioState.XSpeed = marioState.SlidingSpeedX;
            marioState.YSpeed = 0.0f;
            marioState.ZSpeed = marioState.SlidingSpeedZ;

            //! Speed is capped a frame late (butt slide HSG)
            marioState.HSpeed = (float)Math.Sqrt(
                marioState.SlidingSpeedX * marioState.SlidingSpeedX +
                marioState.SlidingSpeedZ * marioState.SlidingSpeedZ);

            if (marioState.HSpeed > 100.0f)
            {
                marioState.SlidingSpeedX = marioState.SlidingSpeedX * 100.0f / marioState.HSpeed;
                marioState.SlidingSpeedZ = marioState.SlidingSpeedZ * 100.0f / marioState.HSpeed;
            }

            if (newFacingDYaw < -0x4000 || newFacingDYaw > 0x4000)
            {
                marioState.HSpeed *= -1.0f;
            }
        }
示例#14
0
        private static void update_sliding(MutableMarioState marioState, float stopSpeed, TriangleDataModel floor, List <TriangleDataModel> walls)
        {
            short intendedDYaw = MoreMath.NormalizeAngleShort(marioState.IntendedAngle - marioState.SlidingAngle);
            float forward      = InGameTrigUtilities.InGameCosine(intendedDYaw);
            float sideward     = InGameTrigUtilities.InGameSine(intendedDYaw);

            //! 10k glitch
            if (forward < 0.0f && marioState.HSpeed >= 0.0f)
            {
                forward *= 0.5f + 0.5f * marioState.HSpeed / 100.0f;
            }

            float accel;
            float lossFactor;
            int   floorClass = 0x13;

            switch (floorClass)
            {
            case 0x0013:
                accel      = 10.0f;
                lossFactor = marioState.IntendedMagnitude / 32.0f * forward * 0.02f + 0.98f;
                break;

            case 0x0014:
                accel      = 8.0f;
                lossFactor = marioState.IntendedMagnitude / 32.0f * forward * 0.02f + 0.96f;
                break;

            default:
                accel      = 7.0f;
                lossFactor = marioState.IntendedMagnitude / 32.0f * forward * 0.02f + 0.92f;
                break;

            case 0x0015:
                accel      = 5.0f;
                lossFactor = marioState.IntendedMagnitude / 32.0f * forward * 0.02f + 0.92f;
                break;
            }

            float oldSpeed = (float)Math.Sqrt(
                marioState.SlidingSpeedX * marioState.SlidingSpeedX +
                marioState.SlidingSpeedZ * marioState.SlidingSpeedZ);

            //! This is attempting to use trig derivatives to rotate mario's speed.
            // It is slightly off/asymmetric since it uses the new X speed, but the old
            // Z speed.
            marioState.SlidingSpeedX += marioState.SlidingSpeedZ * (marioState.IntendedMagnitude / 32.0f) * sideward * 0.05f;
            marioState.SlidingSpeedZ -= marioState.SlidingSpeedX * (marioState.IntendedMagnitude / 32.0f) * sideward * 0.05f;

            float newSpeed = (float)Math.Sqrt(
                marioState.SlidingSpeedX * marioState.SlidingSpeedX +
                marioState.SlidingSpeedZ * marioState.SlidingSpeedZ);

            if (oldSpeed > 0.0f && newSpeed > 0.0f)
            {
                marioState.SlidingSpeedX = marioState.SlidingSpeedX * oldSpeed / newSpeed;
                marioState.SlidingSpeedZ = marioState.SlidingSpeedZ * oldSpeed / newSpeed;
            }

            update_sliding_angle(marioState, accel, lossFactor, floor, walls);
        }
示例#15
0
        void calc_new_obj_vel_and_pos_y_underwater(
            TriangleDataModel objFloor, float floorY, float objVelX, float objVelZ, float waterY)
        {
            float floor_nX = objFloor.NormX;
            float floor_nY = objFloor.NormY;
            float floor_nZ = objFloor.NormZ;

            float netYAccel = (1.0f - Buoyancy) * (-1.0f * Gravity);

            YSpeed -= netYAccel;

            if (YSpeed > 75.0)
            {
                YSpeed = 75.0f;
            }
            if (YSpeed < -75.0)
            {
                YSpeed = -75.0f;
            }

            Y += YSpeed;

            if (Y < floorY)
            {
                Y = floorY;

                if (YSpeed < -17.5)
                {
                    YSpeed = -(YSpeed / 2);
                }
                else
                {
                    YSpeed = 0;
                }
            }

            if (HSpeed > 12.5 && (waterY + 30.0f) > Y && (waterY - 30.0f) < Y)
            {
                YSpeed = -YSpeed;
            }

            if ((int)Y >= (int)floorY && (int)Y < (int)floorY + 37)
            {
                objVelX += floor_nX * (floor_nX * floor_nX + floor_nZ * floor_nZ)
                           / (floor_nX * floor_nX + floor_nY * floor_nY + floor_nZ * floor_nZ) * netYAccel * 2;
                objVelZ += floor_nZ * (floor_nX * floor_nX + floor_nZ * floor_nZ)
                           / (floor_nX * floor_nX + floor_nY * floor_nY + floor_nZ * floor_nZ) * netYAccel * 2;
            }

            if (objVelX < 0.000001 && objVelX > -0.000001)
            {
                objVelX = 0;
            }
            if (objVelZ < 0.000001 && objVelZ > -0.000001)
            {
                objVelZ = 0;
            }

            if (YSpeed < 0.000001 && YSpeed > -0.000001)
            {
                YSpeed = 0;
            }

            if (objVelX != 0 || objVelZ != 0)
            {
                Yaw = InGameTrigUtilities.InGameATan(objVelZ, objVelX);
            }

            HSpeed = (float)Math.Sqrt(objVelX * objVelX + objVelZ * objVelZ) * 0.8f;
            YSpeed = (float)(YSpeed * 0.8);
        }
示例#16
0
        // update_air_without_turn
        private static MarioState ComputeAirHSpeed(MarioState initialState, RelativeDirection direction)
        {
            bool longJump = false;
            int  maxSpeed = longJump ? 48 : 32;

            ushort marioAngle = initialState.MarioAngle;
            int    deltaAngleIntendedFacing;

            switch (direction)
            {
            case RelativeDirection.Forward:
                deltaAngleIntendedFacing = 0;
                break;

            case RelativeDirection.Backward:
                deltaAngleIntendedFacing = 32768;
                break;

            case RelativeDirection.Left:
                deltaAngleIntendedFacing = 16384;
                break;

            case RelativeDirection.Right:
                deltaAngleIntendedFacing = 49152;
                break;

            case RelativeDirection.Center:
                deltaAngleIntendedFacing = 0;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            float inputScaledMagnitude = direction == RelativeDirection.Center ? 0 : 32;

            float perpSpeed = 0;
            float newHSpeed = ApproachHSpeed(initialState.HSpeed, 0, 0.35f, 0.35f);

            if (inputScaledMagnitude > 0)
            {
                newHSpeed += (inputScaledMagnitude / 32) * 1.5f * InGameTrigUtilities.InGameCosine(deltaAngleIntendedFacing);
                perpSpeed  = InGameTrigUtilities.InGameSine(deltaAngleIntendedFacing) * (inputScaledMagnitude / 32) * 10;
            }

            if (newHSpeed > maxSpeed)
            {
                newHSpeed -= 1;
            }
            if (newHSpeed < -16)
            {
                newHSpeed += 2;
            }

            float newSlidingXSpeed = InGameTrigUtilities.InGameSine(marioAngle) * newHSpeed;
            float newSlidingZSpeed = InGameTrigUtilities.InGameCosine(marioAngle) * newHSpeed;

            newSlidingXSpeed += perpSpeed * InGameTrigUtilities.InGameSine(marioAngle + 0x4000);
            newSlidingZSpeed += perpSpeed * InGameTrigUtilities.InGameCosine(marioAngle + 0x4000);
            float newXSpeed = newSlidingXSpeed;
            float newZSpeed = newSlidingZSpeed;

            return(new MarioState(
                       initialState.X,
                       initialState.Y,
                       initialState.Z,
                       newXSpeed,
                       initialState.YSpeed,
                       newZSpeed,
                       newHSpeed,
                       initialState.SlidingSpeedX,
                       initialState.SlidingSpeedZ,
                       initialState.SlidingAngle,
                       initialState.MarioAngle,
                       initialState.CameraAngle,
                       initialState,
                       null,
                       initialState.Index + 1));
        }
示例#17
0
        public void update_swimming_speed(int waterLevel)
        {
            float buoyancy = get_buoyancy(waterLevel);

            YSpeed = HSpeed * InGameTrigUtilities.InGameSine(Pitch) + buoyancy;
        }
示例#18
0
        void calc_new_obj_vel_and_pos_y(float objVelX, float objVelZ)
        {
            float floor_nX = 0;
            float floor_nY = 1;
            float floor_nZ = 0;

            // Caps vertical speed with a "terminal velocity".
            YSpeed -= 2.5f;
            if (YSpeed > 75.0)
            {
                YSpeed = 75.0f;
            }
            if (YSpeed < -75.0)
            {
                YSpeed = -75.0f;
            }

            float floorY = Y;

            Y += YSpeed;

            //Snap the object up to the floor.
            if (Y < floorY)
            {
                Y = floorY;

                // Bounces an object if the ground is hit fast enough.
                if (YSpeed < -17.5)
                {
                    YSpeed = -(YSpeed / 2);
                }
                else
                {
                    YSpeed = 0;
                }
            }

            //! (Obj Position Crash) If you got an object with height past 2^31, the game would crash.
            if ((int)Y >= (int)floorY && (int)Y < (int)floorY + 37)
            {
                // Adds horizontal component of gravity for horizontal speed.
                objVelX += floor_nX * (floor_nX * floor_nX + floor_nZ * floor_nZ)
                           / (floor_nX * floor_nX + floor_nY * floor_nY + floor_nZ * floor_nZ) * 2.5f
                           * 2;
                objVelZ += floor_nZ * (floor_nX * floor_nX + floor_nZ * floor_nZ)
                           / (floor_nX * floor_nX + floor_nY * floor_nY + floor_nZ * floor_nZ) * 2.5f
                           * 2;

                if (objVelX < 0.000001 && objVelX > -0.000001)
                {
                    objVelX = 0;
                }
                if (objVelZ < 0.000001 && objVelZ > -0.000001)
                {
                    objVelZ = 0;
                }

                if (objVelX != 0 || objVelZ != 0)
                {
                    Yaw = InGameTrigUtilities.InGameATan(objVelZ, objVelX);
                }

                HSpeed = (float)Math.Sqrt(objVelX * objVelX + objVelZ * objVelZ) * 0.8f;
            }
        }