Merge branch 'master' into tgui-alerts-and-what-not

This commit is contained in:
SandPoot
2021-10-11 20:41:56 -03:00
committed by GitHub
25 changed files with 121 additions and 70 deletions

Binary file not shown.

Binary file not shown.

View File

@@ -1,6 +1,12 @@
/datum/config_entry/flag/panic_bunker // prevents people the server hasn't seen before from connecting /datum/config_entry/flag/panic_bunker // prevents people the server hasn't seen before from connecting
/datum/config_entry/number/panic_bunker_living // living time in minutes that a player needs to pass the panic bunker /datum/config_entry/number/panic_bunker_living // living time in minutes that a player needs to pass the panic bunker. they pass **if they are above this amount**
config_entry_value = 0 // default: <= 0 meaning any playtime works. -1 to disable criteria.
integer = TRUE
/datum/config_entry/number/panic_bunker_living_vpn
config_entry_value = 0 // default: <= 0 meaning anytime works. -1 to disable criteria.
integer = TRUE
/datum/config_entry/string/panic_bunker_message /datum/config_entry/string/panic_bunker_message
config_entry_value = "Sorry but the server is currently not accepting connections from never before seen players." config_entry_value = "Sorry but the server is currently not accepting connections from never before seen players."

View File

@@ -33,7 +33,7 @@ SUBSYSTEM_DEF(fail2topic)
while(i <= length(rate_limiting)) while(i <= length(rate_limiting))
var/ip = rate_limiting[i] var/ip = rate_limiting[i]
var/last_attempt = rate_limiting[ip] var/last_attempt = rate_limiting[ip]
if(world.time - last_attempt > rate_limit) if(REALTIMEOFDAY - last_attempt > rate_limit)
rate_limiting -= ip rate_limiting -= ip
fail_counts -= ip fail_counts -= ip
else //if we remove that, and the next element is in its place. check that instead of incrementing. else //if we remove that, and the next element is in its place. check that instead of incrementing.
@@ -58,12 +58,12 @@ SUBSYSTEM_DEF(fail2topic)
if (active_bans[ip]) if (active_bans[ip])
return TRUE return TRUE
rate_limiting[ip] = world.time rate_limiting[ip] = REALTIMEOFDAY
if (isnull(last_attempt)) if (isnull(last_attempt))
return FALSE return FALSE
if (world.time - last_attempt > rate_limit) if (REALTIMEOFDAY - last_attempt > rate_limit)
fail_counts -= ip fail_counts -= ip
return FALSE return FALSE
else else
@@ -83,7 +83,7 @@ SUBSYSTEM_DEF(fail2topic)
if (!enabled) if (!enabled)
return return
active_bans[ip] = world.time active_bans[ip] = REALTIMEOFDAY
fail_counts -= ip fail_counts -= ip
rate_limiting -= ip rate_limiting -= ip

View File

@@ -131,7 +131,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
//Tooltip vars //Tooltip vars
var/force_string //string form of an item's force. Edit this var only to set a custom force string var/force_string //string form of an item's force. Edit this var only to set a custom force string
var/last_force_string_check = 0 var/last_force_string_check = 0
var/tip_timer
var/trigger_guard = TRIGGER_GUARD_NONE var/trigger_guard = TRIGGER_GUARD_NONE
@@ -451,7 +450,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
A.Remove(user) A.Remove(user)
if(item_flags & DROPDEL) if(item_flags & DROPDEL)
qdel(src) qdel(src)
item_flags &= ~IN_INVENTORY DISABLE_BITFIELD(item_flags, IN_INVENTORY)
DISABLE_BITFIELD(item_flags, IN_STORAGE)
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user) SEND_SIGNAL(src, COMSIG_ITEM_DROPPED,user)
remove_outline() remove_outline()
// if(!silent) // if(!silent)
@@ -529,6 +529,8 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
if(item_action_slot_check(slot, user, A)) //some items only give their actions buttons when in a specific slot. if(item_action_slot_check(slot, user, A)) //some items only give their actions buttons when in a specific slot.
A.Grant(user) A.Grant(user)
item_flags |= IN_INVENTORY item_flags |= IN_INVENTORY
if(CHECK_BITFIELD(item_flags, IN_STORAGE)) // Left storage item but somehow has the bitfield active still.
DISABLE_BITFIELD(item_flags, IN_STORAGE)
// if(!initial) // if(!initial)
// if(equip_sound && (slot_flags & slot)) // if(equip_sound && (slot_flags & slot))
// playsound(src, equip_sound, EQUIP_SOUND_VOLUME, TRUE, ignore_walls = FALSE) // playsound(src, equip_sound, EQUIP_SOUND_VOLUME, TRUE, ignore_walls = FALSE)
@@ -885,10 +887,9 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/obj/item/MouseEntered(location, control, params) /obj/item/MouseEntered(location, control, params)
SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_ENTER, location, control, params) SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_ENTER, location, control, params)
if((item_flags & IN_INVENTORY || item_flags & IN_STORAGE) && usr.client.prefs.enable_tips && !QDELETED(src)) if((item_flags & IN_INVENTORY || item_flags & IN_STORAGE) && usr?.client.prefs.enable_tips && !QDELETED(src))
var/timedelay = usr.client.prefs.tip_delay/100 var/timedelay = max(usr.client.prefs.tip_delay * 0.01, 0.01) // I heard multiplying is faster, also runtimes from very low/negative numbers
var/user = usr usr.client.tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, usr), timedelay, TIMER_STOPPABLE)//timer takes delay in deciseconds, but the pref is in milliseconds. dividing by 100 converts it.
tip_timer = addtimer(CALLBACK(src, .proc/openTip, location, control, params, user), timedelay, TIMER_STOPPABLE)//timer takes delay in deciseconds, but the pref is in milliseconds. dividing by 100 converts it.
var/mob/living/L = usr var/mob/living/L = usr
if(istype(L) && (L.incapacitated() || (current_equipped_slot in L.check_obscured_slots()) || !L.canUnEquip(src))) if(istype(L) && (L.incapacitated() || (current_equipped_slot in L.check_obscured_slots()) || !L.canUnEquip(src)))
apply_outline(_size = 3) apply_outline(_size = 3)
@@ -901,7 +902,6 @@ GLOBAL_VAR_INIT(embedpocalypse, FALSE) // if true, all items will be able to emb
/obj/item/MouseExited(location,control,params) /obj/item/MouseExited(location,control,params)
SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_EXIT, location, control, params) SEND_SIGNAL(src, COMSIG_ITEM_MOUSE_EXIT, location, control, params)
deltimer(tip_timer)//delete any in-progress timer if the mouse is moved off the item before it finishes
closeToolTip(usr) closeToolTip(usr)
remove_outline() remove_outline()

View File

@@ -540,11 +540,12 @@
if (!(. & EMP_PROTECT_CONTENTS)) if (!(. & EMP_PROTECT_CONTENTS))
for(var/obj/O in src) for(var/obj/O in src)
O.emp_act(severity) O.emp_act(severity)
if(secure && !broken && !(. & EMP_PROTECT_SELF)) if(!secure || broken)
if(prob(50 / severity)) return
if(prob(severity/2))
locked = !locked locked = !locked
update_icon() update_icon()
if(prob(20 / severity) && !opened) if(prob(severity/5) && !opened)
if(!locked) if(!locked)
open() open()
else else

View File

@@ -187,3 +187,6 @@
var/list/block_parry_hinted = list() var/list/block_parry_hinted = list()
/// moused over objects, currently capped at 7. this is awful, and should be replaced with a component to track it using signals for parrying at some point. /// moused over objects, currently capped at 7. this is awful, and should be replaced with a component to track it using signals for parrying at some point.
var/list/moused_over_objects = list() var/list/moused_over_objects = list()
/// AFK tracking
var/last_activity = 0

View File

@@ -83,6 +83,8 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]") log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]")
return return
last_activity = world.time
//Logs all hrefs //Logs all hrefs
log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]") log_href("[src] (usr:[usr]\[[COORD(usr)]\]) : [hsrc ? "[hsrc] " : ""][href]")
@@ -222,6 +224,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
/////////// ///////////
/client/New(TopicData) /client/New(TopicData)
last_activity = world.time
world.SetConfig("APP/admin", ckey, "role=admin") world.SetConfig("APP/admin", ckey, "role=admin")
var/tdata = TopicData //save this for later use var/tdata = TopicData //save this for later use
TopicData = null //Prevent calls to client.Topic from connect TopicData = null //Prevent calls to client.Topic from connect
@@ -578,9 +581,10 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
//If we aren't an admin, and the flag is set //If we aren't an admin, and the flag is set
if(CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey] && !(ckey in GLOB.bunker_passthrough)) if(CONFIG_GET(flag/panic_bunker) && !holder && !GLOB.deadmins[ckey] && !(ckey in GLOB.bunker_passthrough))
var/living_recs = CONFIG_GET(number/panic_bunker_living) var/living_recs = CONFIG_GET(number/panic_bunker_living)
var/vpn_living_recs = CONFIG_GET(number/panic_bunker_living_vpn)
//Relies on pref existing, but this proc is only called after that occurs, so we're fine. //Relies on pref existing, but this proc is only called after that occurs, so we're fine.
var/minutes = get_exp_living(pure_numeric = TRUE) var/minutes = get_exp_living(pure_numeric = TRUE)
if(minutes <= living_recs) // && !CONFIG_GET(flag/panic_bunker_interview) if((minutes <= living_recs) || (IsVPN() && (minutes < vpn_living_recs)))
var/reject_message = "Failed Login: [key] - Account attempting to connect during panic bunker, but they do not have the required living time [minutes]/[living_recs]" var/reject_message = "Failed Login: [key] - Account attempting to connect during panic bunker, but they do not have the required living time [minutes]/[living_recs]"
log_access(reject_message) log_access(reject_message)
message_admins("<span class='adminnotice'>[reject_message]</span>") message_admins("<span class='adminnotice'>[reject_message]</span>")
@@ -850,6 +854,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
/client/Click(atom/object, atom/location, control, params, ignore_spam = FALSE, extra_info) /client/Click(atom/object, atom/location, control, params, ignore_spam = FALSE, extra_info)
if(last_click > world.time - world.tick_lag) if(last_click > world.time - world.tick_lag)
return return
last_activity = world.time
last_click = world.time last_click = world.time
var/ab = FALSE var/ab = FALSE
var/list/L = params2list(params) var/list/L = params2list(params)
@@ -922,6 +927,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
//checks if a client is afk //checks if a client is afk
//3000 frames = 5 minutes //3000 frames = 5 minutes
/client/proc/is_afk(duration = CONFIG_GET(number/inactivity_period)) /client/proc/is_afk(duration = CONFIG_GET(number/inactivity_period))
var/inactivity = world.time - last_activity
if(inactivity > duration) if(inactivity > duration)
return inactivity return inactivity
return FALSE return FALSE

View File

@@ -0,0 +1,3 @@
/client/proc/IsVPN()
var/datum/ipintel/res = get_ip_intel(address)
return res.intel >= CONFIG_GET(number/ipintel_rating_bad)

View File

@@ -15,6 +15,6 @@
var/indelay = stripped_input(usr, "Enter the tooltip delay in milliseconds (default: 500)", "Enter tooltip delay", "", 10) var/indelay = stripped_input(usr, "Enter the tooltip delay in milliseconds (default: 500)", "Enter tooltip delay", "", 10)
indelay = text2num(indelay) indelay = text2num(indelay)
if(usr)//is this what you mean? if(usr)//is this what you mean?
prefs.tip_delay = indelay prefs.tip_delay = max(indelay, 0.01)
prefs.save_preferences() prefs.save_preferences()
to_chat(usr, "<span class='danger'>Tooltip delay set to [indelay] milliseconds.</span>") to_chat(usr, "<span class='danger'>Tooltip delay set to [indelay] milliseconds.</span>")

View File

@@ -24,7 +24,7 @@
var/pirate_type = PIRATES_ROGUES //pick(PIRATES_ROGUES, PIRATES_SILVERSCALES, PIRATES_DUTCHMAN) var/pirate_type = PIRATES_ROGUES //pick(PIRATES_ROGUES, PIRATES_SILVERSCALES, PIRATES_DUTCHMAN)
var/datum/comm_message/threat_msg = new var/datum/comm_message/threat_msg = new
var/payoff = 0 var/payoff = 0
var/payoff_min = 10000 var/payoff_min = 1000
var/ship_template var/ship_template
var/ship_name = "Space Privateers Association" var/ship_name = "Space Privateers Association"
var/initial_send_time = world.time var/initial_send_time = world.time

View File

@@ -6,6 +6,7 @@
set hidden = TRUE set hidden = TRUE
client_keysend_amount += 1 client_keysend_amount += 1
last_activity = world.time
var/cache = client_keysend_amount var/cache = client_keysend_amount
@@ -89,6 +90,7 @@
set hidden = TRUE set hidden = TRUE
keys_held -= _key keys_held -= _key
last_activity = world.time
var/movement = movement_keys[_key] var/movement = movement_keys[_key]
if(!(next_move_dir_add & movement)) if(!(next_move_dir_add & movement))
next_move_dir_sub |= movement next_move_dir_sub |= movement

View File

@@ -312,12 +312,14 @@ Key procs
/datum/language/machine = list(LANGUAGE_ATOM), /datum/language/machine = list(LANGUAGE_ATOM),
/datum/language/draconic = list(LANGUAGE_ATOM), /datum/language/draconic = list(LANGUAGE_ATOM),
/datum/language/slime = list(LANGUAGE_ATOM), /datum/language/slime = list(LANGUAGE_ATOM),
/datum/language/dwarf = list(LANGUAGE_ATOM)) /datum/language/dwarf = list(LANGUAGE_ATOM),
/datum/language/neokanji = list(LANGUAGE_ATOM))
spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM), spoken_languages = list(/datum/language/common = list(LANGUAGE_ATOM),
/datum/language/machine = list(LANGUAGE_ATOM), /datum/language/machine = list(LANGUAGE_ATOM),
/datum/language/draconic = list(LANGUAGE_ATOM), /datum/language/draconic = list(LANGUAGE_ATOM),
/datum/language/slime = list(LANGUAGE_ATOM), /datum/language/slime = list(LANGUAGE_ATOM),
/datum/language/dwarf = list(LANGUAGE_ATOM)) /datum/language/dwarf = list(LANGUAGE_ATOM),
/datum/language/neokanji = list(LANGUAGE_ATOM))
/datum/language_holder/venus /datum/language_holder/venus
understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM), understood_languages = list(/datum/language/common = list(LANGUAGE_ATOM),

View File

@@ -0,0 +1,25 @@
/datum/language/neokanji
name = "Neo-Kanji"
desc = "A bastardized mixture of many old Earth asian dialects. Famously known as the official language of the spider clan."
speech_verb = "proclaims"
ask_verb = "queries"
exclaim_verb = "declares"
whisper_verb = "hushes"
key = "k"
space_chance = 40
default_priority = 94
flags = TONGUELESS_SPEECH
chooseable_roundstart = TRUE
syllables = list("ka", "ki", "ku", "ke", "ko", "ta",
"chi", "tsu", "te", "to", "sa", "shi",
"su", "se", "so", "na","ni","nu","ne",
"no","n","ha","hi","fu","he","ho","ma",
"mi","mu","me","mo","ya","yu","yo","ra",
"ri","ru","re","ro","wa","wo", "an", "ang",
"ao", "ba", "bai", "ban", "bang", "bao",
"bei", "beng", "chuai", "xing", "xong", "zhao",
"zhong", "xil", "ping", "dang", "guang", "guan",
"jing", "jiao", "kung", "fu", "lo", "wang",
"liu", "ling", "mang", "nong", "peng", "qiong",
"san","tiao", "wan","xiong", "men")
icon_state = "neokanji"

View File

@@ -1055,10 +1055,10 @@
return return
if(!HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN)) //if we want to ignore slowdown from damage, but not from equipment if(!HAS_TRAIT(src, TRAIT_IGNOREDAMAGESLOWDOWN)) //if we want to ignore slowdown from damage, but not from equipment
var/scaling = maxHealth / 100 var/scaling = maxHealth / 100
var/health_deficiency = max(((maxHealth / scaling) - (health / scaling)), (getStaminaLoss()*0.75)) var/health_deficiency = max(((maxHealth / scaling) - (health / scaling)), max(0, getStaminaLoss() - 39))
if(health_deficiency >= 40) if(health_deficiency >= 40)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, (health_deficiency - 15) / 75) add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, health_deficiency / 75)
add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, (health_deficiency - 15) / 25) add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, health_deficiency / 25)
else else
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown) remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown)
remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying) remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying)

View File

@@ -4,6 +4,7 @@
set name = "say_indicator" set name = "say_indicator"
set hidden = TRUE set hidden = TRUE
set category = "IC" set category = "IC"
client?.last_activity = world.time
display_typing_indicator() display_typing_indicator()
var/message = tgui_input_text(usr, null, "say") var/message = tgui_input_text(usr, null, "say")
// If they don't type anything just drop the message. // If they don't type anything just drop the message.
@@ -21,12 +22,16 @@
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>") to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
return return
clear_typing_indicator() // clear it immediately! clear_typing_indicator() // clear it immediately!
client?.last_activity = world.time
say(message) say(message)
/mob/verb/me_typing_indicator() /mob/verb/me_typing_indicator()
set name = "me_indicator" set name = "me_indicator"
set hidden = TRUE set hidden = TRUE
set category = "IC" set category = "IC"
client?.last_activity = world.time
display_typing_indicator() display_typing_indicator()
var/message = tgui_input_message(usr, null, "me") var/message = tgui_input_message(usr, null, "me")
// If they don't type anything just drop the message. // If they don't type anything just drop the message.
@@ -52,6 +57,8 @@
message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN)) message = trim(copytext_char(sanitize(message), 1, MAX_MESSAGE_LEN))
clear_typing_indicator() // clear it immediately! clear_typing_indicator() // clear it immediately!
client?.last_activity = world.time
usr.emote("me",1,message,TRUE) usr.emote("me",1,message,TRUE)
/mob/say_mod(input, message_mode) /mob/say_mod(input, message_mode)
@@ -73,6 +80,7 @@
return lowertext(copytext_char(input, 1, customsayverb)) return lowertext(copytext_char(input, 1, customsayverb))
/mob/proc/whisper_keybind() /mob/proc/whisper_keybind()
client?.last_activity = world.time
var/message = tgui_input_text(src, "", "whisper") var/message = tgui_input_text(src, "", "whisper")
if(!length(message)) if(!length(message))
return return
@@ -89,6 +97,7 @@
whisper(message) whisper(message)
/mob/proc/whisper(message, datum/language/language=null) /mob/proc/whisper(message, datum/language/language=null)
client?.last_activity = world.time
say(message, language) //only living mobs actually whisper, everything else just talks say(message, language) //only living mobs actually whisper, everything else just talks
/mob/proc/say_dead(var/message) /mob/proc/say_dead(var/message)
@@ -132,6 +141,7 @@
message = emoji_parse(message) message = emoji_parse(message)
var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>[name]</span>[alt_name] <span class='message'>[emoji_parse(spanned)]</span></span>" var/rendered = "<span class='game deadsay'><span class='prefix'>DEAD:</span> <span class='name'>[name]</span>[alt_name] <span class='message'>[emoji_parse(spanned)]</span></span>"
log_talk(message, LOG_SAY, tag="DEAD") log_talk(message, LOG_SAY, tag="DEAD")
client?.last_activity = world.time
deadchat_broadcast(rendered, follow_target = src, speaker_key = key) deadchat_broadcast(rendered, follow_target = src, speaker_key = key)
/mob/proc/check_emote(message) /mob/proc/check_emote(message)

View File

@@ -21,3 +21,6 @@
var/obj/item/clothing/suit/space/space_ninja/S = H.wear_suit var/obj/item/clothing/suit/space/space_ninja/S = H.wear_suit
if(istype(H.belt, belt)) if(istype(H.belt, belt))
S.energyKatana = H.belt S.energyKatana = H.belt
H.grant_language(/datum/language/neokanji)
var/datum/language_holder/LH = H.get_language_holder()
LH.selected_language = /datum/language/neokanji

View File

@@ -246,15 +246,15 @@
mag_type = /obj/item/ammo_box/magazine/internal/shot/com mag_type = /obj/item/ammo_box/magazine/internal/shot/com
w_class = WEIGHT_CLASS_NORMAL w_class = WEIGHT_CLASS_NORMAL
var/stock = FALSE var/stock = FALSE
var/extend_sound = 'sound/weapons/batonextend.ogg'
recoil = 5 recoil = 5
spread = 2 spread = 2
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/AltClick(mob/living/user) /obj/item/gun/ballistic/shotgun/automatic/combat/compact/AltClick(mob/living/user)
. = ..() if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)) || item_flags & IN_STORAGE)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)) || item_flags && IN_STORAGE)
return return
toggle_stock(user) toggle_stock(user)
return TRUE . = ..()
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/examine(mob/user) /obj/item/gun/ballistic/shotgun/automatic/combat/compact/examine(mob/user)
. = ..() . = ..()
@@ -272,6 +272,7 @@
to_chat(user, "You fold the stock.") to_chat(user, "You fold the stock.")
recoil = 5 recoil = 5
spread = 2 spread = 2
playsound(src.loc, extend_sound, 50, 1)
update_icon() update_icon()
/obj/item/gun/ballistic/shotgun/automatic/combat/compact/update_icon_state() /obj/item/gun/ballistic/shotgun/automatic/combat/compact/update_icon_state()

View File

@@ -26,6 +26,7 @@
/datum/language/vampiric, /datum/language/vampiric,
/datum/language/dwarf, /datum/language/dwarf,
/datum/language/signlanguage, /datum/language/signlanguage,
/datum/language/neokanji,
)) ))
healing_factor = STANDARD_ORGAN_HEALING*5 //Fast!! healing_factor = STANDARD_ORGAN_HEALING*5 //Fast!!
decay_factor = STANDARD_ORGAN_DECAY/2 decay_factor = STANDARD_ORGAN_DECAY/2
@@ -253,7 +254,8 @@
/datum/language/beachbum, /datum/language/beachbum,
/datum/language/aphasia, /datum/language/aphasia,
/datum/language/sylvan, /datum/language/sylvan,
/datum/language/voltaic /datum/language/voltaic,
/datum/language/neokanji,
)) ))
/obj/item/organ/tongue/ethereal/Initialize(mapload) /obj/item/organ/tongue/ethereal/Initialize(mapload)

View File

@@ -300,6 +300,7 @@
process_status() process_status()
if(src_object.ui_act(act_type, payload, src, state)) if(src_object.ui_act(act_type, payload, src, state))
SStgui.update_uis(src_object) SStgui.update_uis(src_object)
usr?.client?.last_activity = world.time
return FALSE return FALSE
switch(type) switch(type)
if("ready") if("ready")

View File

@@ -119,15 +119,18 @@ Notes:
//Includes sanity checks. //Includes sanity checks.
/proc/closeToolTip(mob/user) /proc/closeToolTip(mob/user)
if(istype(user)) if(istype(user))
if(user.client && user.client.tooltips) if(user.client)
user.client.tooltips.hide() var/client/client = user.client
if(client.tooltips)
client.tooltips.hide()
deltimer(client.tip_timer) //delete any in-progress timer if the mouse is moved off the item before it finishes
client.tip_timer = null
/** /**
* # `get_tooltip_data()` * # `get_tooltip_data()`
* *
* If set, will return a list for the tooltip (that will also be put together in a `Join()`) * If set, will return a list for the tooltip (that will also be put together in a `Join()`)
* However, if returning `null`, falls back to default behavior, which is `examine(src)`, and it will definitely include * However, if returning `null`, the tooltip will not be shown as #14942 changed it.
* images since it is the default behavior
* *
* Though no tooltips will be created for atoms that have `tooltips = FALSE` * Though no tooltips will be created for atoms that have `tooltips = FALSE`
*/ */
@@ -137,11 +140,12 @@ Notes:
/atom/movable/MouseEntered(location, control, params) /atom/movable/MouseEntered(location, control, params)
. = ..() . = ..()
if(tooltips) if(tooltips)
if(!QDELETED(src) && usr.client.prefs.enable_tips) if(!QDELETED(src) && usr?.client.prefs.enable_tips)
var/list/tooltip_data = get_tooltip_data() var/list/tooltip_data = get_tooltip_data()
if(length(tooltip_data)) if(length(tooltip_data))
var/examine_data = tooltip_data.Join("<br />") var/examine_data = tooltip_data.Join("<br />")
openToolTip(usr, src, params, title = name, content = examine_data) var/timedelay = max(usr.client.prefs.tip_delay * 0.01, 0.01) // I heard multiplying is faster, also runtimes from very low/negative numbers
usr.client.tip_timer = addtimer(CALLBACK(GLOBAL_PROC, .proc/openToolTip, usr, src, params, name, examine_data), timedelay, TIMER_STOPPABLE)
/atom/movable/MouseExited(location, control, params) /atom/movable/MouseExited(location, control, params)
. = ..() . = ..()
@@ -150,3 +154,7 @@ Notes:
/client/MouseDown(object, location, control, params) /client/MouseDown(object, location, control, params)
closeToolTip(usr) closeToolTip(usr)
. = ..() . = ..()
/client
/// Timers are now handled by clients, not by doing a mess on the item and multiple people overwriting a single timer on the object, have fun.
var/tip_timer = null

View File

@@ -2,9 +2,12 @@
## Requires database ## Requires database
#PANIC_BUNKER #PANIC_BUNKER
## If a player connects during a bunker with less then or this amount of living time (Minutes), we deny the connection ## If a player connects during a bunker with less then or this amount of living time (Minutes), we deny the connection. Set to -1 to disable criteria.
#PANIC_BUNKER_LIVING 90 #PANIC_BUNKER_LIVING 90
## The above but for VPN connections. Set to -1 to disable criteria. You can set the above to disabled and set this to only enforce bunker on VPNs.
#PANIC_BUNKER_LIVING_VPN 120
## The message the Panic Bunker gives when someone is rejected by it ## The message the Panic Bunker gives when someone is rejected by it
## %minutes% is replaced with PANIC_BUNKER_LIVING on runtime, remove it if you don't want this ## %minutes% is replaced with PANIC_BUNKER_LIVING on runtime, remove it if you don't want this
#PANIC_BUNKER_MESSAGE Sorry, but the server is currently not accepting connections from players with less than %minutes% minutes of living time. #PANIC_BUNKER_MESSAGE Sorry, but the server is currently not accepting connections from players with less than %minutes% minutes of living time.

View File

@@ -508,33 +508,6 @@
<ul class="changes bgimages16"> <ul class="changes bgimages16">
<li class="rscadd">lets felinids, humans and moths have markings</li> <li class="rscadd">lets felinids, humans and moths have markings</li>
</ul> </ul>
<h2 class="date">09 August 2021</h2>
<h3 class="author">Arturlang updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Nanite machinery overlays should now work properly</li>
<li class="code_imp">screen objects are now atom/movables instead</li>
<li class="code_imp">Update appearance is used for updating atoms now instead of update_icon and such</li>
</ul>
<h3 class="author">BlueWildrose updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">Old gateway animation is back. Feedback is given that the gateway is open again.</li>
</ul>
<h3 class="author">Putnam3145 updated:</h3>
<ul class="changes bgimages16">
<li class="balance">Rod of asclepius can now be used for revival surgery</li>
</ul>
<h2 class="date">07 August 2021</h2>
<h3 class="author">BlueWildrose updated:</h3>
<ul class="changes bgimages16">
<li class="bugfix">The black dress, pink tutu, the bathrobe, the kimonos, and the qipaos no longer have a missing pixel when wearing them with the feminine bodytype. They're also no longer adjustable (they have no sprite for the adjusted variant and therefore it would just make an error if someone did that.)</li>
</ul>
<h3 class="author">Putnam3145 updated:</h3>
<ul class="changes bgimages16">
<li class="balance">Supernova rad storms are now half as likely per tick tweak: Supernovae don't announce they're ending if they never announced they're starting tweak: Supernovae say explicitly no rad storms can happen if they can't</li>
<li class="rscadd">Monstermos is back</li>
</ul>
</div> </div>
<b>GoonStation 13 Development Team</b> <b>GoonStation 13 Development Team</b>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@@ -1980,6 +1980,7 @@
#include "code\modules\client\client_colour.dm" #include "code\modules\client\client_colour.dm"
#include "code\modules\client\client_defines.dm" #include "code\modules\client\client_defines.dm"
#include "code\modules\client\client_procs.dm" #include "code\modules\client\client_procs.dm"
#include "code\modules\client\client_vpn_detect.dm"
#include "code\modules\client\message.dm" #include "code\modules\client\message.dm"
#include "code\modules\client\player_details.dm" #include "code\modules\client\player_details.dm"
#include "code\modules\client\preferences.dm" #include "code\modules\client\preferences.dm"
@@ -2427,6 +2428,7 @@
#include "code\modules\language\monkey.dm" #include "code\modules\language\monkey.dm"
#include "code\modules\language\mushroom.dm" #include "code\modules\language\mushroom.dm"
#include "code\modules\language\narsian.dm" #include "code\modules\language\narsian.dm"
#include "code\modules\language\neokanji.dm"
#include "code\modules\language\ratvarian.dm" #include "code\modules\language\ratvarian.dm"
#include "code\modules\language\signlanguage.dm" #include "code\modules\language\signlanguage.dm"
#include "code\modules\language\slime.dm" #include "code\modules\language\slime.dm"