mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
* Changes obj_break on machines to use parent calls (#46485) The way stat |= BROKEN was done was a mess, this makes everywhere use obj_break with proper parent calls and adds a signal for when a machine enters the broken state. Why It's Good For The Game Better code quality, more signals. * e * Can pass refactor (#48659) * Makes all CanPass procs call parent * Makes CanPass more extendable and gives the mover a say in the matter * Replace CanPass with CanAllowThrough to use the new system Regex replace `(?<!proc)/CanPass\(` => `/CanAllowThrough(` * Simple optimization pass * Adds linting for equipped() pickup() dropped() (#46614) * lint some inventory procs * lineends * f * line end * lineend * fuck * changes per review * does more * Changes power_change() to respect parent calls for toggling NOPOWER (#46486) About The Pull Request Similar to #46485 Now all relevant uses of power_change() call parent, theres a signal sent when a machine changes the NOPOWER flag, all remaining machines that were using power_change() instead of update_icon() have been fixed. Why It's Good For The Game code quality, eventually signal stuff. and signal stuff * Fix Crossed/Entered/Exited/Bump/ui_act parameter casting (#49016) About The Pull Request Detected as part of my work on SpaceManiac/SpacemanDMM#167 * Makes Crossed and Moved should call parent (#49671) * makes setDir shouldcallparent (#49692) * owo * hehe * Update atoms.dm * Update atoms.dm * Update atoms_movable.dm Co-authored-by: spookydonut <github@spooksoftware.com> Co-authored-by: alexkar598 <> Co-authored-by: Emmett Gaines <ninjanomnom@gmail.com>
227 lines
6.5 KiB
Plaintext
227 lines
6.5 KiB
Plaintext
//Designed for things that need precision trajectories like projectiles.
|
|
//Don't use this for anything that you don't absolutely have to use this with (like projectiles!) because it isn't worth using a datum unless you need accuracy down to decimal places in pixels.
|
|
|
|
//You might see places where it does - 16 - 1. This is intentionally 17 instead of 16, because of how byond's tiles work and how not doing it will result in rounding errors like things getting put on the wrong turf.
|
|
|
|
#define RETURN_PRECISE_POSITION(A) new /datum/position(A)
|
|
#define RETURN_PRECISE_POINT(A) new /datum/point(A)
|
|
|
|
#define RETURN_POINT_VECTOR(ATOM, ANGLE, SPEED) (new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED))
|
|
#define RETURN_POINT_VECTOR_INCREMENT(ATOM, ANGLE, SPEED, AMT) (new /datum/point/vector(ATOM, null, null, null, null, ANGLE, SPEED, AMT))
|
|
|
|
/proc/point_midpoint_points(datum/point/a, datum/point/b) //Obviously will not support multiZ calculations! Same for the two below.
|
|
var/datum/point/P = new
|
|
P.x = a.x + (b.x - a.x) / 2
|
|
P.y = a.y + (b.y - a.y) / 2
|
|
P.z = a.z
|
|
return P
|
|
|
|
/proc/pixel_length_between_points(datum/point/a, datum/point/b)
|
|
return sqrt(((b.x - a.x) ** 2) + ((b.y - a.y) ** 2))
|
|
|
|
/proc/angle_between_points(datum/point/a, datum/point/b)
|
|
return ATAN2((b.y - a.y), (b.x - a.x))
|
|
|
|
/datum/position //For positions with map x/y/z and pixel x/y so you don't have to return lists. Could use addition/subtraction in the future I guess.
|
|
var/x = 0
|
|
var/y = 0
|
|
var/z = 0
|
|
var/pixel_x = 0
|
|
var/pixel_y = 0
|
|
|
|
/datum/position/proc/valid()
|
|
return x && y && z && !isnull(pixel_x) && !isnull(pixel_y)
|
|
|
|
/datum/position/New(_x = 0, _y = 0, _z = 0, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/point.
|
|
if(istype(_x, /datum/point))
|
|
var/datum/point/P = _x
|
|
var/turf/T = P.return_turf()
|
|
_x = T.x
|
|
_y = T.y
|
|
_z = T.z
|
|
_pixel_x = P.return_px()
|
|
_pixel_y = P.return_py()
|
|
else if(isatom(_x))
|
|
var/atom/A = _x
|
|
_x = A.x
|
|
_y = A.y
|
|
_z = A.z
|
|
_pixel_x = A.pixel_x
|
|
_pixel_y = A.pixel_y
|
|
x = _x
|
|
y = _y
|
|
z = _z
|
|
pixel_x = _pixel_x
|
|
pixel_y = _pixel_y
|
|
|
|
/datum/position/proc/return_turf()
|
|
return locate(x, y, z)
|
|
|
|
/datum/position/proc/return_px()
|
|
return pixel_x
|
|
|
|
/datum/position/proc/return_py()
|
|
return pixel_y
|
|
|
|
/datum/position/proc/return_point()
|
|
return new /datum/point(src)
|
|
|
|
/datum/point //A precise point on the map in absolute pixel locations based on world.icon_size. Pixels are FROM THE EDGE OF THE MAP!
|
|
var/x = 0
|
|
var/y = 0
|
|
var/z = 0
|
|
|
|
/datum/point/proc/valid()
|
|
return x && y && z
|
|
|
|
/datum/point/proc/copy_to(datum/point/p = new)
|
|
p.x = x
|
|
p.y = y
|
|
p.z = z
|
|
return p
|
|
|
|
/datum/point/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0) //first argument can also be a /datum/position or /atom.
|
|
if(istype(_x, /datum/position))
|
|
var/datum/position/P = _x
|
|
_x = P.x
|
|
_y = P.y
|
|
_z = P.z
|
|
_pixel_x = P.pixel_x
|
|
_pixel_y = P.pixel_y
|
|
else if(istype(_x, /atom))
|
|
var/atom/A = _x
|
|
_x = A.x
|
|
_y = A.y
|
|
_z = A.z
|
|
_pixel_x = A.pixel_x
|
|
_pixel_y = A.pixel_y
|
|
initialize_location(_x, _y, _z, _pixel_x, _pixel_y)
|
|
|
|
/datum/point/proc/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
|
|
if(!isnull(tile_x))
|
|
x = ((tile_x - 1) * world.icon_size) + world.icon_size / 2 + p_x + 1
|
|
if(!isnull(tile_y))
|
|
y = ((tile_y - 1) * world.icon_size) + world.icon_size / 2 + p_y + 1
|
|
if(!isnull(tile_z))
|
|
z = tile_z
|
|
|
|
/datum/point/proc/debug_out()
|
|
var/turf/T = return_turf()
|
|
return "\ref[src] aX [x] aY [y] aZ [z] pX [return_px()] pY [return_py()] mX [T.x] mY [T.y] mZ [T.z]"
|
|
|
|
/datum/point/proc/move_atom_to_src(atom/movable/AM)
|
|
AM.forceMove(return_turf())
|
|
AM.pixel_x = return_px()
|
|
AM.pixel_y = return_py()
|
|
|
|
/datum/point/proc/return_turf()
|
|
return locate(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
|
|
|
|
/datum/point/proc/return_coordinates() //[turf_x, turf_y, z]
|
|
return list(CEILING(x / world.icon_size, 1), CEILING(y / world.icon_size, 1), z)
|
|
|
|
/datum/point/proc/return_position()
|
|
return new /datum/position(src)
|
|
|
|
/datum/point/proc/return_px()
|
|
return MODULUS(x, world.icon_size) - 16 - 1
|
|
|
|
/datum/point/proc/return_py()
|
|
return MODULUS(y, world.icon_size) - 16 - 1
|
|
|
|
/datum/point/vector
|
|
var/speed = 32 //pixels per iteration
|
|
var/iteration = 0
|
|
var/angle = 0
|
|
var/mpx = 0 //calculated x/y movement amounts to prevent having to do trig every step.
|
|
var/mpy = 0
|
|
var/starting_x = 0 //just like before, pixels from EDGE of map! This is set in initialize_location().
|
|
var/starting_y = 0
|
|
var/starting_z = 0
|
|
|
|
/datum/point/vector/New(_x, _y, _z, _pixel_x = 0, _pixel_y = 0, _angle, _speed, initial_increment = 0)
|
|
..()
|
|
initialize_trajectory(_speed, _angle)
|
|
if(initial_increment)
|
|
increment(initial_increment)
|
|
|
|
/datum/point/vector/initialize_location(tile_x, tile_y, tile_z, p_x = 0, p_y = 0)
|
|
. = ..()
|
|
starting_x = x
|
|
starting_y = y
|
|
starting_z = z
|
|
|
|
/datum/point/vector/copy_to(datum/point/vector/v = new)
|
|
..(v)
|
|
v.speed = speed
|
|
v.iteration = iteration
|
|
v.angle = angle
|
|
v.mpx = mpx
|
|
v.mpy = mpy
|
|
v.starting_x = starting_x
|
|
v.starting_y = starting_y
|
|
v.starting_z = starting_z
|
|
return v
|
|
|
|
/datum/point/vector/proc/initialize_trajectory(pixel_speed, new_angle)
|
|
if(!isnull(pixel_speed))
|
|
speed = pixel_speed
|
|
set_angle(new_angle)
|
|
|
|
/datum/point/vector/proc/set_angle(new_angle) //calculations use "byond angle" where north is 0 instead of 90, and south is 180 instead of 270.
|
|
if(isnull(angle))
|
|
return
|
|
angle = new_angle
|
|
update_offsets()
|
|
|
|
/datum/point/vector/proc/update_offsets()
|
|
mpx = sin(angle) * speed
|
|
mpy = cos(angle) * speed
|
|
|
|
/datum/point/vector/proc/set_speed(new_speed)
|
|
if(isnull(new_speed) || speed == new_speed)
|
|
return
|
|
speed = new_speed
|
|
update_offsets()
|
|
|
|
/datum/point/vector/proc/increment(multiplier = 1)
|
|
iteration++
|
|
x += mpx * (multiplier)
|
|
y += mpy * (multiplier)
|
|
|
|
/datum/point/vector/proc/return_vector_after_increments(amount = 7, multiplier = 1, force_simulate = FALSE)
|
|
var/datum/point/vector/v = copy_to()
|
|
if(force_simulate)
|
|
for(var/i in 1 to amount)
|
|
v.increment(multiplier)
|
|
else
|
|
v.increment(multiplier * amount)
|
|
return v
|
|
|
|
/datum/point/vector/proc/on_z_change()
|
|
return
|
|
|
|
/datum/point/vector/processed //pixel_speed is per decisecond.
|
|
var/last_process = 0
|
|
var/last_move = 0
|
|
var/paused = FALSE
|
|
|
|
/datum/point/vector/processed/Destroy()
|
|
. = ..()
|
|
STOP_PROCESSING(SSprojectiles, src)
|
|
|
|
/datum/point/vector/processed/proc/start()
|
|
last_process = world.time
|
|
last_move = world.time
|
|
START_PROCESSING(SSprojectiles, src)
|
|
|
|
/datum/point/vector/processed/process()
|
|
if(paused)
|
|
last_move += world.time - last_process
|
|
last_process = world.time
|
|
return
|
|
var/needed_time = world.time - last_move
|
|
last_process = world.time
|
|
last_move = world.time
|
|
increment(needed_time / SSprojectiles.wait)
|