mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-26 14:39:58 +01:00
[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:
committed by
Emmett Gaines
parent
5c4bbdb984
commit
798bbd3d99
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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,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"
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user