diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm
index f447c378f65..88d3d1dd6b7 100644
--- a/code/__HELPERS/unsorted.dm
+++ b/code/__HELPERS/unsorted.dm
@@ -1346,30 +1346,31 @@ B --><-- A
var/myid = orbitid
if (orbiting)
stop_orbit()
- //sadly this is the only way to ensure the original orbit proc stops and resets the atom's transform.
- sleep(1)
+ //sadly this is the only way to ensure the original orbit proc stops
+ //and resets the atom's transform before we continue.
+ //time is based on the sleep in the loop and the time for the final animation of initial_transform.
+ sleep(2.6+world.tick_lag)
if (orbiting || !istype(A) || orbitid != myid) //post sleep re-check
return
orbiting = A
var/lastloc = loc
var/angle = 0
var/matrix/initial_transform = matrix(transform)
- spawn
- while(orbiting && orbiting.loc && orbitid == myid && (!lockinorbit || loc == lastloc))
- loc = get_turf(orbiting.loc)
- lastloc = loc
- angle += angle_increment
- var/matrix/shift = matrix(initial_transform)
- shift.Translate(radius,0)
- if(clockwise)
- shift.Turn(angle)
- else
- shift.Turn(-angle)
- animate(src,transform = shift,2)
+ while(orbiting && orbiting.loc && orbitid == myid && (lockinorbit || loc == lastloc))
+ loc = get_turf(orbiting.loc)
+ lastloc = loc
+ angle += angle_increment
- sleep(0.6) //the effect breaks above 0.6 delay
- animate(src,transform = initial_transform,2)
+ var/matrix/shift = matrix(initial_transform)
+ shift.Translate(radius,0)
+ if(clockwise)
+ shift.Turn(angle)
+ else
+ shift.Turn(-angle)
+ animate(src,transform = shift,2)
+ sleep(0.6) //the effect breaks above 0.6 delay
+ animate(src,transform = initial_transform,2)
/atom/movable/proc/stop_orbit()
diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm
index b6649aada21..194277ff065 100644
--- a/code/modules/mob/dead/observer/observer.dm
+++ b/code/modules/mob/dead/observer/observer.dm
@@ -206,12 +206,26 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
// This is the ghost's follow verb with an argument
/mob/dead/observer/proc/ManualFollow(atom/movable/target)
- if(target && target != src)
- if(orbiting && orbiting == target)
- return
- src << "Now orbiting [target]."
- orbit(target,24,0)
+ if (!istype(target))
+ return
+ var/icon/I = icon(target.icon,target.icon_state,target.dir)
+
+ var/orbitsize = (I.Width()+I.Height())*0.5
+ orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25)
+
+ if(orbiting != target)
+ src << "Now orbiting [target]."
+
+ orbit(target,orbitsize,0)
+
+/mob/dead/observer/orbit()
+ ..()
+ //restart our floating animation after orbit is done.
+ sleep 2 //orbit sets up a 2ds animation when it finishes, so we wait for that to end
+ if (!orbiting) //make sure another orbit hasn't started
+ pixel_y = 0
+ animate(src, pixel_y = 2, time = 10, loop = -1)
/mob/dead/observer/verb/jumptomob() //Moves the ghost instead of just changing the ghosts's eye -Nodrak
set category = "Ghost"
diff --git a/html/changelogs/mso-orbittweaks.yml b/html/changelogs/mso-orbittweaks.yml
new file mode 100644
index 00000000000..4e9f91034b0
--- /dev/null
+++ b/html/changelogs/mso-orbittweaks.yml
@@ -0,0 +1,10 @@
+author: MrStonedOne
+
+delete-after: True
+
+changes:
+ - rscdel: "Removed feature where quick consecutive ghost orbits while moving could be used to fuck with your sprite"
+ - bugfix: "Fixed ghosts losing floating animation when returning from an orbit"
+ - bugfix: "Fixed logic error that prevented orbit's automatic cancel when the orbiting thing moved in certain situations."
+ - rscadd: "Ghost Orbit size now changes based on the icon size of the thing they are orbiting (for that sweet sweet singulo orbiting action)"
+ - tweak: "Removed needless checks in ghost orbit, you can now orbit yourself and restart an orbit around the thing you are already orbiting"