Dynamic glidespeed

ported from yogstation
This commit is contained in:
QuoteFox
2020-10-05 03:58:10 +01:00
parent 5e298aac96
commit 631090cf04
23 changed files with 113 additions and 36 deletions

View File

@@ -101,3 +101,4 @@
* The arguments are the same when the text and number values are the same and all other values have the same ref
*/
#define ELEMENT_BESPOKE (1 << 1)
#define COMSIG_MOVABLE_UPDATE_GLIDE_SIZE "movable_glide_size" //Called when the movable's glide size is updated: (new_glide_size)

View File

@@ -0,0 +1,16 @@
//The minimum for glide_size to be clamped to.
#define MIN_GLIDE_SIZE 1
//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
// Originally a really stupid /tg/ var that sucked and was really bad and caused it to look horrible. Now it's a way of compensating for time dilation
GLOBAL_VAR_INIT(glide_size_multiplier, 1.0)
///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))

View File

@@ -46,6 +46,7 @@ SUBSYSTEM_DEF(spacedrift)
var/old_dir = AM.dir
var/old_loc = AM.loc
AM.inertia_moving = TRUE
AM.set_glide_size(DELAY_TO_GLIDE_SIZE(AM.inertia_move_delay))
step(AM, AM.inertia_dir)
AM.inertia_moving = FALSE
AM.inertia_next_move = world.time + AM.inertia_move_delay

View File

@@ -110,7 +110,7 @@ SUBSYSTEM_DEF(throwing)
finalize()
return
AM.Move(step, get_dir(AM, step))
AM.Move(step, get_dir(AM, step), DELAY_TO_GLIDE_SIZE(1 / speed))
if (!AM.throwing) // we hit something during our move
finalize(hit = TRUE)

View File

@@ -1,6 +1,6 @@
SUBSYSTEM_DEF(time_track)
name = "Time Tracking"
wait = 600
wait = 100
flags = SS_NO_INIT|SS_NO_TICK_CHECK
runlevels = RUNLEVEL_LOBBY | RUNLEVELS_DEFAULT
@@ -30,6 +30,7 @@ SUBSYSTEM_DEF(time_track)
time_dilation_avg_fast = MC_AVERAGE_FAST(time_dilation_avg_fast, time_dilation_current)
time_dilation_avg = MC_AVERAGE(time_dilation_avg, time_dilation_avg_fast)
time_dilation_avg_slow = MC_AVERAGE_SLOW(time_dilation_avg_slow, time_dilation_avg)
GLOB.glide_size_multiplier = (current_byondtime - last_tick_byond_time) / (current_realtime - last_tick_realtime)
else
first_run = FALSE
last_tick_realtime = current_realtime

View File

@@ -28,10 +28,13 @@
RegisterSignal(target, COMSIG_MOVABLE_MOVED, orbited_spy)
target = target.loc
RegisterSignal(parent, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE, .proc/orbiter_glide_size_update)
/datum/component/orbiter/UnregisterFromParent()
var/atom/target = parent
while(ismovableatom(target))
UnregisterSignal(target, COMSIG_MOVABLE_MOVED)
UnregisterSignal(target, COMSIG_MOVABLE_UPDATE_GLIDE_SIZE)
target = target.loc
/datum/component/orbiter/Destroy()
@@ -81,6 +84,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
@@ -95,6 +104,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)
@@ -139,6 +152,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)

View File

@@ -30,8 +30,12 @@
/datum/component/riding/proc/vehicle_mob_unbuckle(datum/source, mob/living/M, force = FALSE)
restore_position(M)
unequip_buckle_inhands(M)
M.updating_glide_size = TRUE
/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()
@@ -49,8 +53,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()

View File

@@ -29,7 +29,7 @@
var/list/client_mobs_in_contents // This contains all the client mobs within this container
var/list/acted_explosions //for explosion dodging
glide_size = 8
appearance_flags = TILE_BOUND|PIXEL_SCALE
appearance_flags = TILE_BOUND|PIXEL_SCALE|LONG_GLIDE
var/datum/forced_movement/force_moving = null //handled soley by forced_movement.dm
var/floating = FALSE
var/movement_type = GROUND //Incase you have multiple types, you automatically use the most useful one. IE: Skating on ice, flippers on water, flying over chasm/space, etc.
@@ -191,19 +191,21 @@
/atom/movable/proc/Move_Pulled(atom/A)
if(!pulling)
return
return FALSE
if(pulling.anchored || !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
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)
step(pulling, get_dir(pulling.loc, A))
@@ -235,7 +237,7 @@
// 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
@@ -278,7 +280,7 @@
//
////////////////////////////////////////
/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(pulling)
@@ -291,6 +293,9 @@
if(!loc || !newloc)
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
@@ -364,19 +369,32 @@
var/pull_dir = get_dir(src, pulling)
//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.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
if(pulling && get_dist(src, pulling) > 1) //the pullee couldn't keep up
stop_pulling()
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()
//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
/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)
//Called after a successful Move(). By this point, we've already moved
/atom/movable/proc/Moved(atom/OldLoc, Dir, Forced = FALSE)
SEND_SIGNAL(src, COMSIG_MOVABLE_MOVED, OldLoc, Dir, Forced)
@@ -645,16 +663,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

View File

@@ -554,10 +554,12 @@
var/move_result = 0
var/oldloc = loc
if(internal_damage & MECHA_INT_CONTROL_LOST)
set_glide_size(DELAY_TO_GLIDE_SIZE(step_in))
move_result = mechsteprand()
else if(dir != direction && (!strafe || occupant.client.keys_held["Alt"]))
move_result = mechturn(direction)
else
set_glide_size(DELAY_TO_GLIDE_SIZE(step_in))
move_result = mechstep(direction)
if(move_result || loc != oldloc)// halfway done diagonal move still returns false
use_power(step_energy_drain)

View File

@@ -68,6 +68,7 @@
buckled_mobs |= M
M.update_canmove()
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)
@@ -87,6 +88,7 @@
buckled_mob.anchored = initial(buckled_mob.anchored)
buckled_mob.update_canmove()
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)

View File

@@ -129,12 +129,13 @@
if(current_tube == null)
setDir(next_dir)
Move(get_step(loc, dir), dir) // Allow collisions when leaving the tubes.
Move(get_step(loc, dir), dir, DELAY_TO_GLIDE_SIZE(exit_delay)) // Allow collisions when leaving the tubes.
break
last_delay = current_tube.enter_delay(src, next_dir)
sleep(last_delay)
setDir(next_dir)
set_glide_size(DELAY_TO_GLIDE_SIZE(last_delay + exit_delay))
forceMove(next_loc) // When moving from one tube to another, skip collision and such.
if(current_tube && current_tube.should_stop_pod(src, next_dir))

View File

@@ -218,7 +218,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/list/ignoring = list()
var/clientfps = 0
var/clientfps = 60
var/parallax

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 20
#define SAVEFILE_VERSION_MAX 21
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -42,6 +42,8 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
//if your savefile is 3 months out of date, then 'tough shit'.
/datum/preferences/proc/update_preferences(current_version, savefile/S)
if(current_version < 21)
clientfps = 60
return
/datum/preferences/proc/update_character(current_version, savefile/S)

View File

@@ -322,11 +322,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
return
ghostize(0, penalize = TRUE)
/mob/dead/observer/Move(NewLoc, direct)
/mob/dead/observer/Move(NewLoc, direct, glide_size_override = 32)
if(updatedir)
setDir(direct)//only update dir if we actually need it, so overlays won't spin on base sprites that don't have directions of their own
var/oldloc = loc
if(glide_size_override)
set_glide_size(glide_size_override)
if(NewLoc)
forceMove(NewLoc)
update_parallax_contents()

View File

@@ -3,7 +3,7 @@
real_name = "Unknown"
icon = 'icons/mob/human.dmi'
icon_state = "caucasian_m"
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE
appearance_flags = KEEP_TOGETHER|TILE_BOUND|PIXEL_SCALE|LONG_GLIDE
/mob/living/carbon/human/Initialize()
verbs += /mob/living/proc/mob_sleep

View File

@@ -252,8 +252,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
@@ -547,10 +547,10 @@
/mob/living/proc/update_damage_overlays()
return
/mob/living/Move(atom/newloc, direct)
/mob/living/Move(atom/newloc, direct, glide_size_override)
if (buckled && buckled.loc != newloc) //not updating position
if (!buckled.anchored)
return buckled.Move(newloc, direct)
return buckled.Move(newloc, direct, glide_size)
else
return 0

View File

@@ -48,7 +48,7 @@ Difficulty: Medium
vision_range = 10
wander = FALSE
elimination = 1
appearance_flags = 0
appearance_flags = LONG_GLIDE
mouse_opacity = MOUSE_OPACITY_ICON
/mob/living/simple_animal/hostile/megafauna/legion/Initialize()

View File

@@ -123,3 +123,7 @@
var/time_initialized = null
var/mirrorcanloadappearance = FALSE
///Whether the mob is updating glide size when movespeed updates or not
var/updating_glide_size = TRUE

View File

@@ -86,6 +86,7 @@
return FALSE
//We are now going to move
var/add_delay = mob.movement_delay()
mob.set_glide_size(DELAY_TO_GLIDE_SIZE(add_delay * (((direct & 3) && (direct & 12)) ? 2 : 1))) // set it now in case of pulled objects
if(old_move_delay + (add_delay*MOVEMENT_DELAY_BUFFER_DELTA) + MOVEMENT_DELAY_BUFFER > world.time)
move_delay = old_move_delay
else
@@ -109,6 +110,7 @@
if((direct & (direct - 1)) && mob.loc == n) //moved diagonally successfully
add_delay *= 2
move_delay += add_delay
mob.set_glide_size(DELAY_TO_GLIDE_SIZE(add_delay))
if(.) // If mob is null here, we deserve the runtime
if(mob.throwing)
mob.throwing.finalize(FALSE)
@@ -364,14 +366,12 @@
/mob/proc/toggle_move_intent(mob/user)
if(m_intent == MOVE_INTENT_RUN)
m_intent = MOVE_INTENT_WALK
glide_size = 4
else
m_intent = MOVE_INTENT_RUN
glide_size = 8
if(hud_used && hud_used.static_inventory)
for(var/obj/screen/mov_intent/selector in hud_used.static_inventory)
selector.update_icon(src)
/mob/verb/up()
set name = "Move Upwards"
set category = "IC"
@@ -402,4 +402,4 @@
return TRUE
/mob/proc/canZMove(direction, turf/target)
return FALSE
return FALSE

View File

@@ -10,7 +10,7 @@
move_resist = INFINITY
layer = MASSIVE_OBJ_LAYER
light_range = 6
appearance_flags = 0
appearance_flags = LONG_GLIDE
var/current_size = 1
var/allowed_size = 1
var/contained = 1 //Are we going to move around?

View File

@@ -68,15 +68,17 @@
// movement process, persists while holder is moving through pipes
/obj/structure/disposalholder/proc/move()
set waitfor = FALSE
var/ticks = 1
var/obj/structure/disposalpipe/last
while(active)
var/obj/structure/disposalpipe/curr = loc
last = curr
set_glide_size(DELAY_TO_GLIDE_SIZE(ticks * world.tick_lag))
curr = curr.transfer(src)
if(!curr && active)
last.expel(src, loc, dir)
stoplag()
ticks = stoplag()
if(!(count--))
active = FALSE

View File

@@ -999,7 +999,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

View File

@@ -69,6 +69,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"