mirror of
https://github.com/CHOMPStation2/CHOMPStation2.git
synced 2025-12-10 18:22:39 +00:00
Co-authored-by: Selis <selis@xynolabs.com> Co-authored-by: Selis <sirlionfur@hotmail.de> Co-authored-by: Kashargul <144968721+Kashargul@users.noreply.github.com> Co-authored-by: SatinIsle <thesatinisle@gmail.com> Co-authored-by: Heroman <alesha3000@list.ru> Co-authored-by: Casey <a.roaming.shadow@gmail.com> Co-authored-by: Raeschen <rycoop29@gmail.com>
130 lines
3.8 KiB
Plaintext
130 lines
3.8 KiB
Plaintext
/datum/orbit
|
|
var/atom/movable/orbiter
|
|
var/atom/orbiting
|
|
var/lock = TRUE
|
|
var/turf/lastloc
|
|
var/lastprocess
|
|
var/matrix/init_transform
|
|
|
|
/datum/orbit/New(var/atom/movable/_orbiter, var/atom/_orbiting, _lock)
|
|
orbiter = _orbiter
|
|
orbiting = _orbiting
|
|
init_transform = _orbiter.transform
|
|
SSorbit.processing += src
|
|
if (!orbiting.orbiters)
|
|
orbiting.orbiters = list()
|
|
orbiting.orbiters += src
|
|
|
|
if (orbiter.orbiting)
|
|
orbiter.stop_orbit()
|
|
orbiter.orbiting = src
|
|
Check()
|
|
lock = _lock
|
|
|
|
//do not qdel directly, use stop_orbit on the orbiter. (This way the orbiter can bind to the orbit stopping)
|
|
/datum/orbit/Destroy(force = FALSE)
|
|
SSorbit.processing -= src
|
|
if (orbiter)
|
|
orbiter.orbiting = null
|
|
orbiter.transform = init_transform
|
|
orbiter = null
|
|
if (orbiting)
|
|
if (orbiting.orbiters)
|
|
orbiting.orbiters -= src
|
|
if (!orbiting.orbiters.len)//we are the last orbit, delete the list
|
|
orbiting.orbiters = null
|
|
orbiting = null
|
|
return ..()
|
|
|
|
/datum/orbit/proc/Check(turf/targetloc, list/checked_already = list())
|
|
//Avoid infinite loops for people who end up orbiting themself through another orbiter
|
|
checked_already[src] = TRUE
|
|
if (!orbiter)
|
|
qdel(src)
|
|
return
|
|
if (!orbiting)
|
|
orbiter.stop_orbit()
|
|
return
|
|
if (!orbiter.orbiting) //admin wants to stop the orbit.
|
|
orbiter.orbiting = src //set it back to us first
|
|
orbiter.stop_orbit()
|
|
var/atom/movable/AM = orbiting
|
|
if(istype(AM) && AM.orbiting && AM.orbiting.orbiting == orbiter)
|
|
orbiter.stop_orbit()
|
|
return
|
|
lastprocess = world.time
|
|
if (!targetloc)
|
|
targetloc = get_turf(orbiting)
|
|
if (!targetloc || (!lock && orbiter.loc != lastloc && orbiter.loc != targetloc))
|
|
orbiter.stop_orbit()
|
|
return
|
|
orbiter.loc = targetloc
|
|
//TODO-LESH-DEL orbiter.update_parallax_contents()
|
|
orbiter.update_light()
|
|
lastloc = orbiter.loc
|
|
for(var/other_orbit in orbiter.orbiters)
|
|
var/datum/orbit/OO = other_orbit
|
|
//Skip if checked already
|
|
if(checked_already[OO])
|
|
continue
|
|
OO.Check(targetloc, checked_already)
|
|
|
|
/atom/movable/var/datum/orbit/orbiting = null
|
|
/atom/var/list/orbiters = null
|
|
|
|
//A: atom to orbit
|
|
//radius: range to orbit at, radius of the circle formed by orbiting (in pixels)
|
|
//clockwise: whether you orbit clockwise or anti clockwise
|
|
//rotation_speed: how fast to rotate (how many ds should it take for a rotation to complete)
|
|
//rotation_segments: the resolution of the orbit circle, less = a more block circle, this can be used to produce hexagons (6 segments) triangles (3 segments), and so on, 36 is the best default.
|
|
//pre_rotation: Chooses to rotate src 90 degress towards the orbit dir (clockwise/anticlockwise), useful for things to go "head first" like ghosts
|
|
//lockinorbit: Forces src to always be on A's turf, otherwise the orbit cancels when src gets too far away (eg: ghosts)
|
|
|
|
/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE, lockinorbit = FALSE)
|
|
if (!istype(A))
|
|
return
|
|
|
|
new/datum/orbit(src, A, lockinorbit)
|
|
if (!orbiting) //something failed, and our orbit datum deleted itself
|
|
return
|
|
|
|
//Head first!
|
|
if (pre_rotation)
|
|
var/matrix/M = matrix(transform)
|
|
var/pre_rot = 90
|
|
if(!clockwise)
|
|
pre_rot = -90
|
|
M.Turn(pre_rot)
|
|
transform = M
|
|
|
|
var/matrix/shift = matrix(transform)
|
|
shift.Translate(0,radius)
|
|
transform = shift
|
|
|
|
SpinAnimation(rotation_speed, -1, clockwise, rotation_segments)
|
|
|
|
/atom/movable/proc/stop_orbit()
|
|
SpinAnimation(0,0)
|
|
QDEL_NULL(orbiting)
|
|
|
|
/atom/Destroy(force = FALSE)
|
|
. = ..()
|
|
if (orbiters)
|
|
for(var/datum/orbit/O as anything in orbiters)
|
|
if (O.orbiter)
|
|
O.orbiter.stop_orbit()
|
|
|
|
/atom/movable/Destroy(force = FALSE)
|
|
. = ..()
|
|
if (orbiting)
|
|
stop_orbit()
|
|
|
|
/*
|
|
/atom/movable/proc/transfer_observers_to(atom/movable/target)
|
|
if(orbiters)
|
|
for(var/datum/orbit/O as anything in orbiters)
|
|
if(O.orbiter && isobserver(O.orbiter))
|
|
var/mob/dead/observer/D = O.orbiter
|
|
D.ManualFollow(target)
|
|
*/
|