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); }
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))); }
// 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); }
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); }
void obj_update_pos_vel_xz() { float xVel = HSpeed * InGameTrigUtilities.InGameSine(Yaw); float zVel = HSpeed * InGameTrigUtilities.InGameCosine(Yaw); X += xVel; Z += zVel; }
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(); }
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); }
// 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); }
// 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)); }
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); }
// 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); }
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; } }
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); }
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); }
// 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)); }
public void update_swimming_speed(int waterLevel) { float buoyancy = get_buoyancy(waterLevel); YSpeed = HSpeed * InGameTrigUtilities.InGameSine(Pitch) + buoyancy; }
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; } }