diff --git a/code/__HELPERS/type2type.dm b/code/__HELPERS/type2type.dm index 006c6a516f7..4bb4860e797 100644 --- a/code/__HELPERS/type2type.dm +++ b/code/__HELPERS/type2type.dm @@ -109,6 +109,21 @@ if (degree < 315) return WEST return NORTH|WEST +/** + * Returns the trigonometric degrees of a given direction. + * Use this instead of dir2angle if you're using cos() and sin() to generate a velocity or acceleration vector. + */ +/proc/dir2degree(var/D) + switch (D) // Starting from 0 on a Unit Circle + if (EAST) return 0 + if (NORTHEAST) return 45 + if (NORTH) return 90 + if (NORTHWEST) return 135 + if (WEST) return 180 + if (SOUTHWEST) return 225 + if (SOUTH) return 270 + if (SOUTHEAST) return 315 + // Returns the north-zero clockwise angle in degrees, given a direction /proc/dir2angle(var/D) switch (D) diff --git a/code/modules/overmap/ships/ship.dm b/code/modules/overmap/ships/ship.dm index 1f4de2c40ea..d7f47ac5604 100644 --- a/code/modules/overmap/ships/ship.dm +++ b/code/modules/overmap/ships/ship.dm @@ -199,25 +199,38 @@ return round(num_burns/burns_per_grid) /obj/effect/overmap/visitable/ship/proc/decelerate() - if(((speed[1]) || (speed[2])) && can_burn()) - if (speed[1]) - adjust_speed(-SIGN(speed[1]) * min(get_burn_acceleration(),abs(speed[1])), 0) - if (speed[2]) - adjust_speed(0, -SIGN(speed[2]) * min(get_burn_acceleration(),abs(speed[2]))) + if(can_burn()) + // Pythagorean theorem gives us the magnitude of the ship's velocity, which is always an absolute value. + // This is also the mathematical definition for Vector.size + var/magnitude_velocity = ((speed[1] ** 2) + (speed[2] **2)) ** (1/2) + + // Get the magnitude of our desired change in velocity + var/alpha = min(get_burn_acceleration(), magnitude_velocity) + + // First we "Normalize" the current velocity to get the direction without a distance + // Then we take the exact negative of this direction to get its true opposite + // And finally multiply by the magnitude of our desired delta_v to get the true delta_v + var/delta_x = -(speed[1] / magnitude_velocity) * alpha + var/delta_y = -(speed[2] / magnitude_velocity) * alpha + + adjust_speed(delta_x, delta_y) last_burn = world.time /obj/effect/overmap/visitable/ship/proc/accelerate(direction, accel_limit) if(can_burn()) last_burn = world.time + + // Get our "Alpha" value as the ship's desired acceleration (change in Velocity) var/acceleration = min(get_burn_acceleration(), accel_limit) - if(direction & EAST) - adjust_speed(acceleration, 0) - if(direction & WEST) - adjust_speed(-acceleration, 0) - if(direction & NORTH) - adjust_speed(0, acceleration) - if(direction & SOUTH) - adjust_speed(0, -acceleration) + + // Convert from cardinal directions to an angle (in degrees) + // !This is absolutely terrible and should at some point be swapped to Radians + // !But for now it's "Okay" until overmap ships are updated to work on time differentials properly. + var/theta = dir2degree(direction) + + // This comes from the actual definition of a Vector2d, , where theta is an Angle, and A is a constant multiplier that traditionally represents distance. + // In this case A is our DeltaVelocity, or Acceleration. + adjust_speed(acceleration * cos(theta), acceleration * sin(theta)) /obj/effect/overmap/visitable/ship/process() ..() diff --git a/html/changelogs/hellfirejag-fix-ship-math.yml b/html/changelogs/hellfirejag-fix-ship-math.yml new file mode 100644 index 00000000000..ad2bedecf90 --- /dev/null +++ b/html/changelogs/hellfirejag-fix-ship-math.yml @@ -0,0 +1,4 @@ +author: Hellfirejag +delete-after: True +changes: + - bugfix: "Fixed math errors in overmap ship math that caused severe precision errors when accelerating diagonally."