mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-28 10:31:59 +00:00
## About The Pull Request theres an issue with SSinput calculating the average_click_delay that made it skip queuing clicks much faster than it should have. now it should work. also moves everything to deciseconds for consistency (except for the statpanel display, which changes it to per second). also i increased the click delay threshold to 1 tick in deciseconds because really we should only be refusing to queue if SSinput is being skipped for whatever reason or each tick is receiving massive non input overtime ## Why It's Good For The Game feex queuing clicks to lower overtime when the server is overloaded ## Changelog 🆑 fix: queuing clicks should work correctly now /🆑
101 lines
3.9 KiB
Plaintext
101 lines
3.9 KiB
Plaintext
VERB_MANAGER_SUBSYSTEM_DEF(input)
|
|
name = "Input"
|
|
init_order = INIT_ORDER_INPUT
|
|
init_stage = INITSTAGE_EARLY
|
|
flags = SS_TICKER
|
|
priority = FIRE_PRIORITY_INPUT
|
|
runlevels = RUNLEVELS_DEFAULT | RUNLEVEL_LOBBY
|
|
|
|
use_default_stats = FALSE
|
|
|
|
var/list/macro_set
|
|
|
|
///running average of how many clicks inputted by a player the server processes every second. used for the subsystem stat entry
|
|
var/clicks_per_second = 0
|
|
///count of how many clicks onto atoms have elapsed before being cleared by fire(). used to average with clicks_per_second.
|
|
var/current_clicks = 0
|
|
///acts like clicks_per_second but only counts the clicks actually processed by SSinput itself while clicks_per_second counts all clicks
|
|
var/delayed_clicks_per_second = 0
|
|
///running average of how many movement iterations from player input the server processes every second. used for the subsystem stat entry
|
|
var/movements_per_second = 0
|
|
///running average of the amount of real time clicks take to truly execute after the command is originally sent to the server.
|
|
///if a click isnt delayed at all then it counts as 0 deciseconds.
|
|
var/average_click_delay = 0
|
|
|
|
/datum/controller/subsystem/verb_manager/input/Initialize()
|
|
setup_default_macro_sets()
|
|
|
|
initialized = TRUE
|
|
|
|
refresh_client_macro_sets()
|
|
|
|
return SS_INIT_SUCCESS
|
|
|
|
// This is for when macro sets are eventualy datumized
|
|
/datum/controller/subsystem/verb_manager/input/proc/setup_default_macro_sets()
|
|
macro_set = list(
|
|
"Any" = "\"KeyDown \[\[*\]\]\"",
|
|
"Any+UP" = "\"KeyUp \[\[*\]\]\"",
|
|
"Back" = "\".winset \\\"input.text=\\\"\\\"\\\"\"",
|
|
"Tab" = "\".winset \\\"input.focus=true?map.focus=true:input.focus=true\\\"\"",
|
|
"Escape" = "Reset-Held-Keys",
|
|
)
|
|
|
|
// Badmins just wanna have fun ♪
|
|
/datum/controller/subsystem/verb_manager/input/proc/refresh_client_macro_sets()
|
|
var/list/clients = GLOB.clients
|
|
for(var/i in 1 to clients.len)
|
|
var/client/user = clients[i]
|
|
user.set_macros()
|
|
|
|
/datum/controller/subsystem/verb_manager/input/can_queue_verb(datum/callback/verb_callback/incoming_callback, control)
|
|
//make sure the incoming verb is actually something we specifically want to handle
|
|
if(control != "mapwindow.map")
|
|
return FALSE
|
|
|
|
if(average_click_delay > MAXIMUM_CLICK_LATENCY || !..())
|
|
current_clicks++
|
|
average_click_delay = MC_AVG_FAST_UP_SLOW_DOWN(average_click_delay, 0)
|
|
return FALSE
|
|
|
|
return TRUE
|
|
|
|
///stupid workaround for byond not recognizing the /atom/Click typepath for the queued click callbacks
|
|
/atom/proc/_Click(location, control, params)
|
|
if(usr)
|
|
Click(location, control, params)
|
|
|
|
/datum/controller/subsystem/verb_manager/input/fire()
|
|
..()
|
|
|
|
var/moves_this_run = 0
|
|
for(var/mob/user in GLOB.keyloop_list)
|
|
moves_this_run += user.focus?.keyLoop(user.client)//only increments if a player moves due to their own input
|
|
|
|
movements_per_second = MC_AVG_SECONDS(movements_per_second, moves_this_run, wait TICKS)
|
|
|
|
/datum/controller/subsystem/verb_manager/input/run_verb_queue()
|
|
var/deferred_clicks_this_run = 0 //acts like current_clicks but doesnt count clicks that dont get processed by SSinput
|
|
|
|
for(var/datum/callback/verb_callback/queued_click as anything in verb_queue)
|
|
if(!istype(queued_click))
|
|
stack_trace("non /datum/callback/verb_callback instance inside SSinput's verb_queue!")
|
|
continue
|
|
|
|
average_click_delay = MC_AVG_FAST_UP_SLOW_DOWN(average_click_delay, TICKS2DS((DS2TICKS(world.time) - queued_click.creation_time)))
|
|
queued_click.InvokeAsync()
|
|
|
|
current_clicks++
|
|
deferred_clicks_this_run++
|
|
|
|
verb_queue.Cut() //is ran all the way through every run, no exceptions
|
|
|
|
clicks_per_second = MC_AVG_SECONDS(clicks_per_second, current_clicks, wait SECONDS)
|
|
delayed_clicks_per_second = MC_AVG_SECONDS(delayed_clicks_per_second, deferred_clicks_this_run, wait SECONDS)
|
|
current_clicks = 0
|
|
|
|
/datum/controller/subsystem/verb_manager/input/stat_entry(msg)
|
|
. = ..()
|
|
. += "M/S:[round(movements_per_second,0.01)] | C/S:[round(clicks_per_second,0.01)] ([round(delayed_clicks_per_second,0.01)] | CD: [round(average_click_delay / (1 SECONDS),0.01)])"
|
|
|