Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into make-emotes-local
This commit is contained in:
@@ -287,7 +287,7 @@
|
||||
R = rank_names[new_rank]
|
||||
if(!R) //rank with that name doesn't exist yet - make it
|
||||
if(D)
|
||||
R = new(new_rank, D.rank.rights) //duplicate our previous admin_rank but with a new name
|
||||
R = new(new_rank, D.rank.rights, D.rank.exclude_rights, D.rank.can_edit_rights) //duplicate our previous admin_rank but with a new name
|
||||
else
|
||||
R = new(new_rank) //blank new admin_rank
|
||||
GLOB.admin_ranks += R
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
var/ntype = text2num(type)
|
||||
|
||||
//Add client links
|
||||
var/dat = ""
|
||||
var/list/dat = list()
|
||||
if(M.client)
|
||||
dat += "<center><p>Client</p></center>"
|
||||
dat += "<center>"
|
||||
@@ -46,22 +46,27 @@
|
||||
var/log_source = M.logging;
|
||||
if(source == LOGSRC_CLIENT && M.client) //if client doesn't exist just fall back to the mob log
|
||||
log_source = M.client.player_details.logging //should exist, if it doesn't that's a bug, don't check for it not existing
|
||||
|
||||
var/list/concatenated_logs = list()
|
||||
for(var/log_type in log_source)
|
||||
var/nlog_type = text2num(log_type)
|
||||
if(nlog_type & ntype)
|
||||
var/list/reversed = log_source[log_type]
|
||||
if(islist(reversed))
|
||||
reversed = reverseRange(reversed.Copy())
|
||||
for(var/entry in reversed)
|
||||
dat += "<font size=2px><b>[entry]</b><br>[reversed[entry]]</font><br>"
|
||||
dat += "<hr>"
|
||||
var/list/all_the_entrys = log_source[log_type]
|
||||
for(var/entry in all_the_entrys)
|
||||
concatenated_logs += "<b>[entry]</b><br>[all_the_entrys[entry]]"
|
||||
if(length(concatenated_logs))
|
||||
sortTim(concatenated_logs, cmp = /proc/cmp_text_dsc) //Sort by timestamp.
|
||||
dat += "<font size=2px>"
|
||||
dat += concatenated_logs.Join("<br>")
|
||||
dat += "</font>"
|
||||
|
||||
usr << browse(dat, "window=invidual_logging_[key_name(M)];size=600x480")
|
||||
var/datum/browser/popup = new(usr, "invidual_logging_[key_name(M)]", "Individual Logs", 600, 600)
|
||||
popup.set_content(dat.Join())
|
||||
popup.open()
|
||||
|
||||
/proc/individual_logging_panel_link(mob/M, log_type, log_src, label, selected_src, selected_type)
|
||||
var/slabel = label
|
||||
if(selected_type == log_type && selected_src == log_src)
|
||||
slabel = "<b>\[[label]\]</b>"
|
||||
|
||||
//This is necessary because num2text drops digits and rounds on big numbers. If more defines get added in the future it could break again.
|
||||
log_type = num2text(log_type, MAX_BITFLAG_DIGITS)
|
||||
return "<a href='?_src_=holder;[HrefToken()];individuallog=[REF(M)];log_type=[log_type];log_src=[log_src]'>[slabel]</a>"
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
var/list/stored_profiles = list() //list of datum/changelingprofile
|
||||
var/datum/changelingprofile/first_prof = null
|
||||
var/dna_max = 6 //How many extra DNA strands the changeling can store for transformation.
|
||||
var/absorbedcount = 0
|
||||
/// did we get succed by another changeling
|
||||
var/hostile_absorbed = FALSE
|
||||
@@ -252,12 +251,6 @@
|
||||
var/mob/living/carbon/user = owner.current
|
||||
if(!istype(user))
|
||||
return
|
||||
if(stored_profiles.len)
|
||||
var/datum/changelingprofile/prof = stored_profiles[1]
|
||||
if(prof.dna == user.dna && stored_profiles.len >= dna_max)//If our current DNA is the stalest, we gotta ditch it.
|
||||
if(verbose)
|
||||
to_chat(user, "<span class='warning'>We have reached our capacity to store genetic information! We must transform before absorbing more.</span>")
|
||||
return
|
||||
if(!target)
|
||||
return
|
||||
if(NO_DNA_COPY in target.dna.species.species_traits)
|
||||
@@ -317,9 +310,6 @@
|
||||
return prof
|
||||
|
||||
/datum/antagonist/changeling/proc/add_profile(datum/changelingprofile/prof)
|
||||
if(stored_profiles.len > dna_max)
|
||||
if(!push_out_profile())
|
||||
return
|
||||
|
||||
if(!first_prof)
|
||||
first_prof = prof
|
||||
@@ -340,19 +330,6 @@
|
||||
stored_profiles -= prof
|
||||
qdel(prof)
|
||||
|
||||
/datum/antagonist/changeling/proc/get_profile_to_remove()
|
||||
for(var/datum/changelingprofile/prof in stored_profiles)
|
||||
if(!prof.protected)
|
||||
return prof
|
||||
|
||||
/datum/antagonist/changeling/proc/push_out_profile()
|
||||
var/datum/changelingprofile/removeprofile = get_profile_to_remove()
|
||||
if(removeprofile)
|
||||
stored_profiles -= removeprofile
|
||||
return 1
|
||||
return 0
|
||||
|
||||
|
||||
/datum/antagonist/changeling/proc/create_initial_profile()
|
||||
var/mob/living/carbon/C = owner.current //only carbons have dna now, so we have to typecaste
|
||||
if(ishuman(C))
|
||||
|
||||
@@ -679,6 +679,7 @@
|
||||
item_state = "ling_gauntlets"
|
||||
desc = "Rough bone and chitin, pulsing with an abomination barely called \"life\". Good for punching people, not so much for firearms."
|
||||
transfer_prints = TRUE
|
||||
item_flags = DROPDEL // whoops
|
||||
body_parts_covered = ARMS|HANDS
|
||||
cold_protection = ARMS|HANDS
|
||||
min_cold_protection_temperature = GLOVES_MIN_TEMP_PROTECT
|
||||
@@ -691,13 +692,13 @@
|
||||
var/slow_enhancement = 20
|
||||
var/slow_wound_enhancement = 20
|
||||
silent = TRUE
|
||||
inherited_trait = TRAIT_CHUNKYFINGERS // dummy thicc bone hands
|
||||
secondary_trait = TRAIT_MAULER // its only violence from here, bucko
|
||||
inherited_trait = TRAIT_CHUNKYFINGERS // how do you expect to shoot anyone with bone covered hands
|
||||
secondary_trait = TRAIT_MAULER // just punch them idiot
|
||||
var/fasthands = TRUE
|
||||
|
||||
/obj/item/clothing/gloves/fingerless/pugilist/cling/examine(mob/user)
|
||||
. = ..()
|
||||
. += "[src] are formed to allow for [fasthands ? "fast, precise strikes" : "crippling, damaging blows"]."
|
||||
. += "[src] are shaped for [fasthands ? "fast, precise strikes" : "crippling, damaging blows"]."
|
||||
. += "Alt-click them to change between rapid strikes and strong blows."
|
||||
|
||||
/obj/item/clothing/gloves/fingerless/pugilist/cling/AltClick(mob/user)
|
||||
|
||||
@@ -136,6 +136,7 @@
|
||||
hoodtype = /obj/item/clothing/head/hooded/cult_hoodie/eldritch
|
||||
// slightly better than normal cult robes
|
||||
armor = list("melee" = 50, "bullet" = 50, "laser" = 50,"energy" = 50, "bomb" = 35, "bio" = 20, "rad" = 0, "fire" = 20, "acid" = 20)
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
|
||||
/obj/item/reagent_containers/glass/beaker/eldritch
|
||||
name = "flask of eldritch essence"
|
||||
|
||||
@@ -89,6 +89,8 @@
|
||||
|
||||
var/list/char_render_holders //Should only be a key-value list of north/south/east/west = obj/screen.
|
||||
|
||||
/// Last time they used fix macros
|
||||
var/last_macro_fix = 0
|
||||
/// Keys currently held
|
||||
var/list/keys_held = list()
|
||||
/// These next two vars are to apply movement for keypresses and releases made while move delayed.
|
||||
|
||||
@@ -269,7 +269,7 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
prefs = new /datum/preferences(src)
|
||||
GLOB.preferences_datums[ckey] = prefs
|
||||
|
||||
addtimer(CALLBACK(src, .proc/ensure_keys_set), 10) //prevents possible race conditions
|
||||
addtimer(CALLBACK(src, .proc/ensure_keys_set, prefs), 10) //prevents possible race conditions
|
||||
|
||||
prefs.last_ip = address //these are gonna be used for banning
|
||||
prefs.last_id = computer_id //these are gonna be used for banning
|
||||
@@ -443,7 +443,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
if(!winexists(src, "asset_cache_browser")) // The client is using a custom skin, tell them.
|
||||
to_chat(src, "<span class='warning'>Unable to access asset cache browser, if you are using a custom skin file, please allow DS to download the updated version, if you are not, then make a bug report. This is not a critical issue but can cause issues with resource downloading, as it is impossible to know when extra resources arrived to you.</span>")
|
||||
|
||||
|
||||
//This is down here because of the browse() calls in tooltip/New()
|
||||
if(!tooltips)
|
||||
tooltips = new /datum/tooltip(src)
|
||||
@@ -475,11 +474,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
fit_viewport()
|
||||
Master.UpdateTickRate()
|
||||
|
||||
/client/proc/ensure_keys_set()
|
||||
if(SSinput.initialized)
|
||||
set_macros()
|
||||
update_movement_keys(prefs)
|
||||
|
||||
//////////////
|
||||
//DISCONNECT//
|
||||
//////////////
|
||||
@@ -937,23 +931,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
|
||||
y = clamp(y+change, min,max)
|
||||
view_size.setDefault("[x]x[y]")
|
||||
|
||||
/client/proc/update_movement_keys(datum/preferences/direct_prefs)
|
||||
var/datum/preferences/D = prefs || direct_prefs
|
||||
if(!D?.key_bindings)
|
||||
return
|
||||
movement_keys = list()
|
||||
for(var/key in D.key_bindings)
|
||||
for(var/kb_name in D.key_bindings[key])
|
||||
switch(kb_name)
|
||||
if("North")
|
||||
movement_keys[key] = NORTH
|
||||
if("East")
|
||||
movement_keys[key] = EAST
|
||||
if("West")
|
||||
movement_keys[key] = WEST
|
||||
if("South")
|
||||
movement_keys[key] = SOUTH
|
||||
|
||||
/client/proc/change_view(new_size)
|
||||
if (isnull(new_size))
|
||||
CRASH("change_view called without argument.")
|
||||
|
||||
@@ -53,7 +53,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
/// List with a key string associated to a list of keybindings. Unlike key_bindings, this one operates on raw key, allowing for binding a key that triggers regardless of if a modifier is depressed as long as the raw key is sent.
|
||||
var/list/modless_key_bindings = list()
|
||||
|
||||
|
||||
var/tgui_fancy = TRUE
|
||||
var/tgui_lock = TRUE
|
||||
var/windowflashing = TRUE
|
||||
@@ -219,7 +218,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
//we couldn't load character data so just randomize the character appearance + name
|
||||
random_character() //let's create a random character then - rather than a fat, bald and naked man.
|
||||
key_bindings = deepCopyList(GLOB.hotkey_keybinding_list_by_key) // give them default keybinds and update their movement keys
|
||||
C?.update_movement_keys(src)
|
||||
C?.ensure_keys_set(src)
|
||||
real_name = pref_species.random_name(gender,1)
|
||||
if(!loaded_preferences_successfully)
|
||||
save_preferences()
|
||||
@@ -952,7 +951,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/list/default_keys = hotkeys ? kb.hotkey_keys : kb.classic_keys
|
||||
if(LAZYLEN(default_keys))
|
||||
dat += "| Default: [default_keys.Join(", ")]"
|
||||
dat += "</span><span class='independent'>Independent Binding: <a href='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=[current_independent_binding];independent=1'>[current_independent_binding]</a></span>"
|
||||
dat += "</span>"
|
||||
if(!kb.special && !kb.clientside)
|
||||
dat += "<span class='independent'>Independent Binding: <a href='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=[current_independent_binding];independent=1'>[current_independent_binding]</a></span>"
|
||||
dat += "<br>"
|
||||
else
|
||||
var/bound_key = user_binds[kb.name][1]
|
||||
@@ -965,7 +966,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var/list/default_keys = hotkeys ? kb.classic_keys : kb.hotkey_keys
|
||||
if(LAZYLEN(default_keys))
|
||||
dat += "| Default: [default_keys.Join(", ")]"
|
||||
dat += "</span><span class='independent'>Independent Binding: <a href='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=[current_independent_binding];independent=1'>[current_independent_binding]</a></span>"
|
||||
dat += "</span>"
|
||||
if(!kb.special && !kb.clientside)
|
||||
dat += "<span class='independent'>Independent Binding: <a href='?_src_=prefs;preference=keybindings_capture;keybinding=[kb.name];old_key=[current_independent_binding];independent=1'>[current_independent_binding]</a></span>"
|
||||
dat += "<br>"
|
||||
|
||||
dat += "<br><br>"
|
||||
@@ -991,7 +994,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
#undef APPEARANCE_CATEGORY_COLUMN
|
||||
#undef MAX_MUTANT_ROWS
|
||||
|
||||
/datum/preferences/proc/CaptureKeybinding(mob/user, datum/keybinding/kb, old_key, independent = FALSE)
|
||||
/datum/preferences/proc/CaptureKeybinding(mob/user, datum/keybinding/kb, old_key, independent = FALSE, special = FALSE)
|
||||
var/HTML = {"
|
||||
<div id='focus' style="outline: 0;" tabindex=0>Keybinding: [kb.full_name]<br>[kb.description]<br><br><b>Press any key to change<br>Press ESC to clear</b></div>
|
||||
<script>
|
||||
@@ -1003,7 +1006,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
var shift = e.shiftKey ? 1 : 0;
|
||||
var numpad = (95 < e.keyCode && e.keyCode < 112) ? 1 : 0;
|
||||
var escPressed = e.keyCode == 27 ? 1 : 0;
|
||||
var url = 'byond://?_src_=prefs;preference=keybindings_set;keybinding=[kb.name];old_key=[old_key];[independent?"independent=1":""];clear_key='+escPressed+';key='+e.key+';alt='+alt+';ctrl='+ctrl+';shift='+shift+';numpad='+numpad+';key_code='+e.keyCode;
|
||||
var url = 'byond://?_src_=prefs;preference=keybindings_set;keybinding=[kb.name];old_key=[old_key];[independent?"independent=1;":""][special?"special=1;":""]clear_key='+escPressed+';key='+e.key+';alt='+alt+';ctrl='+ctrl+';shift='+shift+';numpad='+numpad+';key_code='+e.keyCode;
|
||||
window.location=url;
|
||||
deedDone = true;
|
||||
}
|
||||
@@ -2354,11 +2357,11 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
|
||||
if("hotkeys")
|
||||
hotkeys = !hotkeys
|
||||
user.client.set_macros()
|
||||
user.client.ensure_keys_set(src)
|
||||
|
||||
if("keybindings_capture")
|
||||
var/datum/keybinding/kb = GLOB.keybindings_by_name[href_list["keybinding"]]
|
||||
CaptureKeybinding(user, kb, href_list["old_key"], text2num(href_list["independent"]))
|
||||
CaptureKeybinding(user, kb, href_list["old_key"], text2num(href_list["independent"]), kb.special || kb.clientside)
|
||||
return
|
||||
|
||||
if("keybindings_set")
|
||||
@@ -2378,9 +2381,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
else
|
||||
if(key_bindings[old_key])
|
||||
key_bindings[old_key] -= kb_name
|
||||
LAZYADD(key_bindings["Unbound"], kb_name)
|
||||
if(!length(key_bindings[old_key]))
|
||||
key_bindings -= old_key
|
||||
user << browse(null, "window=capturekeypress")
|
||||
if(href_list["special"]) // special keys need a full reset
|
||||
user.client.ensure_keys_set(src)
|
||||
save_preferences()
|
||||
ShowChoices(user)
|
||||
return
|
||||
@@ -2415,7 +2421,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
key_bindings -= old_key
|
||||
key_bindings[full_key] += list(kb_name)
|
||||
key_bindings[full_key] = sortList(key_bindings[full_key])
|
||||
user.client.update_movement_keys()
|
||||
if(href_list["special"]) // special keys need a full reset
|
||||
user.client.ensure_keys_set(src)
|
||||
user << browse(null, "window=capturekeypress")
|
||||
save_preferences()
|
||||
|
||||
@@ -2427,7 +2434,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
hotkeys = (choice == "Hotkey")
|
||||
key_bindings = (hotkeys) ? deepCopyList(GLOB.hotkey_keybinding_list_by_key) : deepCopyList(GLOB.classic_keybinding_list_by_key)
|
||||
modless_key_bindings = list()
|
||||
user.client.update_movement_keys()
|
||||
user.client.ensure_keys_set(src)
|
||||
|
||||
if("chat_on_map")
|
||||
chat_on_map = !chat_on_map
|
||||
@@ -2827,17 +2834,21 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
cached_holoform_icons[filter_type] = process_holoform_icon_filter(custom_holoform_icon, filter_type)
|
||||
return cached_holoform_icons[filter_type]
|
||||
|
||||
//Used in savefile update 32, can be removed once that is no longer relevant.
|
||||
/// Resets the client's keybindings. Asks them for which
|
||||
/datum/preferences/proc/force_reset_keybindings()
|
||||
var/choice = tgalert(parent.mob, "Your basic keybindings need to be reset, emotes will remain as before. Would you prefer 'hotkey' or 'classic' mode?", "Reset keybindings", "Hotkey", "Classic")
|
||||
hotkeys = (choice != "Classic")
|
||||
force_reset_keybindings_direct(hotkeys)
|
||||
|
||||
/// Does the actual reset
|
||||
/datum/preferences/proc/force_reset_keybindings_direct(hotkeys = TRUE)
|
||||
var/list/oldkeys = key_bindings
|
||||
key_bindings = (hotkeys) ? deepCopyList(GLOB.hotkey_keybinding_list_by_key) : deepCopyList(GLOB.classic_keybinding_list_by_key)
|
||||
|
||||
for(var/key in oldkeys)
|
||||
if(!key_bindings[key])
|
||||
key_bindings[key] = oldkeys[key]
|
||||
parent.update_movement_keys()
|
||||
parent?.ensure_keys_set(src)
|
||||
|
||||
/datum/preferences/proc/is_loadout_slot_available(slot)
|
||||
var/list/L
|
||||
|
||||
@@ -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 43
|
||||
#define SAVEFILE_VERSION_MAX 46
|
||||
|
||||
/*
|
||||
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
|
||||
@@ -42,7 +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 < 32) //If you remove this, remove force_reset_keybindings() too.
|
||||
if(current_version < 46) //If you remove this, remove force_reset_keybindings() too.
|
||||
force_reset_keybindings_direct(TRUE)
|
||||
addtimer(CALLBACK(src, .proc/force_reset_keybindings), 30) //No mob available when this is run, timer allows user choice.
|
||||
|
||||
/datum/preferences/proc/update_character(current_version, savefile/S)
|
||||
|
||||
@@ -50,7 +50,7 @@ GLOBAL_VAR_INIT(normal_looc_colour, "#6699CC")
|
||||
|
||||
msg = emoji_parse(msg)
|
||||
|
||||
mob.log_talk(msg,LOG_OOC, tag="(LOOC)")
|
||||
mob.log_talk(msg,LOG_OOC, tag="LOOC")
|
||||
|
||||
var/list/heard = get_hearers_in_view(7, get_top_level_mob(src.mob))
|
||||
for(var/mob/M in heard)
|
||||
|
||||
@@ -126,6 +126,7 @@
|
||||
name = "long red forensics coat"
|
||||
icon_state = "forensics_red_long"
|
||||
item_state = "forensics_red_long"
|
||||
mutantrace_variation = STYLE_DIGITIGRADE
|
||||
|
||||
/obj/item/clothing/suit/det_suit/forensicsblue
|
||||
name = "blue forensics coat"
|
||||
@@ -136,6 +137,7 @@
|
||||
name = "long blue forensics coat"
|
||||
icon_state = "forensics_blue_long"
|
||||
item_state = "forensics_blue_long"
|
||||
mutantrace_variation = STYLE_DIGITIGRADE
|
||||
|
||||
|
||||
//Engineering
|
||||
|
||||
@@ -64,6 +64,8 @@
|
||||
icon_state = "labcoat_tox"
|
||||
|
||||
// Departmental Jackets
|
||||
/obj/item/clothing/suit/toggle/labcoat/depjacket
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
|
||||
/obj/item/clothing/suit/toggle/labcoat/depjacket/sci
|
||||
name = "science jacket"
|
||||
|
||||
@@ -99,18 +99,21 @@
|
||||
desc = "A rather impractical, long coat."
|
||||
icon_state = "tailcoat"
|
||||
item_state = "tailcoat"
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
|
||||
/obj/item/clothing/suit/vickyblack
|
||||
name = "black victorian coat"
|
||||
desc = "An overbearing black coat, it looks far older than you are."
|
||||
icon_state = "vickyblack"
|
||||
item_state = "vickyblack"
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
|
||||
/obj/item/clothing/suit/vickyred
|
||||
name = "red victorian coat"
|
||||
desc = "An overbearing red coat, it looks far older than you are."
|
||||
icon_state = "vickyred"
|
||||
item_state = "vickyred"
|
||||
mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON
|
||||
|
||||
/obj/item/clothing/suit/apron/overalls
|
||||
name = "coveralls"
|
||||
|
||||
@@ -168,7 +168,6 @@
|
||||
desc = "A simple, inconspicuous harness replacement for a jumpsuit."
|
||||
icon_state = "gear_harness"
|
||||
item_state = "gear_harness"
|
||||
body_parts_covered = CHEST|GROIN
|
||||
can_adjust = FALSE
|
||||
|
||||
/obj/item/clothing/under/misc/durathread
|
||||
@@ -236,7 +235,7 @@
|
||||
icon_state = "tssuit"
|
||||
item_state = "r_suit"
|
||||
can_adjust = FALSE
|
||||
mutantrace_variation = USE_TAUR_CLIP_MASK
|
||||
mutantrace_variation = STYLE_DIGITIGRADE
|
||||
|
||||
/obj/item/clothing/under/misc/poly_shirt
|
||||
name = "polychromic button-up shirt"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
name = "Spontaneous Brain Trauma"
|
||||
typepath = /datum/round_event/brain_trauma
|
||||
weight = 25
|
||||
min_players = 5
|
||||
|
||||
/datum/round_event_control/brain_trauma/canSpawnEvent(var/players_amt, var/gamemode)
|
||||
var/list/enemy_roles = list("Medical Doctor","Chief Medical Officer","Paramedic")
|
||||
|
||||
@@ -554,7 +554,7 @@ Since Ramadan is an entire month that lasts 29.5 days on average, the start and
|
||||
|
||||
/datum/holiday/xmas
|
||||
name = CHRISTMAS
|
||||
begin_day = 22
|
||||
begin_day = 10
|
||||
begin_month = DECEMBER
|
||||
end_day = 27
|
||||
drone_hat = /obj/item/clothing/head/santa
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#define CATEGORY_MOVEMENT "MOVEMENT"
|
||||
#define CATEGORY_TARGETING "TARGETING"
|
||||
#define CATEGORY_COMBAT "COMBAT"
|
||||
#define CATEGORY_COMMUNICATION "COMMUNICATION"
|
||||
|
||||
#define WEIGHT_HIGHEST 0
|
||||
#define WEIGHT_ADMIN 10
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
var/category = CATEGORY_MISC
|
||||
var/weight = WEIGHT_LOWEST
|
||||
var/keybind_signal
|
||||
/// Is this a clientside verb trigger? If so, this should be set to the name of the verb.
|
||||
var/clientside
|
||||
/// Special - Needs to update special keys on update. clientside implis special.
|
||||
var/special = FALSE
|
||||
|
||||
/datum/keybinding/New()
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/datum/keybinding/client/communication
|
||||
category = CATEGORY_COMMUNICATION
|
||||
|
||||
/datum/keybinding/client/communication/say
|
||||
hotkey_keys = list("CtrlT")
|
||||
name = "Say"
|
||||
full_name = "IC Say"
|
||||
clientside = "say"
|
||||
|
||||
/datum/keybinding/client/communication/ooc
|
||||
hotkey_keys = list("O")
|
||||
name = "OOC"
|
||||
full_name = "Out Of Character Say (OOC)"
|
||||
clientside = "ooc"
|
||||
|
||||
/datum/keybinding/client/communication/me
|
||||
hotkey_keys = list("CtrlM")
|
||||
name = "Me"
|
||||
full_name = "Me (emote)"
|
||||
clientside = "me"
|
||||
|
||||
//indicators
|
||||
/datum/keybinding/client/communication/say_with_indicator
|
||||
hotkey_keys = list("T")
|
||||
classic_keys = list()
|
||||
name = "say_with_indicator"
|
||||
full_name = "Say with Typing Indicator"
|
||||
|
||||
/datum/keybinding/client/communication/say_with_indicator/down(client/user)
|
||||
var/mob/M = user.mob
|
||||
M.say_typing_indicator()
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/client/communication/me_with_indicator
|
||||
hotkey_keys = list("M")
|
||||
classic_keys = list()
|
||||
name = "me_with_indicator"
|
||||
full_name = "Me (emote) with Typing Indicator"
|
||||
|
||||
/datum/keybinding/client/communication/me_with_indicator/down(client/user)
|
||||
var/mob/M = user.mob
|
||||
M.me_typing_indicator()
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/client/communication/subtle
|
||||
hotkey_keys = list("5")
|
||||
classic_keys = list()
|
||||
name = "Subtle"
|
||||
full_name = "Subtle Emote"
|
||||
clientside = "subtle"
|
||||
|
||||
/datum/keybinding/client/communication/subtler
|
||||
hotkey_keys = list("6")
|
||||
classic_keys = list()
|
||||
name = "Subtler"
|
||||
full_name = "Subtler Anti-Ghost Emote"
|
||||
clientside = "subtler-anti-ghost"
|
||||
|
||||
/datum/keybinding/client/communication/whisper
|
||||
hotkey_keys = list("Y")
|
||||
classic_keys = list()
|
||||
name = "Whisper"
|
||||
full_name = "Whisper"
|
||||
clientside = "whisper"
|
||||
|
||||
/datum/keybinding/client/communication/looc
|
||||
hotkey_keys = list("L")
|
||||
classic_keys = list()
|
||||
name = "LOOC"
|
||||
full_name = "Local Out of Character chat"
|
||||
clientside = "looc"
|
||||
@@ -76,59 +76,3 @@
|
||||
else
|
||||
user.mob.dropItemToGround(I)
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/mob/say_with_indicator
|
||||
hotkey_keys = list("CtrlT")
|
||||
classic_keys = list()
|
||||
name = "say_with_indicator"
|
||||
full_name = "Say with Typing Indicator"
|
||||
|
||||
/datum/keybinding/mob/say_with_indicator/down(client/user)
|
||||
var/mob/M = user.mob
|
||||
M.say_typing_indicator()
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/mob/me_with_indicator
|
||||
hotkey_keys = list("CtrlM")
|
||||
classic_keys = list()
|
||||
name = "me_with_indicator"
|
||||
full_name = "Me (emote) with Typing Indicator"
|
||||
|
||||
/datum/keybinding/mob/me_with_indicator/down(client/user)
|
||||
var/mob/M = user.mob
|
||||
M.me_typing_indicator()
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/living/subtle
|
||||
hotkey_keys = list("5")
|
||||
classic_keys = list()
|
||||
name = "subtle_emote"
|
||||
full_name = "Subtle Emote"
|
||||
|
||||
/datum/keybinding/living/subtle/down(client/user)
|
||||
var/mob/living/L = user.mob
|
||||
L.subtle()
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/living/subtler
|
||||
hotkey_keys = list("6")
|
||||
classic_keys = list()
|
||||
name = "subtler_emote"
|
||||
full_name = "Subtler Anti-Ghost Emote"
|
||||
|
||||
/datum/keybinding/living/subtler/down(client/user)
|
||||
var/mob/living/L = user.mob
|
||||
L.subtler()
|
||||
return TRUE
|
||||
|
||||
/datum/keybinding/mob/whisper
|
||||
hotkey_keys = list("Y")
|
||||
classic_keys = list()
|
||||
name = "whisper"
|
||||
full_name = "Whisper"
|
||||
|
||||
/datum/keybinding/mob/whisper/down(client/user)
|
||||
var/mob/M = user.mob
|
||||
M.whisper_keybind()
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/datum/keybinding/movement
|
||||
category = CATEGORY_MOVEMENT
|
||||
weight = WEIGHT_HIGHEST
|
||||
special = TRUE
|
||||
|
||||
/datum/keybinding/movement/north
|
||||
hotkey_keys = list("W", "North")
|
||||
|
||||
@@ -7,10 +7,28 @@
|
||||
/datum/proc/keyLoop(client/user) // Called once every frame
|
||||
//SHOULD_NOT_SLEEP(TRUE)
|
||||
|
||||
/client/verb/fix_macros()
|
||||
set name = "Fix Keybindings"
|
||||
set desc = "Re-assert all your macros/keybindings."
|
||||
set category = "OOC"
|
||||
if(last_macro_fix > (world.time - 10 SECONDS))
|
||||
to_chat(src, "<span class='warning'>It's been too long since the last reset. Wait a while.</span>")
|
||||
return
|
||||
if(!SSinput.initialized)
|
||||
to_chat(src, "<span class='warning'>Input hasn't been initialized yet. Wait a while.</span>")
|
||||
return
|
||||
to_chat(src, "<span class='danger'>Force-reasserting all macros.</span>")
|
||||
last_macro_fix = world.time
|
||||
full_macro_assert()
|
||||
|
||||
// removes all the existing macros
|
||||
/client/proc/erase_all_macros()
|
||||
var/erase_output = ""
|
||||
var/list/macro_set = params2list(winget(src, "default.*", "command")) // The third arg doesnt matter here as we're just removing them all
|
||||
var/list/set_text = list()
|
||||
for(var/macroset in SSinput.all_macrosets)
|
||||
set_text += "[macroset].*"
|
||||
set_text = set_text.Join(";")
|
||||
var/list/macro_set = params2list(winget(src, "[set_text]", "command"))
|
||||
for(var/k in 1 to length(macro_set))
|
||||
var/list/split_name = splittext(macro_set[k], ".")
|
||||
var/macro_name = "[split_name[1]].[split_name[2]]" // [3] is "command"
|
||||
@@ -27,20 +45,74 @@
|
||||
winset(src, "[name]-[REF(key)]", "parent=[name];name=[key];command=[command]")
|
||||
|
||||
/client/proc/set_macros(datum/preferences/prefs_override = prefs)
|
||||
set waitfor = FALSE
|
||||
|
||||
keys_held.Cut()
|
||||
|
||||
erase_all_macros()
|
||||
|
||||
apply_macro_set(SKIN_MACROSET_HOTKEYS, SSinput.macroset_hotkey)
|
||||
apply_macro_set(SKIN_MACROSET_CLASSIC_HOTKEYS, SSinput.macroset_classic_hotkey)
|
||||
apply_macro_set(SKIN_MACROSET_CLASSIC_INPUT, SSinput.macroset_classic_input)
|
||||
|
||||
set_hotkeys_preference()
|
||||
|
||||
/client/proc/set_hotkeys_preference(datum/preferences/prefs_override = prefs)
|
||||
if(prefs_override.hotkeys)
|
||||
winset(src, null, "map.focus=true input.background-color=[COLOR_INPUT_DISABLED] mainwindow.macro=[SKIN_MACROSET_HOTKEYS]")
|
||||
else
|
||||
winset(src, null, "input.focus=true input.background-color=[COLOR_INPUT_ENABLED] mainwindow.macro=[SKIN_MACROSET_CLASSIC_INPUT]")
|
||||
|
||||
/client/proc/ensure_keys_set(datum/preferences/prefs_override = prefs)
|
||||
if(SSinput.initialized)
|
||||
full_macro_assert(prefs_override)
|
||||
|
||||
/client/proc/full_macro_assert(datum/preferences/prefs_override = prefs)
|
||||
INVOKE_ASYNC(src, .proc/do_full_macro_assert, prefs_override) // winget sleeps.
|
||||
|
||||
/client/proc/do_full_macro_assert(datum/preferences/prefs_override = prefs)
|
||||
erase_all_macros()
|
||||
set_macros(prefs_override)
|
||||
update_special_keybinds(prefs_override)
|
||||
set_hotkeys_preference(prefs_override)
|
||||
|
||||
/client/proc/do_special_keybind(key, command, datum/preferences/prefs_override = prefs)
|
||||
var/alt = findtext(key, "Alt")
|
||||
if(alt)
|
||||
key = copytext(key, 1, alt) + copytext(key, alt + 3, 0)
|
||||
var/ctrl = findtext(key, "Ctrl")
|
||||
if(ctrl)
|
||||
key = copytext(key, 1, ctrl) + copytext(key, ctrl + 4, 0)
|
||||
var/shift = findtext(key, "Shift")
|
||||
if(shift)
|
||||
key = copytext(key, 1, shift) + copytext(key, shift + 5, 0)
|
||||
if(!alt && !ctrl && !shift && !prefs_override.hotkeys)
|
||||
return /// DO NOT.
|
||||
key = "[alt? "Alt+":""][ctrl? "Ctrl+":""][shift? "Shift+":""][key]"
|
||||
for(var/macroset in SSinput.all_macrosets)
|
||||
winset(src, "[macroset]-[REF(key)]", "parent=[macroset];name=[key];command=[command]")
|
||||
|
||||
/**
|
||||
* Updates the keybinds for special keys
|
||||
*
|
||||
* Handles adding macros for the keys that need it
|
||||
* And adding movement keys to the clients movement_keys list
|
||||
* At the time of writing this, communication(OOC, Say, IC) require macros
|
||||
* Arguments:
|
||||
* * direct_prefs - the preference we're going to get keybinds from
|
||||
*/
|
||||
/client/proc/update_special_keybinds(datum/preferences/direct_prefs)
|
||||
var/datum/preferences/D = direct_prefs || prefs
|
||||
if(!D?.key_bindings)
|
||||
return
|
||||
movement_keys = list()
|
||||
for(var/key in D.key_bindings)
|
||||
for(var/kb_name in D.key_bindings[key])
|
||||
switch(kb_name)
|
||||
if("North")
|
||||
movement_keys[key] = NORTH
|
||||
if("East")
|
||||
movement_keys[key] = EAST
|
||||
if("West")
|
||||
movement_keys[key] = WEST
|
||||
if("South")
|
||||
movement_keys[key] = SOUTH
|
||||
else
|
||||
var/datum/keybinding/KB = GLOB.keybindings_by_name[kb_name]
|
||||
if(!KB.clientside)
|
||||
continue
|
||||
do_special_keybind(key, KB.clientside, D)
|
||||
|
||||
@@ -258,6 +258,16 @@
|
||||
AM.setDir(current_dir)
|
||||
now_pushing = FALSE
|
||||
|
||||
// i wish to have a "friendly chat" with whoever made three tail variables instead of one
|
||||
/mob/proc/has_tail()
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/has_tail()
|
||||
if(!dna || !dna.features)
|
||||
return ..()
|
||||
var/list/L = dna.features // caches list because i refuse to type it out and because performance
|
||||
return (L["mam_tail"] && (L["mam_tail"] != "None")) || (L["tail_human"] && (L["tail_human"] != "None")) || (L["tail_lizard"] && (L["tail_lizard"] != "None"))
|
||||
|
||||
/mob/living/start_pulling(atom/movable/AM, state, force = pull_force, supress_message = FALSE)
|
||||
if(!AM || !src)
|
||||
return FALSE
|
||||
@@ -296,9 +306,12 @@
|
||||
|
||||
log_combat(src, M, "grabbed", addition="passive grab")
|
||||
if(!supress_message && !(iscarbon(AM) && HAS_TRAIT(src, TRAIT_STRONG_GRABBER)))
|
||||
visible_message("<span class='warning'>[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by [M.p_their()] hands":" passively"]!</span>",
|
||||
"<span class='warning'>You have grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by [M.p_their()] hands":" passively"]!</span>", target = M,
|
||||
target_message = "<span class='warning'>[src] has grabbed you[(zone_selected == "l_arm" || zone_selected == "r_arm")? " by your hands":" passively"]!</span>")
|
||||
if((zone_selected == BODY_ZONE_PRECISE_GROIN) && has_tail() && M.has_tail())
|
||||
visible_message("<span class='warning'>[src] coils [p_their()] tail with [AM], pulling [M.p_them()] along!</span>", "[src] has entwined [p_their()] tail with yours, pulling you along!")
|
||||
else
|
||||
visible_message("<span class='warning'>[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by [M.p_their()] hands":" passively"]!</span>",
|
||||
"<span class='warning'>You have grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by [M.p_their()] hands":" passively"]!</span>", target = M,
|
||||
target_message = "<span class='warning'>[src] has grabbed you[(zone_selected == "l_arm" || zone_selected == "r_arm")? " by your hands":" passively"]!</span>")
|
||||
if(!iscarbon(src))
|
||||
M.LAssailant = null
|
||||
else
|
||||
|
||||
@@ -496,8 +496,19 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
colored_message = "<font color=[color]>[message]</font>"
|
||||
else
|
||||
colored_message = "<font color='[color]'>[message]</font>"
|
||||
|
||||
var/list/timestamped_message = list("[LAZYLEN(logging[smessage_type]) + 1]\[[TIME_STAMP("hh:mm:ss", FALSE)]\] [key_name(src)] [loc_name(src)]" = colored_message)
|
||||
|
||||
//This makes readability a bit better for admins.
|
||||
switch(message_type)
|
||||
if(LOG_WHISPER)
|
||||
colored_message = "(WHISPER) [colored_message]"
|
||||
if(LOG_OOC)
|
||||
colored_message = "(OOC) [colored_message]"
|
||||
if(LOG_ASAY)
|
||||
colored_message = "(ASAY) [colored_message]"
|
||||
if(LOG_EMOTE)
|
||||
colored_message = "(EMOTE) [colored_message]"
|
||||
|
||||
var/list/timestamped_message = list("\[[TIME_STAMP("hh:mm:ss", FALSE)]\] [key_name(src)] [loc_name(src)]" = colored_message)
|
||||
|
||||
logging[smessage_type] += timestamped_message
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
if(GLOB.say_disabled) //This is here to try to identify lag problems
|
||||
to_chat(usr, "<span class='danger'>Speech is currently admin-disabled.</span>")
|
||||
return
|
||||
|
||||
|
||||
if(length(message) > MAX_MESSAGE_LEN)
|
||||
to_chat(usr, message)
|
||||
to_chat(usr, "<span class='danger'>^^^----- The preceeding message has been DISCARDED for being over the maximum length of [MAX_MESSAGE_LEN]. It has NOT been sent! -----^^^</span>")
|
||||
|
||||
@@ -1373,9 +1373,9 @@
|
||||
// next: take from or charge to the cell, depending on how much is left
|
||||
if(cell && !shorted)
|
||||
if(cur_excess > 0)
|
||||
var/charging_cell = min(cur_excess, cell.maxcharge * GLOB.CHARGELEVEL)
|
||||
var/charging_cell = min(min(cur_excess*GLOB.CELLRATE, cell.maxcharge * GLOB.CHARGELEVEL), cell.maxcharge - cell.charge)
|
||||
cell.give(charging_cell)
|
||||
add_load(charging_cell)
|
||||
add_load(charging_cell/GLOB.CELLRATE)
|
||||
lastused_total += charging_cell
|
||||
longtermpower = min(10,longtermpower + 1)
|
||||
if(chargemode && !charging)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// stored_power += (pulse_strength-RAD_COLLECTOR_EFFICIENCY)*RAD_COLLECTOR_COEFFICIENT
|
||||
#define RAD_COLLECTOR_EFFICIENCY 80 // radiation needs to be over this amount to get power
|
||||
#define RAD_COLLECTOR_COEFFICIENT 100
|
||||
#define RAD_COLLECTOR_STORED_OUT 0.04 // (this*100)% of stored power outputted per tick. Doesn't actualy change output total, lower numbers just means collectors output for longer in absence of a source
|
||||
#define RAD_COLLECTOR_COEFFICIENT 125
|
||||
#define RAD_COLLECTOR_STORED_OUT 0.05 // (this*100)% of stored power outputted per tick. Doesn't actualy change output total, lower numbers just means collectors output for longer in absence of a source
|
||||
#define RAD_COLLECTOR_MINING_CONVERSION_RATE 0.00001 //This is gonna need a lot of tweaking to get right. This is the number used to calculate the conversion of watts to research points per process()
|
||||
#define RAD_COLLECTOR_OUTPUT min(stored_power, (stored_power*RAD_COLLECTOR_STORED_OUT)+1000) //Produces at least 1000 watts if it has more than that stored
|
||||
|
||||
|
||||
@@ -35,8 +35,18 @@ All effects don't start immediately, but rather get worse over time; the rate is
|
||||
91-100: Dangerously toxic - swift death
|
||||
*/
|
||||
|
||||
|
||||
/datum/reagent/consumable/ethanol/on_mob_add(mob/living/L, amount)
|
||||
. = ..()
|
||||
if(!iscarbon(L))
|
||||
return
|
||||
|
||||
var/mob/living/carbon/C = L
|
||||
if(HAS_TRAIT(C, TRAIT_ROBOTIC_ORGANISM))
|
||||
C.reagents.remove_reagent(type, amount, FALSE)
|
||||
|
||||
/datum/reagent/consumable/ethanol/on_mob_life(mob/living/carbon/C)
|
||||
if(HAS_TRAIT(C, TRAIT_NO_ALCOHOL))
|
||||
if(HAS_TRAIT(C, TRAIT_TOXIC_ALCOHOL))
|
||||
C.adjustToxLoss((boozepwr/25)*REM,forced = TRUE)
|
||||
else if(C.drunkenness < volume * boozepwr * ALCOHOL_THRESHOLD_MODIFIER)
|
||||
var/booze_power = boozepwr
|
||||
|
||||
@@ -71,21 +71,21 @@
|
||||
// Generate page html
|
||||
var/html = SStgui.basehtml
|
||||
html = replacetextEx(html, "\[tgui:windowId]", id)
|
||||
// Process inline assets
|
||||
var/inline_styles = ""
|
||||
var/inline_scripts = ""
|
||||
// Inject inline assets
|
||||
var/inline_assets_str = ""
|
||||
for(var/datum/asset/asset in inline_assets)
|
||||
var/mappings = asset.get_url_mappings()
|
||||
for(var/name in mappings)
|
||||
var/url = mappings[name]
|
||||
// Not urlencoding since asset strings are considered safe
|
||||
// Not encoding since asset strings are considered safe
|
||||
if(copytext(name, -4) == ".css")
|
||||
inline_styles += "<link rel=\"stylesheet\" type=\"text/css\" href=\"[url]\">\n"
|
||||
inline_assets_str += "Byond.loadCss('[url]', true);\n"
|
||||
else if(copytext(name, -3) == ".js")
|
||||
inline_scripts += "<script type=\"text/javascript\" defer src=\"[url]\"></script>\n"
|
||||
inline_assets_str += "Byond.loadJs('[url]', true);\n"
|
||||
asset.send(client)
|
||||
html = replacetextEx(html, "<!-- tgui:styles -->\n", inline_styles)
|
||||
html = replacetextEx(html, "<!-- tgui:scripts -->\n", inline_scripts)
|
||||
if(length(inline_assets_str))
|
||||
inline_assets_str = "<script>\n" + inline_assets_str + "</script>\n"
|
||||
html = replacetextEx(html, "<!-- tgui:assets -->\n", inline_assets_str)
|
||||
// Inject custom HTML
|
||||
html = replacetextEx(html, "<!-- tgui:html -->\n", inline_html)
|
||||
// Open the window
|
||||
|
||||
Reference in New Issue
Block a user