[ready] Smooth-ish move rising: revengeance (#47817)

* Smooth movement

Squashed commit:

[870d550fff] updates a variable name to not shadow a parent variable

[65131a9a4b] redundant

[7c85f7b87e] override based pulling and pushing

[60a9760c4b] unnecessary when it's done via an override

[0a67dfb3cb] removes a redundant manual override

[7f25104fed] pushing

[2bfd9973eb] eh

[fca7155245] cast properly

[ad4b9ad8ab] compile fix

[c28fde4bfb] some wonkiness with pulling fixed

[0e028d30b3] buckling fix + finer rounding

[8f93df2bbe] dragging + buckling fixes

[1541e1ce78] small optimization

[bda72345dd] smoother movement

fix to dragging being fucky

vehicle fix

orbiter fix

eof newline

cleanup

comment cleanup

stupid hack

bunch of tweaks/hacks + 60 fps default oh god

potential fix for orbiter issues (in a shitty way)

early override for some cases

unset orbit

multiply instead of add offset

no

no more timescale scaling and higher multiplier

meant to include this in last commit

comment

* clamp to 6, 1.25 multiplier

* (poorly) fixed buckles not always propagating

* get rid of some debug prints whoops

* fixes an infinite loop

* syntax + update savefile instead of interpreting 0 different

* uuuh
This commit is contained in:
Rob Bailey
2019-12-05 02:34:46 +00:00
committed by Emmett Gaines
parent 5c4bbdb984
commit 798bbd3d99
13 changed files with 100 additions and 27 deletions
+1
View File
@@ -185,6 +185,7 @@
#define HEARING_SPANS 6
#define HEARING_MESSAGE_MODE 7 */
#define COMSIG_MOVABLE_DISPOSING "movable_disposing" //called when the movable is added to a disposal holder object for disposal movement: (obj/structure/disposalholder/holder, obj/machinery/disposal/source)
#define COMSIG_MOVABLE_UPDATE_GLIDE_SIZE "movable_glide_size" //Called when the movable's glide size is updated: (new_glide_size)
// /mob signals
#define COMSIG_MOB_DEATH "mob_death" //from base of mob/death(): (gibbed)
+18
View File
@@ -0,0 +1,18 @@
//The minimum for glide_size to be clamped to.
//Clamped to 5 because byond's glide size scaling is actually just completely broken and "step"
//movement is better than dealing with the awful camera juddering
#define MIN_GLIDE_SIZE 5
//The maximum for glide_size to be clamped to.
//This shouldn't be higher than the icon size, and generally you shouldn't be changing this, but it's here just in case.
#define MAX_GLIDE_SIZE 32
//This is a global so it can be changed in game, if you want to make this a bit faster you can make it a constant/define directly in the code
GLOBAL_VAR_INIT(glide_size_multiplier, 1.25)
///Broken down, here's what this does:
/// divides the world icon_size (32) by delay divided by ticklag to get the number of pixels something should be moving each tick.
/// The division result is given a min value of 1 to prevent obscenely slow glide sizes from being set
/// Then that's multiplied by the global glide size multiplier. 1.25 by default feels pretty close to spot on. This is just to try to get byond to behave.
/// The whole result is then clamped to within the range above.
/// Not very readable but it works
#define DELAY_TO_GLIDE_SIZE(delay) (CLAMP(((32 / max(delay / world.tick_lag, 1)) * GLOB.glide_size_multiplier), MIN_GLIDE_SIZE, MAX_GLIDE_SIZE))
+18
View File
@@ -28,10 +28,13 @@
if(ismovableatom(target))
tracker = new(target, CALLBACK(src, .proc/move_react))
RegisterSignal(parent, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE, .proc/orbiter_glide_size_update)
/datum/component/orbiter/UnregisterFromParent()
var/atom/target = parent
target.orbiters = null
QDEL_NULL(tracker)
UnregisterSignal(parent, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE)
/datum/component/orbiter/Destroy()
var/atom/master = parent
@@ -79,6 +82,12 @@
orbiter.transform = shift
orbiter.SpinAnimation(rotation_speed, -1, clockwise, rotation_segments, parallel = FALSE)
if(ismob(orbiter))
var/mob/M = orbiter
M.updating_glide_size = FALSE
if(ismovableatom(parent))
var/atom/movable/AM = parent
orbiter.glide_size = AM.glide_size
//we stack the orbits up client side, so we can assign this back to normal server side without it breaking the orbit
orbiter.transform = initial_transform
@@ -94,6 +103,10 @@
orbiters -= orbiter
orbiter.stop_orbit(src)
orbiter.orbiting = null
if(ismob(orbiter))
var/mob/M = orbiter
M.updating_glide_size = TRUE
M.glide_size = 8
if(!refreshing && !length(orbiters) && !QDELING(src))
qdel(src)
@@ -124,6 +137,11 @@
return
end_orbit(orbiter)
/datum/component/orbiter/proc/orbiter_glide_size_update(datum/source, target)
for(var/orbiter in orbiters)
var/atom/movable/AM = orbiter
AM.glide_size = target
/////////////////////
/atom/movable/proc/orbit(atom/A, radius = 10, clockwise = FALSE, rotation_speed = 20, rotation_segments = 36, pre_rotation = TRUE)
+8 -2
View File
@@ -32,10 +32,14 @@
var/atom/movable/AM = parent
restore_position(M)
unequip_buckle_inhands(M)
M.updating_glide_size = TRUE
if(del_on_unbuckle_all && !AM.has_buckled_mobs())
qdel(src)
/datum/component/riding/proc/vehicle_mob_buckle(datum/source, mob/living/M, force = FALSE)
var/atom/movable/AM = parent
M.set_glide_size(AM.glide_size)
M.updating_glide_size = FALSE
handle_vehicle_offsets()
/datum/component/riding/proc/handle_vehicle_layer()
@@ -53,8 +57,10 @@
/datum/component/riding/proc/vehicle_moved(datum/source)
var/atom/movable/AM = parent
for(var/i in AM.buckled_mobs)
ride_check(i)
AM.set_glide_size(DELAY_TO_GLIDE_SIZE(vehicle_move_delay))
for(var/mob/M in AM.buckled_mobs)
ride_check(M)
M.set_glide_size(AM.glide_size)
handle_vehicle_offsets()
handle_vehicle_layer()
+33 -16
View File
@@ -167,20 +167,21 @@
/atom/movable/proc/Move_Pulled(atom/A)
if(!pulling)
return
return FALSE
if(pulling.anchored || pulling.move_resist > move_force || !pulling.Adjacent(src))
stop_pulling()
return
return FALSE
if(isliving(pulling))
var/mob/living/L = pulling
if(L.buckled && L.buckled.buckle_prevents_pull) //if they're buckled to something that disallows pulling, prevent it
stop_pulling()
return
return FALSE
if(A == loc && pulling.density)
return
if(!Process_Spacemove(get_dir(pulling.loc, A)))
return
step(pulling, get_dir(pulling.loc, A))
return FALSE
var/move_dir = get_dir(pulling.loc, A)
if(!Process_Spacemove(move_dir))
return FALSE
pulling.Move(get_step(pulling.loc, move_dir), move_dir, glide_size)
return TRUE
/mob/living/Move_Pulled(atom/A)
@@ -209,11 +210,18 @@
if(pulledby && moving_diagonally != FIRST_DIAG_STEP && get_dist(src, pulledby) > 1) //separated from our puller and not in the middle of a diagonal move.
pulledby.stop_pulling()
/atom/movable/proc/set_glide_size(target = 8)
SEND_SIGNAL(src, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE, target)
glide_size = target
for(var/atom/movable/AM in buckled_mobs)
AM.set_glide_size(target)
////////////////////////////////////////
// Here's where we rewrite how byond handles movement except slightly different
// To be removed on step_ conversion
// All this work to prevent a second bump
/atom/movable/Move(atom/newloc, direct=0)
/atom/movable/Move(atom/newloc, direct=0, glide_size_override = 0)
. = FALSE
if(!newloc || newloc == loc)
return
@@ -256,10 +264,10 @@
continue
var/atom/movable/thing = i
thing.Crossed(src)
//
////////////////////////////////////////
/atom/movable/Move(atom/newloc, direct)
/atom/movable/Move(atom/newloc, direct, glide_size_override = 0)
var/atom/movable/pullee = pulling
var/turf/T = loc
if(!moving_from_pull)
@@ -268,6 +276,10 @@
return FALSE
var/atom/oldloc = loc
//Early override for some cases like diagonal movement
if(glide_size_override)
set_glide_size(glide_size_override)
if(loc != newloc)
if (!(direct & (direct - 1))) //Cardinal move
. = ..()
@@ -339,13 +351,18 @@
//puller and pullee more than one tile away or in diagonal position
if(get_dist(src, pulling) > 1 || (moving_diagonally != SECOND_DIAG_STEP && ((pull_dir - 1) & pull_dir)))
pulling.moving_from_pull = src
pulling.Move(T, get_dir(pulling, T)) //the pullee tries to reach our previous position
pulling.Move(T, get_dir(pulling, T), glide_size) //the pullee tries to reach our previous position
pulling.moving_from_pull = null
check_pulling()
//glide_size strangely enough can change mid movement animation and update correctly while the animation is playing
//This means that if you don't override it late like this, it will just be set back by the movement update that's called when you move turfs.
if(glide_size_override)
set_glide_size(glide_size_override)
last_move = direct
setDir(direct)
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc,direct)) //movement failed due to buckled mob(s)
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc, direct, glide_size_override)) //movement failed due to buckled mob(s)
return FALSE
//Called after a successful Move(). By this point, we've already moved
@@ -621,16 +638,16 @@
SSthrowing.currentrun[src] = TT
TT.tick()
/atom/movable/proc/handle_buckled_mob_movement(newloc,direct)
/atom/movable/proc/handle_buckled_mob_movement(newloc, direct, glide_size_override)
for(var/m in buckled_mobs)
var/mob/living/buckled_mob = m
if(!buckled_mob.Move(newloc, direct))
if(!buckled_mob.Move(newloc, direct, glide_size_override))
forceMove(buckled_mob.loc)
last_move = buckled_mob.last_move
inertia_dir = last_move
buckled_mob.inertia_dir = last_move
return 0
return 1
return FALSE
return TRUE
/atom/movable/proc/force_pushed(atom/movable/pusher, force = MOVE_FORCE_DEFAULT, direction)
return FALSE
+2
View File
@@ -73,6 +73,7 @@
buckled_mobs |= M
M.update_mobility()
M.throw_alert("buckled", /obj/screen/alert/restrained/buckled)
M.set_glide_size(glide_size)
post_buckle_mob(M)
SEND_SIGNAL(src, COMSIG_MOVABLE_BUCKLE, M, force)
@@ -92,6 +93,7 @@
buckled_mob.anchored = initial(buckled_mob.anchored)
buckled_mob.update_mobility()
buckled_mob.clear_alert("buckled")
buckled_mob.set_glide_size(DELAY_TO_GLIDE_SIZE(buckled_mob.total_multiplicative_slowdown()))
buckled_mobs -= buckled_mob
SEND_SIGNAL(src, COMSIG_MOVABLE_UNBUCKLE, buckled_mob, force)
+1 -1
View File
@@ -1465,7 +1465,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
preferred_map = maplist[pickedmap]
if ("clientfps")
var/desiredfps = input(user, "Choose your desired fps. (0 = synced with server tick rate (currently:[world.fps]))", "Character Preference", clientfps) as null|num
var/desiredfps = input(user, "Choose your desired fps. (0 = synced with server tickrate (currently:[world.fps]))", "Character Preference", clientfps) as null|num
if (!isnull(desiredfps))
clientfps = desiredfps
parent.fps = desiredfps
+5 -1
View File
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
#define SAVEFILE_VERSION_MAX 29
#define SAVEFILE_VERSION_MAX 30
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -47,6 +47,10 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
parent.update_movement_keys()
to_chat(parent, "<span class='userdanger'>Empty keybindings, setting default to [hotkeys ? "Hotkey" : "Classic"] mode</span>")
if(current_version < 30)
if(clientfps == 0)
clientfps = 60
/datum/preferences/proc/update_character(current_version, savefile/S)
if(current_version < 19)
pda_style = "mono"
+5 -4
View File
@@ -236,8 +236,8 @@
var/current_dir
if(isliving(AM))
current_dir = AM.dir
if(step(AM, t))
step(src, t)
if(AM.Move(get_step(AM.loc, t), t, glide_size))
Move(get_step(loc, t), t)
if(current_dir)
AM.setDir(current_dir)
now_pushing = FALSE
@@ -609,7 +609,7 @@
/mob/living/proc/update_damage_overlays()
return
/mob/living/Move(atom/newloc, direct)
/mob/living/Move(atom/newloc, direct, glide_size_override)
if(lying)
if(direct & EAST)
lying = 90
@@ -619,7 +619,8 @@
lying_prev = lying
if (buckled && buckled.loc != newloc) //not updating position
if (!buckled.anchored)
return buckled.Move(newloc, direct)
buckled.glide_size = glide_size //This should be being set by the override in the move below but it's not and I'm fucking suffering
return buckled.Move(newloc, direct, glide_size_override)
else
return FALSE
+6 -2
View File
@@ -190,7 +190,7 @@
///Allows a datum to intercept all click calls this mob is the source of
var/datum/click_intercept
///THe z level this mob is currently registered in
///The z level this mob is currently registered in
var/registered_z = null
var/memory_throttle_time = 0
@@ -204,7 +204,11 @@
var/bloody_hands = 0
var/datum/focus //What receives our keyboard inputs. src by default
/// What receives our keyboard inputs. src by default
var/datum/focus
/// Used for tracking last uses of emotes for cooldown purposes
var/list/emotes_used
///Whether the mob is updating glide size when movespeed updates or not
var/updating_glide_size = TRUE
+2
View File
@@ -110,6 +110,8 @@ Key procs
continue
. += amt
cached_multiplicative_slowdown = .
if(updating_glide_size)
set_glide_size(DELAY_TO_GLIDE_SIZE(cached_multiplicative_slowdown))
///Get the move speed modifiers list of the mob
/mob/proc/get_movespeed_modifiers()
@@ -1007,7 +1007,6 @@
throwforce = 10
throw_speed = 0.1
throw_range = 28
glide_size = 2
flags_1 = CONDUCT_1
max_amount = 60
turf_type = /turf/open/floor/sepia
+1
View File
@@ -70,6 +70,7 @@
#include "code\__DEFINES\mobs.dm"
#include "code\__DEFINES\monkeys.dm"
#include "code\__DEFINES\move_force.dm"
#include "code\__DEFINES\movement.dm"
#include "code\__DEFINES\movespeed_modification.dm"
#include "code\__DEFINES\nanites.dm"
#include "code\__DEFINES\networks.dm"