diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 97b2237a934..551be3fc4ea 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -33,8 +33,12 @@ #define AMBIENT_OCCLUSION 2097152 #define AZERTY 4194304 #define NUMPAD_TARGET 8388606 +#define CHAT_GHOSTPDA 16777212‬ #define TOGGLES_DEFAULT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_LOOC|MEMBER_PUBLIC|DONATOR_PUBLIC|NUMPAD_TARGET) -#define TOGGLES_TOTAL 16777212 // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined. +#define TOGGLES_TOTAL 33554424‬ // If you add or remove a preference toggle above, make sure you update this define with the total value of the toggles combined. + + +#define TOGGLES_DEFAULT (CHAT_OOC|CHAT_DEAD|CHAT_GHOSTEARS|CHAT_GHOSTSIGHT|CHAT_PRAYER|CHAT_RADIO|CHAT_LOOC|MEMBER_PUBLIC|DONATOR_PUBLIC|AMBIENT_OCCLUSION|CHAT_GHOSTPDA) // Admin attack logs filter system, see /proc/add_attack_logs and /proc/msg_admin_attack #define ATKLOG_ALL 0 diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index 6b5807deaef..9e01753d492 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -353,12 +353,12 @@ var/middle = L.len / 2 + 1 // Copy is first,second-1 return mergeLists(sortList(L.Copy(0,middle)), sortList(L.Copy(middle))) //second parameter null = to end of list -//Mergsorge: uses sortList() but uses the var's name specifically. This should probably be using mergeAtom() instead +//Mergsorge: uses sortAssoc() but uses the var's name specifically. This should probably be using mergeAtom() instead /proc/sortNames(var/list/L) var/list/Q = new() for(var/atom/x in L) Q[x.name] = x - return sortList(Q) + return sortAssoc(Q) /proc/mergeLists(var/list/L, var/list/R) var/Li=1 diff --git a/code/_onclick/hud/screen_objects.dm b/code/_onclick/hud/screen_objects.dm index c583617ac23..91c8d6250b4 100644 --- a/code/_onclick/hud/screen_objects.dm +++ b/code/_onclick/hud/screen_objects.dm @@ -453,7 +453,6 @@ /obj/screen/healths/corgi icon = 'icons/mob/screen_corgi.dmi' - /obj/screen/healths/guardian name = "summoner health" icon = 'icons/mob/guardian.dmi' @@ -467,14 +466,18 @@ screen_loc = ui_healthdoll var/list/cached_healthdoll_overlays = list() // List of icon states (strings) for overlays +/obj/screen/healthdoll/Click() + if(ishuman(usr)) + var/mob/living/carbon/H = usr + H.check_self_for_injuries() + /obj/screen/component_button var/obj/screen/parent - /obj/screen/component_button/Initialize(mapload, obj/screen/new_parent) . = ..() parent = new_parent /obj/screen/component_button/Click(params) if(parent) - parent.component_click(src, params) \ No newline at end of file + parent.component_click(src, params) diff --git a/code/datums/helper_datums/input.dm b/code/datums/helper_datums/input.dm index 3bcf9509e37..19205a4ab62 100644 --- a/code/datums/helper_datums/input.dm +++ b/code/datums/helper_datums/input.dm @@ -1,71 +1,90 @@ /proc/input_async(mob/user=usr, prompt, list/choices) - var/datum/async_input/A = new(choices, prompt) - A.show(user) + var/datum/async_input/A = new(choices, prompt, , user) + A.show() return A /proc/input_ranked_async(mob/user=usr, prompt="Order by greatest to least preference", list/choices) - var/datum/async_input/ranked/A = new(choices, prompt) - A.show(user) + var/datum/async_input/ranked/A = new(choices, prompt, "ranked_input", user) + A.show() + return A + +/proc/input_autocomplete_async(mob/user=usr, prompt="Enter text: ", list/choices) + var/datum/async_input/autocomplete/A = new(choices, prompt, "ac_input", user) + A.show() return A /datum/async_input var/datum/browser/popup + // If associative list, key will be used for display, but the final result will be the value var/list/choices + var/datum/callback/onCloseCb var/flash = TRUE var/immediate_submit = FALSE var/prompt var/result = null var/style = "text-align: center;" + var/mob/user var/window_id var/height = 200 var/width = 400 -/datum/async_input/New(list/new_choices, new_prompt="Pick an option:", new_window_id="async_input") +/datum/async_input/New(list/new_choices, new_prompt="Pick an option:", new_window_id="async_input", mob/new_user=usr) choices = new_choices prompt = new_prompt window_id = new_window_id + user = new_user + popup = new(user, window_id, , width, height, src) /datum/async_input/proc/close() if(popup) popup.close() + if(result && choices[result]) + result = choices[result] + if(onCloseCb) + onCloseCb.Invoke(result) return result -/datum/async_input/proc/show(mob/user) - var/dat = create_ui(user) - popup = new(user, window_id, , width, height, src) - popup.set_content(dat) +// Callback function should take the result as the last argument +/datum/async_input/proc/on_close(var/datum/callback/cb) + onCloseCb = cb + +/datum/async_input/proc/show() + popup.set_content(create_ui()) if(flash && result == null) window_flash(user.client) popup.open() -/datum/async_input/proc/create_ui(mob/user) +/datum/async_input/proc/create_ui() var/dat = "
" - dat += render_prompt(user) - dat += render_choices(user) + dat += render_prompt() + dat += render_choices() dat += "
" dat += "
" - dat += button("Submit", "submit=1", , result == null && !immediate_submit) + dat += render_buttons() dat += "
" return dat -/datum/async_input/proc/render_prompt(mob/user) +/datum/async_input/proc/render_prompt() return "

[prompt]

" -/datum/async_input/proc/render_choices(mob/user) +/datum/async_input/proc/render_choices() var/dat = " " for(var/choice in choices) dat += button(choice, "choice=[choice]", choice == result) dat += " " return dat -/datum/async_input/proc/button(label, topic, on=FALSE, disabled=FALSE) +/datum/async_input/proc/render_buttons() + return button("Submit", "submit=1", , result == null && !immediate_submit) + +/datum/async_input/proc/button(label, topic, on=FALSE, disabled=FALSE, id="") var/class = "" if(on) class = "linkOn" if(disabled) class = "linkOff" topic = "" - return "[label]" + return "[label]" /datum/async_input/Topic(href, href_list) if(href_list["submit"] || href_list["close"]) @@ -74,14 +93,14 @@ if(href_list["choice"]) result = href_list["choice"] - show(usr) + show() return /datum/async_input/ranked height = 400 immediate_submit = TRUE -/datum/async_input/ranked/render_choices(mob/user) +/datum/async_input/ranked/render_choices() var/dat = "
" dat += "" for(var/i = 1, i <= choices.len, i++) @@ -103,13 +122,47 @@ if(href_list["upvote"]) var/index = text2num(href_list["upvote"]) choices.Swap(index, index - 1) - show(usr) + show() return if(href_list["downvote"]) var/index = text2num(href_list["downvote"]) choices.Swap(index, index + 1) - show(usr) + show() + return + + ..() + +/datum/async_input/autocomplete + immediate_submit = TRUE + height = 150 + +/datum/async_input/autocomplete/New() + ..() + popup.add_script("autocomplete.js", 'html/browser/autocomplete.js') + +/datum/async_input/autocomplete/render_prompt() + return "" + +/datum/async_input/autocomplete/render_choices() + var/dat = "" + dat += "" + for(var/choice in choices) + dat += "" + return dat + +/datum/async_input/autocomplete/render_buttons() + var/dat = button("Submit", "", , result == null && !immediate_submit, "submit-button") + dat += button("Cancel", "close=1") + return dat + +/datum/async_input/autocomplete/Topic(href, href_list) + if(href_list["submit"]) + // Entering an invalid choice is the same as canceling + if(href_list["submit"] in choices) + result = href_list["submit"] + close() return ..() diff --git a/code/datums/uplink_item.dm b/code/datums/uplink_item.dm index b6167338ad3..79c68a2a2d2 100644 --- a/code/datums/uplink_item.dm +++ b/code/datums/uplink_item.dm @@ -1627,7 +1627,8 @@ GLOBAL_LIST_INIT(uplink_items, subtypesof(/datum/uplink_item)) reference = "CIB" item = /obj/item/storage/box/cyber_implants/bundle cost = 40 - + gamemodes = list(/datum/game_mode/nuclear) + /datum/uplink_item/bundles_TC/medical name = "Medical Bundle" desc = "The support specialist: Aid your fellow operatives with this medical bundle. Contains a tactical medkit, \ diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index 3b67153e0b8..86c245a191f 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -58,6 +58,10 @@ pulledby = null return ..() +//Returns an atom's power cell, if it has one. Overload for individual items. +/atom/movable/proc/get_cell() + return + /atom/movable/proc/start_pulling(atom/movable/AM, state, force = move_force, supress_message = FALSE) if(QDELETED(AM)) return FALSE diff --git a/code/game/machinery/defib_mount.dm b/code/game/machinery/defib_mount.dm index 49c5fbcbce6..77d68590efa 100644 --- a/code/game/machinery/defib_mount.dm +++ b/code/game/machinery/defib_mount.dm @@ -15,6 +15,10 @@ var/obj/item/defibrillator/defib //this mount's defibrillator var/clamps_locked = FALSE //if true, and a defib is loaded, it can't be removed without unlocking the clamps +/obj/machinery/defibrillator_mount/get_cell() + if(defib) + return defib.get_cell() + /obj/machinery/defibrillator_mount/New(location, direction, building = 0) ..() @@ -28,7 +32,6 @@ pixel_x = (dir & 3)? 0 : (dir == 4 ? -30 : 30) pixel_y = (dir & 3)? (dir == 1 ? -30 : 30) : 0 - /obj/machinery/defibrillator_mount/loaded/New() //loaded subtype for mapping use ..() defib = new/obj/item/defibrillator/loaded(src) diff --git a/code/game/machinery/floodlight.dm b/code/game/machinery/floodlight.dm index c11b3d7a725..68e22f2e8c7 100644 --- a/code/game/machinery/floodlight.dm +++ b/code/game/machinery/floodlight.dm @@ -12,6 +12,8 @@ var/open = FALSE var/brightness_on = 14 +/obj/machinery/floodlight/get_cell() + return cell /obj/machinery/floodlight/Initialize() . = ..() diff --git a/code/game/machinery/recharger.dm b/code/game/machinery/recharger.dm index 81006be3fdd..b8f2d153d9f 100644 --- a/code/game/machinery/recharger.dm +++ b/code/game/machinery/recharger.dm @@ -8,6 +8,7 @@ idle_power_usage = 4 active_power_usage = 250 var/obj/item/charging = null + var/using_power = FALSE var/list/allowed_devices = list(/obj/item/gun/energy, /obj/item/melee/baton, /obj/item/modular_computer, /obj/item/rcs, /obj/item/bodyanalyzer) var/icon_state_off = "rechargeroff" var/icon_state_charged = "recharger2" @@ -81,22 +82,21 @@ if(stat & (NOPOWER|BROKEN) || !anchored) return - var/using_power = 0 + using_power = FALSE if(charging) if(istype(charging, /obj/item/gun/energy)) var/obj/item/gun/energy/E = charging if(E.power_supply.charge < E.power_supply.maxcharge) E.power_supply.give(E.power_supply.chargerate) use_power(250) - using_power = 1 - + using_power = TRUE if(istype(charging, /obj/item/melee/baton)) var/obj/item/melee/baton/B = charging if(B.bcell) if(B.bcell.give(B.bcell.chargerate)) use_power(200) - using_power = 1 + using_power = TRUE if(istype(charging, /obj/item/modular_computer)) var/obj/item/modular_computer/C = charging @@ -107,21 +107,21 @@ if(B.battery.charge < B.battery.maxcharge) B.battery.give(B.battery.chargerate) use_power(200) - using_power = 1 + using_power = TRUE if(istype(charging, /obj/item/rcs)) var/obj/item/rcs/R = charging if(R.rcell) if(R.rcell.give(R.rcell.chargerate)) use_power(200) - using_power = 1 + using_power = TRUE if(istype(charging, /obj/item/bodyanalyzer)) var/obj/item/bodyanalyzer/B = charging if(B.power_supply) if(B.power_supply.give(B.power_supply.chargerate)) use_power(200) - using_power = 1 + using_power = TRUE update_icon(using_power) @@ -141,7 +141,7 @@ B.bcell.charge = 0 ..(severity) -/obj/machinery/recharger/update_icon(using_power = 0) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier. +/obj/machinery/recharger/update_icon(using_power = FALSE) //we have an update_icon() in addition to the stuff in process to make it feel a tiny bit snappier. if(stat & (NOPOWER|BROKEN) || !anchored) icon_state = icon_state_off return @@ -153,6 +153,23 @@ return icon_state = icon_state_idle +/obj/machinery/recharger/examine(mob/user) + ..() + if(charging && (!in_range(user, src) && !issilicon(user) && !isobserver(user))) + to_chat(user, "You're too far away to examine [src]'s contents and display!") + return + + if(charging) + to_chat(user, "\The [src] contains:") + to_chat(user, "- \A [charging].") + if(!(stat & (NOPOWER|BROKEN))) + var/obj/item/stock_parts/cell/C = charging.get_cell() + to_chat(user, "The status display reads:") + if(using_power) + to_chat(user, "- Recharging [(C.chargerate/C.maxcharge)*100]% cell charge per cycle.") + if(charging) + to_chat(user, "- \The [charging]'s cell is at [C.percent()]%.") + // Atlantis: No need for that copy-pasta code, just use var to store icon_states instead. /obj/machinery/recharger/wallcharger name = "wall recharger" diff --git a/code/game/machinery/spaceheater.dm b/code/game/machinery/spaceheater.dm index 3777dfc866d..ccba902b058 100644 --- a/code/game/machinery/spaceheater.dm +++ b/code/game/machinery/spaceheater.dm @@ -12,6 +12,9 @@ var/set_temperature = 50 // in celcius, add T0C for kelvin var/heating_power = 40000 +/obj/machinery/space_heater/get_cell() + return cell + /obj/machinery/space_heater/New() ..() cell = new(src) @@ -39,7 +42,6 @@ else to_chat(user, "The charge meter reads [cell ? round(cell.percent(),1) : 0]%") - /obj/machinery/space_heater/emp_act(severity) if(stat & (BROKEN|NOPOWER)) ..(severity) diff --git a/code/game/mecha/mecha.dm b/code/game/mecha/mecha.dm index d9d9d5dd261..2ff5cabaaaa 100644 --- a/code/game/mecha/mecha.dm +++ b/code/game/mecha/mecha.dm @@ -137,6 +137,10 @@ //////////////////////// ////// Helpers ///////// //////////////////////// + +/obj/mecha/get_cell() + return cell + /obj/mecha/proc/add_airtank() internal_tank = new /obj/machinery/portable_atmospherics/canister/air(src) return internal_tank diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm index 9bb036c4d05..cad4ae25ac8 100644 --- a/code/game/objects/items/devices/scanners.dm +++ b/code/game/objects/items/devices/scanners.dm @@ -591,6 +591,9 @@ REAGENT SCANNER var/scan_time = 10 SECONDS //how long does it take to scan var/scan_cd = 60 SECONDS //how long before we can scan again +/obj/item/bodyanalyzer/get_cell() + return power_supply + /obj/item/bodyanalyzer/advanced cell_type = /obj/item/stock_parts/cell/upgraded/plus diff --git a/code/game/objects/items/weapons/defib.dm b/code/game/objects/items/weapons/defib.dm index 05f725fcf54..fbdc403d758 100644 --- a/code/game/objects/items/weapons/defib.dm +++ b/code/game/objects/items/weapons/defib.dm @@ -22,6 +22,9 @@ var/obj/item/stock_parts/cell/high/bcell = null var/combat = 0 //can we revive through space suits? +/obj/item/defibrillator/get_cell() + return bcell + /obj/item/defibrillator/New() //starts without a cell for rnd ..() paddles = make_paddles() diff --git a/code/game/objects/items/weapons/rpd.dm b/code/game/objects/items/weapons/rpd.dm index 63a3ffef0c5..4381c4295c7 100644 --- a/code/game/objects/items/weapons/rpd.dm +++ b/code/game/objects/items/weapons/rpd.dm @@ -4,6 +4,9 @@ #define RPD_COOLDOWN_TIME 4 //How long should we have to wait between dispensing pipes? #define RPD_WALLBUILD_TIME 40 //How long should drilling into a wall take? +#define RPD_MENU_ROTATE "Rotate pipes" //Stuff for radial menu +#define RPD_MENU_FLIP "Flip pipes" //Stuff for radial menu +#define RPD_MENU_DELETE "Delete pipes" //Stuff for radial menu /obj/item/rpd name = "rapid pipe dispenser" @@ -172,6 +175,9 @@ var/list/pipemenu = list( ui.open() ui.set_auto_update(1) +/obj/item/rpd/AltClick(mob/user) + radial_menu(user) + /obj/item/rpd/ui_data(mob/user, ui_key = "main", datum/topic_state/state = inventory_state) var/data[0] data["iconrotation"] = iconrotation @@ -200,6 +206,44 @@ var/list/pipemenu = list( return SSnanoui.update_uis(src) +//RPD radial menu + +/obj/item/rpd/proc/check_menu(mob/living/user) + if(!istype(user)) + return + if(user.incapacitated()) + return + if(loc != user) + return + return TRUE + +/obj/item/rpd/proc/radial_menu(mob/user) + if(!check_menu(user)) + to_chat(user, "You can't do that right now!") + return + var/list/choices = list( + RPD_MENU_ROTATE = image(icon = 'icons/obj/interface.dmi', icon_state = "rpd_rotate"), + RPD_MENU_FLIP = image(icon = 'icons/obj/interface.dmi', icon_state = "rpd_flip"), + RPD_MENU_DELETE = image(icon = 'icons/obj/interface.dmi', icon_state = "rpd_delete"), + "UI" = image(icon = 'icons/obj/interface.dmi', icon_state = "ui_interact") + ) + var/selected_mode = show_radial_menu(user, src, choices, custom_check = CALLBACK(src, .proc/check_menu, user)) + if(!check_menu(user)) + return + if(selected_mode == "UI") + ui_interact(user) + else + switch(selected_mode) + if(RPD_MENU_ROTATE) + mode = RPD_ROTATE_MODE + if(RPD_MENU_FLIP) + mode = RPD_FLIP_MODE + if(RPD_MENU_DELETE) + mode = RPD_DELETE_MODE + else + return //Either nothing was selected, or an invalid mode was selected + to_chat(user, "You set [src]'s mode.") + /obj/item/rpd/afterattack(atom/target, mob/user, proximity) ..() if(loc != user) @@ -236,3 +280,6 @@ var/list/pipemenu = list( #undef RPD_COOLDOWN_TIME #undef RPD_WALLBUILD_TIME +#undef RPD_MENU_ROTATE +#undef RPD_MENU_FLIP +#undef RPD_MENU_DELETE diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index f128b874eaa..526340daea5 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -20,6 +20,9 @@ user.visible_message("[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide.") return FIRELOSS +/obj/item/melee/baton/get_cell() + return bcell + /obj/item/melee/baton/New() ..() update_icon() diff --git a/code/modules/admin/verbs/adminpm.dm b/code/modules/admin/verbs/adminpm.dm index caa051f8748..83531c9b0b9 100644 --- a/code/modules/admin/verbs/adminpm.dm +++ b/code/modules/admin/verbs/adminpm.dm @@ -279,6 +279,9 @@ /datum/pm_tracker/proc/add_message(client/title, client/sender, message, mob/user) if(!pms[title.key]) pms[title.key] = new /datum/pm_convo(title) + else if(!pms[title.key].client) + // If they DCed earlier, we need to add the client reference back + pms[title.key].client = title pms[title.key].add(sender, message) if(!open) @@ -308,16 +311,25 @@ dat += "[label]" var/datum/pm_convo/convo = pms[current_title] + var/datum/browser/popup = new(user, window_id, "Messages", 1000, 600, src) if(convo) + popup.add_head_content(@{""}) convo.read = TRUE dat += "

[check_rights(R_ADMIN, FALSE, user) ? fancy_title(current_title) : current_title]

" dat += "

" - dat += "

" + dat += "
" + dat += "
" for(var/message in convo.messages) dat += "" dat += "
[message]
" + dat += "
" if(convo.typing) dat += "[current_title] is typing" dat += "
" @@ -327,17 +339,23 @@ if(check_rights(R_ADMIN, FALSE, user)) dat += "Ping" - var/datum/browser/popup = new(user, window_id, "Messages", 1000, 600, src) popup.set_content(dat) popup.open() open = TRUE /datum/pm_tracker/proc/fancy_title(title) - var/client/C = pms[title].client + var/client/C = pms[title].client || update_client(title) if(!C) return "[title] (Disconnected)" return "[key_name(C, FALSE)] ([ADMIN_QUE(C.mob,"?")]) ([ADMIN_PP(C.mob,"PP")]) ([ADMIN_VV(C.mob,"VV")]) ([ADMIN_SM(C.mob,"SM")]) ([admin_jump_link(C.mob)]) (CA)" +/datum/pm_tracker/proc/update_client(title) + var/client/C = GLOB.directory[ckey(title)] + if(C) + pms[title].client = C + return C + return null + /datum/pm_tracker/Topic(href, href_list) if(href_list["archive"]) pms[href_list["archive"]].archived = !pms[href_list["archive"]].archived diff --git a/code/modules/client/preference/preferences.dm b/code/modules/client/preference/preferences.dm index 9c310fc29ee..e09fc89736a 100644 --- a/code/modules/client/preference/preferences.dm +++ b/code/modules/client/preference/preferences.dm @@ -455,6 +455,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts dat += "Ghost Ears: [(toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]
" dat += "Ghost Radio: [(toggles & CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"]
" dat += "Ghost Sight: [(toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]
" + dat += "Ghost PDA: [(toggles & CHAT_GHOSTPDA) ? "All PDA Messages" : "No PDA Messages"]
" if(check_rights(R_ADMIN,0)) dat += "OOC Color:     Change
" if(config.allow_Metadata) @@ -2029,6 +2030,9 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts if("ghost_radio") toggles ^= CHAT_GHOSTRADIO + + if("ghost_pda") + toggles ^= CHAT_GHOSTPDA if("ghost_anonsay") ghost_anonsay = !ghost_anonsay diff --git a/code/modules/client/preference/preferences_toggles.dm b/code/modules/client/preference/preferences_toggles.dm index 3d44cd82bfe..e164a2ab843 100644 --- a/code/modules/client/preference/preferences_toggles.dm +++ b/code/modules/client/preference/preferences_toggles.dm @@ -266,3 +266,11 @@ else to_chat(usr, "You are now in QWERTY mode.") return +/client/verb/toggle_ghost_pda() + set name = "Show/Hide GhostPDA" + set category = "Preferences" + set desc = ".Toggle seeing PDA messages as an observer." + prefs.toggles ^= CHAT_GHOSTPDA + to_chat(src, "As a ghost, you will now [(prefs.toggles & CHAT_GHOSTPDA) ? "see all PDA messages" : "no longer see PDA messages"].") + prefs.save_preferences(src) + feedback_add_details("admin_verb","TGP") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/clothing/gloves/miscellaneous.dm b/code/modules/clothing/gloves/miscellaneous.dm index 227374bd420..8e5e658e31a 100644 --- a/code/modules/clothing/gloves/miscellaneous.dm +++ b/code/modules/clothing/gloves/miscellaneous.dm @@ -64,7 +64,6 @@ item_state = "lgloves" flags = NODROP - /obj/item/clothing/gloves/color/yellow/stun name = "stun gloves" desc = "Horrendous and awful. It smells like cancer. The fact it has wires attached to it is incidental." @@ -72,6 +71,9 @@ var/stun_strength = 5 var/stun_cost = 2000 +/obj/item/clothing/gloves/color/yellow/stun/get_cell() + return cell + /obj/item/clothing/gloves/color/yellow/stun/New() ..() update_icon() diff --git a/code/modules/clothing/spacesuits/rig/rig.dm b/code/modules/clothing/spacesuits/rig/rig.dm index 913e65af734..b463a513764 100644 --- a/code/modules/clothing/spacesuits/rig/rig.dm +++ b/code/modules/clothing/spacesuits/rig/rig.dm @@ -97,6 +97,9 @@ to_chat(usr, "The maintenance panel is [open ? "open" : "closed"].") to_chat(usr, "Hardsuit systems are [offline ? "offline" : "online"].") +/obj/item/rig/get_cell() + return cell + /obj/item/rig/New() ..() diff --git a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm index 48b4453f6d4..3cd95f37923 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/smartfridge.dm @@ -164,7 +164,7 @@ // Virology Medical Smartfridge // ---------------------------- /obj/machinery/smartfridge/secure/chemistry/virology - name = "smart virus storage" + name = "Smart Virus Storage" desc = "A refrigerated storage unit for volatile sample storage." req_access_txt = "39" spawn_meds = list(/obj/item/reagent_containers/syringe/antiviral = 4, @@ -386,7 +386,8 @@ return data /obj/machinery/smartfridge/Topic(href, href_list) - if(..()) return 0 + if(..()) + return FALSE var/mob/user = usr var/datum/nanoui/ui = SSnanoui.get_open_ui(user, src, "main") @@ -396,7 +397,7 @@ if(href_list["close"]) user.unset_machine() ui.close() - return 0 + return FALSE if(href_list["vend"]) var/index = text2num(href_list["vend"]) @@ -409,17 +410,26 @@ item_quants[K] = max(count - amount, 0) var/i = amount - for(var/obj/O in contents) - if(O.name == K) - O.forceMove(loc) - adjust_item_drop_location(O) - update_icon() - i-- - if(i <= 0) - return 1 - - return 1 - return 0 + if(i == 1 && Adjacent(user) && !issilicon(user)) + for(var/obj/O in contents) + if(O.name == K) + if(!user.put_in_hands(O)) + O.forceMove(loc) + adjust_item_drop_location(O) + update_icon() + break + return TRUE + else + for(var/obj/O in contents) + if(O.name == K) + O.forceMove(loc) + adjust_item_drop_location(O) + update_icon() + i-- + if(i <= 0) + return TRUE + return TRUE + return FALSE /obj/machinery/smartfridge/proc/throw_item() var/obj/throw_item = null diff --git a/code/modules/mining/mine_items.dm b/code/modules/mining/mine_items.dm index 8ba8b13c09c..f10b78dc526 100644 --- a/code/modules/mining/mine_items.dm +++ b/code/modules/mining/mine_items.dm @@ -82,6 +82,7 @@ /obj/item/flashlight/lantern name = "lantern" icon_state = "lantern" + item_state = "lantern" desc = "A mining lantern." brightness_on = 6 // luminosity when on diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index c8c7d5c32e3..1b11a35e58b 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -402,9 +402,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp to_chat(usr, "Not when you're not dead!") return - var/area/A = input("Area to jump to", "BOOYEA") as null|anything in ghostteleportlocs - var/area/thearea = ghostteleportlocs[A] + var/datum/async_input/A = input_autocomplete_async(usr, "Area to jump to: ", ghostteleportlocs) + A.on_close(CALLBACK(src, .proc/teleport)) +/mob/dead/observer/proc/teleport(area/thearea) if(!thearea) return @@ -425,9 +426,8 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set desc = "Follow and orbit a mob." var/list/mobs = getpois(skip_mindless=1) - var/input = input("Please, select a mob!", "Haunt", null, null) as null|anything in mobs - var/mob/target = mobs[input] - ManualFollow(target) + var/datum/async_input/A = input_autocomplete_async(usr, "Please, select a mob: ", mobs) + A.on_close(CALLBACK(src, .proc/ManualFollow)) // This is the ghost's follow verb with an argument /mob/dead/observer/proc/ManualFollow(var/atom/movable/target) @@ -499,25 +499,21 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp set name = "Jump to Mob" set desc = "Teleport to a mob" - if(isobserver(usr)) //Make sure they're an observer! - var/list/dest = list() //List of possible destinations (mobs) - var/target = null //Chosen target. + if(isobserver(usr)) //Make sure they're an observer! + var/list/dest = getpois(mobs_only=1) //Fill list, prompt user with list + var/datum/async_input/A = input_autocomplete_async(usr, "Enter a mob name: ", dest) + A.on_close(CALLBACK(src, .proc/jump_to_mob)) - dest += getpois(mobs_only=1) //Fill list, prompt user with list - target = input("Please, select a mob!", "Jump to Mob", null, null) as null|anything in dest - - if(!target) //Make sure we actually have a target - return - else - var/mob/M = dest[target] //Destination mob - var/mob/A = src //Source mob - var/turf/T = get_turf(M) //Turf of the destination mob - - if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination. - A.forceMove(T) - else - to_chat(A, "This mob is not located in the game world.") +/mob/dead/observer/proc/jump_to_mob(mob/M) + if(!M) + return + var/mob/A = src //Source mob + var/turf/T = get_turf(M) //Turf of the destination mob + if(T && isturf(T)) //Make sure the turf exists, then move the source to that destination. + A.forceMove(T) + return + to_chat(A, "This mob is not located in the game world.") /* Now a spell. See spells.dm /mob/dead/observer/verb/boo() diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 7be816e5a7a..a8dbaa7ac2f 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -216,56 +216,7 @@ add_attack_logs(M, src, "Shaked", ATKLOG_ALL) if(health >= HEALTH_THRESHOLD_CRIT) if(src == M && ishuman(src)) - var/mob/living/carbon/human/H = src - visible_message( \ - text("[src] examines [].",gender==MALE?"himself":"herself"), \ - "You check yourself for injuries." \ - ) - - var/list/missing = list("head", "chest", "groin", "l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot") - for(var/X in H.bodyparts) - var/obj/item/organ/external/LB = X - missing -= LB.limb_name - var/status = "" - var/brutedamage = LB.brute_dam - var/burndamage = LB.burn_dam - - if(brutedamage > 0) - status = "bruised" - if(brutedamage > 20) - status = "battered" - if(brutedamage > 40) - status = "mangled" - if(brutedamage > 0 && burndamage > 0) - status += " and " - if(burndamage > 40) - status += "peeling away" - - else if(burndamage > 10) - status += "blistered" - else if(burndamage > 0) - status += "numb" - if(LB.status & ORGAN_MUTATED) - status = "weirdly shapen." - if(status == "") - status = "OK" - to_chat(src, "\t Your [LB.name] is [status].") - - for(var/obj/item/I in LB.embedded_objects) - to_chat(src, "\t There is \a [I] embedded in your [LB.name]!") - - for(var/t in missing) - to_chat(src, "Your [parse_zone(t)] is missing!") - - if(H.bleed_rate) - to_chat(src, "You are bleeding!") - if(staminaloss) - if(staminaloss > 30) - to_chat(src, "You're completely exhausted.") - else - to_chat(src, "You feel fatigued.") - if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit)) - H.play_xylophone() + check_self_for_injuries() else if(player_logged) M.visible_message("[M] shakes [src], but [p_they()] [p_do()] not respond. Probably suffering from SSD.", \ @@ -308,6 +259,58 @@ else if(H.w_uniform) H.w_uniform.add_fingerprint(M) +/mob/living/carbon/proc/check_self_for_injuries() + var/mob/living/carbon/human/H = src + visible_message( \ + text("[src] examines [].",gender==MALE?"himself":"herself"), \ + "You check yourself for injuries." \ + ) + + var/list/missing = list("head", "chest", "groin", "l_arm", "r_arm", "l_hand", "r_hand", "l_leg", "r_leg", "l_foot", "r_foot") + for(var/X in H.bodyparts) + var/obj/item/organ/external/LB = X + missing -= LB.limb_name + var/status = "" + var/brutedamage = LB.brute_dam + var/burndamage = LB.burn_dam + + if(brutedamage > 0) + status = "bruised" + if(brutedamage > 20) + status = "battered" + if(brutedamage > 40) + status = "mangled" + if(brutedamage > 0 && burndamage > 0) + status += " and " + if(burndamage > 40) + status += "peeling away" + + else if(burndamage > 10) + status += "blistered" + else if(burndamage > 0) + status += "numb" + if(LB.status & ORGAN_MUTATED) + status = "weirdly shapen." + if(status == "") + status = "OK" + to_chat(src, "\t Your [LB.name] is [status].") + + for(var/obj/item/I in LB.embedded_objects) + to_chat(src, "\t There is \a [I] embedded in your [LB.name]!") + + for(var/t in missing) + to_chat(src, "Your [parse_zone(t)] is missing!") + + if(H.bleed_rate) + to_chat(src, "You are bleeding!") + if(staminaloss) + if(staminaloss > 30) + to_chat(src, "You're completely exhausted.") + else + to_chat(src, "You feel fatigued.") + if((SKELETON in H.mutations) && (!H.w_uniform) && (!H.wear_suit)) + H.play_xylophone() + /mob/living/carbon/flash_eyes(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0) . = ..() var/damage = intensity - check_eye_prot() diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 100dd1ffbba..0c6ddf80fc6 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -103,6 +103,9 @@ var/list/robot_verbs_default = list( var/datum/action/item_action/toggle_research_scanner/scanner = null var/list/module_actions = list() +/mob/living/silicon/robot/get_cell() + return cell + /mob/living/silicon/robot/New(loc,var/syndie = 0,var/unfinished = 0, var/alien = 0) spark_system = new /datum/effect_system/spark_spread() spark_system.set_up(5, 0, src) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 49a3b2718db..1db149418c7 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -50,6 +50,9 @@ var/currentBloodColor = "#A10808" var/currentDNA = null +/mob/living/simple_animal/bot/mulebot/get_cell() + return cell + /mob/living/simple_animal/bot/mulebot/New() ..() wires = new /datum/wires/mulebot(src) diff --git a/code/modules/modular_computers/computers/item/computer_power.dm b/code/modules/modular_computers/computers/item/computer_power.dm index 0a7955cfe52..27c81d48190 100644 --- a/code/modules/modular_computers/computers/item/computer_power.dm +++ b/code/modules/modular_computers/computers/item/computer_power.dm @@ -26,6 +26,10 @@ return battery_module.battery.give(amount) return 0 +/obj/item/modular_computer/get_cell() + var/obj/item/computer_hardware/battery/battery_module = all_components[MC_CELL] + if(battery_module && battery_module.battery) + return battery_module.battery // Used in following function to reduce copypaste /obj/item/modular_computer/proc/power_failure() diff --git a/code/modules/modular_computers/hardware/battery_module.dm b/code/modules/modular_computers/hardware/battery_module.dm index 65b4ef1f640..98f1ab5667e 100644 --- a/code/modules/modular_computers/hardware/battery_module.dm +++ b/code/modules/modular_computers/hardware/battery_module.dm @@ -8,6 +8,9 @@ var/obj/item/stock_parts/cell/battery = null device_type = MC_CELL +/obj/item/computer_hardware/battery/get_cell() + return battery + /obj/item/computer_hardware/battery/New(loc, battery_type = null) if(battery_type) battery = new battery_type(src) diff --git a/code/modules/ninja/suit/suit.dm b/code/modules/ninja/suit/suit.dm index dfd430a5754..6e550e64893 100644 --- a/code/modules/ninja/suit/suit.dm +++ b/code/modules/ninja/suit/suit.dm @@ -27,6 +27,9 @@ Contents: var/obj/item/clothing/mask/gas/space_ninja/suitMask var/mob/living/carbon/human/suitOccupant +/obj/item/clothing/suit/space/space_ninja/get_cell() + return suitCell + /obj/item/clothing/suit/space/space_ninja/proc/toggle_suit_lock(mob/living/carbon/human/user) if(!suitActive) if(!istype(user.wear_suit, /obj/item/clothing/suit/space/space_ninja)) diff --git a/code/modules/ninja/suit/suit_attackby.dm b/code/modules/ninja/suit/suit_attackby.dm index ab6250a2b0f..2a2683a2826 100644 --- a/code/modules/ninja/suit/suit_attackby.dm +++ b/code/modules/ninja/suit/suit_attackby.dm @@ -1,5 +1,3 @@ - - /obj/item/clothing/suit/space/space_ninja/attackby(obj/item/I, mob/U, params) if(U==suitOccupant)//Safety, in case you try doing this without wearing the suit/being the person with the suit. if(istype(I, /obj/item/stock_parts/cell)) @@ -21,4 +19,4 @@ else to_chat(U, "Procedure interrupted. Protocol terminated.") return - ..() \ No newline at end of file + ..() diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 451687cd38c..23a37e06409 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -75,16 +75,19 @@ assets.send(user) var/data - if((!user.say_understands(null, GLOB.all_languages["Galactic Common"]) && !forceshow) || forcestars) //assuming all paper is written in common is better than hardcoded type checks - data = "[name][stars(info)][stamps]" - if(view) - usr << browse(data, "window=[name];size=[paper_width]x[paper_height]") - onclose(usr, "[name]") + var/stars = (!user.say_understands(null, GLOB.all_languages["Galactic Common"]) && !forceshow) || forcestars + if(stars) //assuming all paper is written in common is better than hardcoded type checks + data = "[stars(info)][stamps]" else - data = "[name][infolinks ? info_links : info][stamps]" - if(view) - usr << browse(data, "window=[name];size=[paper_width]x[paper_height]") - onclose(usr, "[name]") + data = "
[infolinks ? info_links : info]
[stamps]" + if(view) + var/datum/browser/popup = new(user, name, , paper_width, paper_height) + popup.stylesheets = list() + popup.set_content(data) + if(!stars) + popup.add_script("marked.js", 'html/browser/marked.js') + popup.add_head_content("[name]") + popup.open() return data /obj/item/paper/verb/rename() diff --git a/code/modules/pda/messenger.dm b/code/modules/pda/messenger.dm index 67ccf48df8a..ab97c956d85 100644 --- a/code/modules/pda/messenger.dm +++ b/code/modules/pda/messenger.dm @@ -169,10 +169,18 @@ if(useTC != 2) // Does our recipient have a broadcaster on their level? to_chat(U, "ERROR: Cannot reach recipient.") return + useMS.send_pda_message("[P.owner]","[pda.owner]","[t]") tnote.Add(list(list("sent" = 1, "owner" = "[P.owner]", "job" = "[P.ownjob]", "message" = "[t]", "target" = "\ref[P]"))) PM.tnote.Add(list(list("sent" = 0, "owner" = "[pda.owner]", "job" = "[pda.ownjob]", "message" = "[t]", "target" = "\ref[pda]"))) pda.investigate_log("PDA Message - [U.key] - [pda.owner] -> [P.owner]: [t]", "pda") + + // Show it to ghosts + for(var/mob/M in GLOB.dead_mob_list) + if(isobserver(M) && M.client && (M.client.prefs.toggles & CHAT_GHOSTPDA)) + var/ghost_message = "[pda.owner] ([ghost_follow_link(pda, ghost=M)]) PDA Message --> [P.owner] ([ghost_follow_link(P, ghost=M)]): [t]" + to_chat(M, "[ghost_message]") + if(!conversations.Find("\ref[P]")) conversations.Add("\ref[P]") if(!PM.conversations.Find("\ref[pda]")) diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index a69ff2a793b..7b3162fdefb 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -135,6 +135,9 @@ usesound = 'sound/items/deconstruct.ogg' toolspeed = 1 +/obj/machinery/power/apc/get_cell() + return cell + /obj/machinery/power/apc/connect_to_network() //Override because the APC does not directly connect to the network; it goes through a terminal. //The terminal is what the power computer looks for anyway. diff --git a/code/modules/power/cell.dm b/code/modules/power/cell.dm index 4719ff75261..33b423c6360 100644 --- a/code/modules/power/cell.dm +++ b/code/modules/power/cell.dm @@ -19,6 +19,9 @@ var/ratingdesc = TRUE var/grown_battery = FALSE // If it's a grown that acts as a battery, add a wire overlay to it. +/obj/item/stock_parts/cell/get_cell() + return src + /obj/item/stock_parts/cell/New() ..() START_PROCESSING(SSobj, src) diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index b25420b5491..cbc230c1e98 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -23,6 +23,9 @@ power_supply.use(round(power_supply.charge / severity)) update_icon() +/obj/item/gun/energy/get_cell() + return power_supply + /obj/item/gun/energy/New() ..() if(cell_type) diff --git a/code/modules/projectiles/guns/throw/crossbow.dm b/code/modules/projectiles/guns/throw/crossbow.dm index bf101cd49c3..9c87f7949a9 100644 --- a/code/modules/projectiles/guns/throw/crossbow.dm +++ b/code/modules/projectiles/guns/throw/crossbow.dm @@ -22,6 +22,9 @@ var/obj/item/stock_parts/cell/cell = null // Used for firing superheated rods. var/list/possible_tensions = list(XBOW_TENSION_20, XBOW_TENSION_40, XBOW_TENSION_60, XBOW_TENSION_80, XBOW_TENSION_FULL) +/obj/item/gun/throw/crossbow/get_cell() + return cell + /obj/item/gun/throw/crossbow/emp_act(severity) if(cell && severity) emp_act(severity) diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 20ecaff13d4..7c53761a70f 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -24,6 +24,9 @@ var/hack_message = "You disable the safety safeguards, enabling the \"Mad Scientist\" mode." var/unhack_message = "You re-enable the safety safeguards, enabling the \"NT Standard\" mode." +/obj/machinery/chem_dispenser/get_cell() + return cell + /obj/machinery/chem_dispenser/New() ..() component_parts = list() diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm index a67f681973d..6f0c53730b4 100644 --- a/code/modules/reagents/chemistry/reagents/food.dm +++ b/code/modules/reagents/chemistry/reagents/food.dm @@ -815,7 +815,7 @@ var/update_flags = STATUS_UPDATE_NONE if(prob(5)) if(prob(10)) - update_flags |= M.adjustToxLoss(rand(2.4), FALSE) + update_flags |= M.adjustToxLoss(rand(2,4), FALSE) if(prob(7)) to_chat(M, "A horrible migraine overpowers you.") update_flags |= M.Stun(rand(2,5), FALSE) diff --git a/code/modules/spacepods/spacepod.dm b/code/modules/spacepods/spacepod.dm index 273ea75e832..16f8e8f067f 100644 --- a/code/modules/spacepods/spacepod.dm +++ b/code/modules/spacepods/spacepod.dm @@ -92,6 +92,8 @@ has_paint = 1 update_icons() +/obj/spacepod/get_cell() + return battery /obj/spacepod/New() . = ..() diff --git a/code/modules/telesci/telepad.dm b/code/modules/telesci/telepad.dm index 2f3667a645f..893e9719fb4 100644 --- a/code/modules/telesci/telepad.dm +++ b/code/modules/telesci/telepad.dm @@ -128,11 +128,13 @@ var/teleporting = 0 var/chargecost = 1000 +/obj/item/rcs/get_cell() + return rcell + /obj/item/rcs/New() ..() rcell = new(src) - /obj/item/rcs/examine(mob/user) ..(user) to_chat(user, "There are [round(rcell.charge/chargecost)] charge\s left.") diff --git a/html/browser/autocomplete.js b/html/browser/autocomplete.js new file mode 100644 index 00000000000..28d3be539c4 --- /dev/null +++ b/html/browser/autocomplete.js @@ -0,0 +1,61 @@ +var $ = document.querySelector.bind(document); +var input; +var submitButton; +var optionsMap = {}; + +function updateTopic() { + if (!input || !submitButton) { + return; + } + + var hrefList = submitButton.getAttribute('href').split(';'); + // Topic must come last in the submit button for this to work + hrefList = hrefList.slice(0, hrefList.length - 1); + hrefList.push(optionsMap[input.value] ? 'submit=' + optionsMap[input.value] : ''); + submitButton.setAttribute('href', hrefList.join(';')); +} + +function clean(name) { + // \improper shows up as 2 characters outside of ascii range + if (name.charCodeAt(0) > 127) { + return name.slice(2); + } + return name; +} + +function setElements() { + input = $('#input'); + submitButton = $('#submit-button'); + var choices = $('#choices'); + + if (!input || !submitButton || !choices) { + return; + } + + + for (var i = 0; i < choices.options.length; i++) { + var name = choices.options[i].value; + var cleaned = clean(name); + optionsMap[cleaned] = name; + choices.options[i].value = cleaned; + } + + input.addEventListener('keyup', function(event) { + if (event.key !== 'Enter') { + return; + } + + if (Object.keys(optionsMap).indexOf(input.value) === -1) { + // Byond doesn't let you to use enter to select + // so we need to prevent unintended submissions + return + } + + submitButton.click(); + event.preventDefault(); + }); + + input.focus(); +} + +window.onload = setElements; diff --git a/html/browser/marked.js b/html/browser/marked.js new file mode 100644 index 00000000000..6fe0e1e4e41 --- /dev/null +++ b/html/browser/marked.js @@ -0,0 +1,26 @@ +/** + * marked - a markdown parser + * Copyright (c) 2011-2018, Christopher Jeffrey. (MIT Licensed) + * https://github.com/markedjs/marked + */ +!function(e){"use strict";var _={newline:/^\n+/,code:/^( {4}[^\n]+\n*)+/,fences:f,hr:/^ {0,3}((?:- *){3,}|(?:_ *){3,}|(?:\* *){3,})(?:\n+|$)/,heading:/^ *(#{1,6}) *([^\n]+?) *(?:#+ *)?(?:\n+|$)/,nptable:f,blockquote:/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/,list:/^( {0,3})(bull) [\s\S]+?(?:hr|def|\n{2,}(?! )(?!\1bull )\n*|\s*$)/,html:"^ {0,3}(?:<(script|pre|style)[\\s>][\\s\\S]*?(?:[^\\n]*\\n+|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?\\?>\\n*|\\n*|\\n*|)[\\s\\S]*?(?:\\n{2,}|$)|<(?!script|pre|style)([a-z][\\w-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$)|(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:\\n{2,}|$))",def:/^ {0,3}\[(label)\]: *\n? *]+)>?(?:(?: +\n? *| *\n *)(title))? *(?:\n+|$)/,table:f,lheading:/^([^\n]+)\n {0,3}(=|-){2,} *(?:\n+|$)/,paragraph:/^([^\n]+(?:\n(?!hr|heading|lheading| {0,3}>|<\/?(?:tag)(?: +|\n|\/?>)|<(?:script|pre|style|!--))[^\n]+)*)/,text:/^[^\n]+/};function a(e){this.tokens=[],this.tokens.links=Object.create(null),this.options=e||m.defaults,this.rules=_.normal,this.options.pedantic?this.rules=_.pedantic:this.options.gfm&&(this.options.tables?this.rules=_.tables:this.rules=_.gfm)}_._label=/(?!\s*\])(?:\\[\[\]]|[^\[\]])+/,_._title=/(?:"(?:\\"?|[^"\\])*"|'[^'\n]*(?:\n[^'\n]+)*\n?'|\([^()]*\))/,_.def=i(_.def).replace("label",_._label).replace("title",_._title).getRegex(),_.bullet=/(?:[*+-]|\d{1,9}\.)/,_.item=/^( *)(bull) ?[^\n]*(?:\n(?!\1bull ?)[^\n]*)*/,_.item=i(_.item,"gm").replace(/bull/g,_.bullet).getRegex(),_.list=i(_.list).replace(/bull/g,_.bullet).replace("hr","\\n+(?=\\1?(?:(?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$))").replace("def","\\n+(?="+_.def.source+")").getRegex(),_._tag="address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|section|source|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul",_._comment=//,_.html=i(_.html,"i").replace("comment",_._comment).replace("tag",_._tag).replace("attribute",/ +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex(),_.paragraph=i(_.paragraph).replace("hr",_.hr).replace("heading",_.heading).replace("lheading",_.lheading).replace("tag",_._tag).getRegex(),_.blockquote=i(_.blockquote).replace("paragraph",_.paragraph).getRegex(),_.normal=d({},_),_.gfm=d({},_.normal,{fences:/^ {0,3}(`{3,}|~{3,})([^`\n]*)\n(?:|([\s\S]*?)\n)(?: {0,3}\1[~`]* *(?:\n+|$)|$)/,paragraph:/^/,heading:/^ *(#{1,6}) +([^\n]+?) *#* *(?:\n+|$)/}),_.gfm.paragraph=i(_.paragraph).replace("(?!","(?!"+_.gfm.fences.source.replace("\\1","\\2")+"|"+_.list.source.replace("\\1","\\3")+"|").getRegex(),_.tables=d({},_.gfm,{nptable:/^ *([^|\n ].*\|.*)\n *([-:]+ *\|[-| :]*)(?:\n((?:.*[^>\n ].*(?:\n|$))*)\n*|$)/,table:/^ *\|(.+)\n *\|?( *[-:]+[-| :]*)(?:\n((?: *[^>\n ].*(?:\n|$))*)\n*|$)/}),_.pedantic=d({},_.normal,{html:i("^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+? *(?:\\n{2,}|\\s*$)|\\s]*)*?/?> *(?:\\n{2,}|\\s*$))").replace("comment",_._comment).replace(/tag/g,"(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(),def:/^ *\[([^\]]+)\]: *]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/}),a.rules=_,a.lex=function(e,t){return new a(t).lex(e)},a.prototype.lex=function(e){return e=e.replace(/\r\n|\r/g,"\n").replace(/\t/g," ").replace(/\u00a0/g," ").replace(/\u2424/g,"\n"),this.token(e,!0)},a.prototype.token=function(e,t){var n,r,s,i,l,o,a,h,p,u,c,g,f,d,k,m,b,x;for(e=e.replace(/^ +$/gm,"");e;)if((s=this.rules.newline.exec(e))&&(e=e.substring(s[0].length),1 ?/gm,""),x=1;b.match(/^ {0,3}>/);)x++,this.tokens.push({type:"blockquote_start"}),b=b.replace(/^ *> ?/gm,"");for(this.token(b,t),c=0;c?@\[\]\\^_`{|}~])/,autolink:/^<(scheme:[^\s\x00-\x1f<>]*|email)>/,url:f,tag:"^comment|^|^<[a-zA-Z][\\w-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^|^",link:/^!?\[(label)\]\(href(?:\s+(title))?\s*\)/,reflink:/^!?\[(label)\]\[(?!\s*\])((?:\\[\[\]]?|[^\[\]\\])+)\]/,nolink:/^!?\[(?!\s*\])((?:\[[^\[\]]*\]|\\[\[\]]|[^\[\]])*)\](?:\[\])?/,strong:/^__([^\s_])__(?!_)|^\*\*([^\s*])\*\*(?!\*)|^__([^\s][\s\S]*?[^\s])__(?!_)|^\*\*([^\s][\s\S]*?[^\s])\*\*(?!\*)/,em:/^_([^\s_])_(?!_)|^\*([^\s*"<\[])\*(?!\*)|^_([^\s][\s\S]*?[^\s_])_(?!_|[^\spunctuation])|^_([^\s_][\s\S]*?[^\s])_(?!_|[^\spunctuation])|^\*([^\s"<\[][\s\S]*?[^\s*])\*(?!\*)|^\*([^\s*"<\[][\s\S]*?[^\s])\*(?!\*)/,code:/^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/,br:/^( {2,}|\\)\n(?!\s*$)/,del:f,text:/^(`+|[^`])(?:[\s\S]*?(?:(?=[\\?@\\[^_{|}~",n.em=i(n.em).replace(/punctuation/g,n._punctuation).getRegex(),n._escapes=/\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/g,n._scheme=/[a-zA-Z][a-zA-Z0-9+.-]{1,31}/,n._email=/[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/,n.autolink=i(n.autolink).replace("scheme",n._scheme).replace("email",n._email).getRegex(),n._attribute=/\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/,n.tag=i(n.tag).replace("comment",_._comment).replace("attribute",n._attribute).getRegex(),n._label=/(?:\[[^\[\]]*\]|\\[\[\]]?|`[^`]*`|`(?!`)|[^\[\]\\`])*?/,n._href=/\s*(<(?:\\[<>]?|[^\s<>\\])*>|[^\s\x00-\x1f]*)/,n._title=/"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/,n.link=i(n.link).replace("label",n._label).replace("href",n._href).replace("title",n._title).getRegex(),n.reflink=i(n.reflink).replace("label",n._label).getRegex(),n.normal=d({},n),n.pedantic=d({},n.normal,{strong:/^__(?=\S)([\s\S]*?\S)__(?!_)|^\*\*(?=\S)([\s\S]*?\S)\*\*(?!\*)/,em:/^_(?=\S)([\s\S]*?\S)_(?!_)|^\*(?=\S)([\s\S]*?\S)\*(?!\*)/,link:i(/^!?\[(label)\]\((.*?)\)/).replace("label",n._label).getRegex(),reflink:i(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label",n._label).getRegex()}),n.gfm=d({},n.normal,{escape:i(n.escape).replace("])","~|])").getRegex(),_extended_email:/[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-_])/,url:/^((?:ftp|https?):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/,_backpedal:/(?:[^?!.,:;*_~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_~)]+(?!$))+/,del:/^~+(?=\S)([\s\S]*?\S)~+/,text:/^(`+|[^`])(?:[\s\S]*?(?:(?=[\\/i.test(i[0])&&(this.inLink=!1),!this.inRawBlock&&/^<(pre|code|kbd|script)(\s|>)/i.test(i[0])?this.inRawBlock=!0:this.inRawBlock&&/^<\/(pre|code|kbd|script)(\s|>)/i.test(i[0])&&(this.inRawBlock=!1),e=e.substring(i[0].length),o+=this.options.sanitize?this.options.sanitizer?this.options.sanitizer(i[0]):u(i[0]):i[0];else if(i=this.rules.link.exec(e)){var a=k(i[2],"()");if(-1$/,"$1"),o+=this.outputLink(i,{href:p.escapes(r),title:p.escapes(s)}),this.inLink=!1}else if((i=this.rules.reflink.exec(e))||(i=this.rules.nolink.exec(e))){if(e=e.substring(i[0].length),t=(i[2]||i[1]).replace(/\s+/g," "),!(t=this.links[t.toLowerCase()])||!t.href){o+=i[0].charAt(0),e=i[0].substring(1)+e;continue}this.inLink=!0,o+=this.outputLink(i,t),this.inLink=!1}else if(i=this.rules.strong.exec(e))e=e.substring(i[0].length),o+=this.renderer.strong(this.output(i[4]||i[3]||i[2]||i[1]));else if(i=this.rules.em.exec(e))e=e.substring(i[0].length),o+=this.renderer.em(this.output(i[6]||i[5]||i[4]||i[3]||i[2]||i[1]));else if(i=this.rules.code.exec(e))e=e.substring(i[0].length),o+=this.renderer.codespan(u(i[2].trim(),!0));else if(i=this.rules.br.exec(e))e=e.substring(i[0].length),o+=this.renderer.br();else if(i=this.rules.del.exec(e))e=e.substring(i[0].length),o+=this.renderer.del(this.output(i[1]));else if(i=this.rules.autolink.exec(e))e=e.substring(i[0].length),r="@"===i[2]?"mailto:"+(n=u(this.mangle(i[1]))):n=u(i[1]),o+=this.renderer.link(r,null,n);else if(this.inLink||!(i=this.rules.url.exec(e))){if(i=this.rules.text.exec(e))e=e.substring(i[0].length),this.inRawBlock?o+=this.renderer.text(i[0]):o+=this.renderer.text(u(this.smartypants(i[0])));else if(e)throw new Error("Infinite loop on byte: "+e.charCodeAt(0))}else{if("@"===i[2])r="mailto:"+(n=u(i[0]));else{for(;l=i[0],i[0]=this.rules._backpedal.exec(i[0])[0],l!==i[0];);n=u(i[0]),r="www."===i[1]?"http://"+n:n}e=e.substring(i[0].length),o+=this.renderer.link(r,null,n)}return o},p.escapes=function(e){return e?e.replace(p.rules._escapes,"$1"):e},p.prototype.outputLink=function(e,t){var n=t.href,r=t.title?u(t.title):null;return"!"!==e[0].charAt(0)?this.renderer.link(n,r,this.output(e[1])):this.renderer.image(n,r,u(e[1]))},p.prototype.smartypants=function(e){return this.options.smartypants?e.replace(/---/g,"—").replace(/--/g,"–").replace(/(^|[-\u2014/(\[{"\s])'/g,"$1‘").replace(/'/g,"’").replace(/(^|[-\u2014/(\[{\u2018\s])"/g,"$1“").replace(/"/g,"”").replace(/\.{3}/g,"…"):e},p.prototype.mangle=function(e){if(!this.options.mangle)return e;for(var t,n="",r=e.length,s=0;s'+(n?e:u(e,!0))+"\n":"
"+(n?e:u(e,!0))+"
"},r.prototype.blockquote=function(e){return"
\n"+e+"
\n"},r.prototype.html=function(e){return e},r.prototype.heading=function(e,t,n,r){return this.options.headerIds?"'+e+"\n":""+e+"\n"},r.prototype.hr=function(){return this.options.xhtml?"
\n":"
\n"},r.prototype.list=function(e,t,n){var r=t?"ol":"ul";return"<"+r+(t&&1!==n?' start="'+n+'"':"")+">\n"+e+"\n"},r.prototype.listitem=function(e){return"
  • "+e+"
  • \n"},r.prototype.checkbox=function(e){return" "},r.prototype.paragraph=function(e){return"

    "+e+"

    \n"},r.prototype.table=function(e,t){return t&&(t=""+t+""),"\n\n"+e+"\n"+t+"
    \n"},r.prototype.tablerow=function(e){return"\n"+e+"\n"},r.prototype.tablecell=function(e,t){var n=t.header?"th":"td";return(t.align?"<"+n+' align="'+t.align+'">':"<"+n+">")+e+"\n"},r.prototype.strong=function(e){return""+e+""},r.prototype.em=function(e){return""+e+""},r.prototype.codespan=function(e){return""+e+""},r.prototype.br=function(){return this.options.xhtml?"
    ":"
    "},r.prototype.del=function(e){return""+e+""},r.prototype.link=function(e,t,n){if(null===(e=l(this.options.sanitize,this.options.baseUrl,e)))return n;var r='"},r.prototype.image=function(e,t,n){if(null===(e=l(this.options.sanitize,this.options.baseUrl,e)))return n;var r=''+n+'":">"},r.prototype.text=function(e){return e},s.prototype.strong=s.prototype.em=s.prototype.codespan=s.prototype.del=s.prototype.text=function(e){return e},s.prototype.link=s.prototype.image=function(e,t,n){return""+n},s.prototype.br=function(){return""},h.parse=function(e,t){return new h(t).parse(e)},h.prototype.parse=function(e){this.inline=new p(e.links,this.options),this.inlineText=new p(e.links,d({},this.options,{renderer:new s})),this.tokens=e.reverse();for(var t="";this.next();)t+=this.tok();return t},h.prototype.next=function(){return this.token=this.tokens.pop(),this.token},h.prototype.peek=function(){return this.tokens[this.tokens.length-1]||0},h.prototype.parseText=function(){for(var e=this.token.text;"text"===this.peek().type;)e+="\n"+this.next().text;return this.inline.output(e)},h.prototype.tok=function(){switch(this.token.type){case"space":return"";case"hr":return this.renderer.hr();case"heading":return this.renderer.heading(this.inline.output(this.token.text),this.token.depth,g(this.inlineText.output(this.token.text)),this.slugger);case"code":return this.renderer.code(this.token.text,this.token.lang,this.token.escaped);case"table":var e,t,n,r,s="",i="";for(n="",e=0;e?@[\]^`{|}~]/g,"").replace(/\s/g,"-");if(this.seen.hasOwnProperty(t))for(var n=t;this.seen[n]++,t=n+"-"+this.seen[n],this.seen.hasOwnProperty(t););return this.seen[t]=0,t},u.escapeTest=/[&<>"']/,u.escapeReplace=/[&<>"']/g,u.replacements={"&":"&","<":"<",">":">",'"':""","'":"'"},u.escapeTestNoEncode=/[<>"']|&(?!#?\w+;)/,u.escapeReplaceNoEncode=/[<>"']|&(?!#?\w+;)/g;var o={},c=/^$|^[a-z][a-z0-9+.-]*:|^[?#]/i;function f(){}function d(e){for(var t,n,r=1;rt)n.splice(t);else for(;n.lengthAn error occurred:

    "+u(e.message+"",!0)+"
    ";throw e}}f.exec=f,m.options=m.setOptions=function(e){return d(m.defaults,e),m},m.getDefaults=function(){return{baseUrl:null,breaks:!1,gfm:!0,headerIds:!0,headerPrefix:"",highlight:null,langPrefix:"language-",mangle:!0,pedantic:!1,renderer:new r,sanitize:!1,sanitizer:null,silent:!1,smartLists:!1,smartypants:!1,tables:!0,xhtml:!1}},m.defaults=m.getDefaults(),m.Parser=h,m.parser=h.parse,m.Renderer=r,m.TextRenderer=s,m.Lexer=a,m.lexer=a.lex,m.InlineLexer=p,m.inlineLexer=p.output,m.Slugger=t,m.parse=m,"undefined"!=typeof module&&"object"==typeof exports?module.exports=m:"function"==typeof define&&define.amd?define(function(){return m}):e.marked=m}(this||("undefined"!=typeof window?window:global)); +var $ = document.querySelector.bind(document); + +function parse(node) { + for (var i = 0; i < node.childNodes.length; i++) { + parse(node.childNodes[i]); + } + + if(!node.innerHTML) { + return; + } + node.innerHTML = marked(node.innerHTML.replace(/
    /gi, '\n'), { breaks: true }); +} + +function main() { + if ($('#markdown')) { + parse($('#markdown')); + } +} + +window.onload = main; diff --git a/html/changelog.html b/html/changelog.html index d98359137e3..b639984a5a6 100644 --- a/html/changelog.html +++ b/html/changelog.html @@ -56,6 +56,63 @@ -->
    +

    08 July 2019

    +

    Arkatos updated:

    +
      +
    • Clicking on a health doll icon will now check you for injuries
    • +
    • Rechargers now show their contents and charge status on close examine
    • +
    • Smartfridge will now try to put an item in your hands after vending, if able
    • +
    +

    AzuleUtama updated:

    +
      +
    • The cybernetic implant bundle can no longer be bought by traitors.
    • +
    +

    Citinited updated:

    +
      +
    • Alt-clicking the RPD now brings up a radial menu with rotate, flip, and delete modes accessible. The main interface remains unchanged.
    • +
    • Writing in blood can't be done while dead or incapacitated any more
    • +
    • You can't write stuff in blood at a distance any more
    • +
    +

    Couls updated:

    +
      +
    • lantern sprites
    • +
    • typo in msg
    • +
    +

    Improvedname updated:

    +
      +
    • Explorer suits now properly hide tails
    • +
    +

    JKnutson101 updated:

    +
      +
    • Fixed Construction Permits deleting themselves prematurely.
    • +
    +

    Kyep updated:

    +
      +
    • fixed a bug with biogenerator.
    • +
    +

    Markolie updated:

    +
      +
    • Ghosts can now see all PDA messages when enabled through a preference setting.
    • +
    • The Mask of Nar'Sie transformation buttons have been removed, as the mask was removed a long time ago.
    • +
    +

    Shadeykins updated:

    +
      +
    • Changed Quarantine, NT Default, Aggressive, and Corporate AI lawsets. balance: Reduced the ability for NT Default AI's to murder people just because.
    • +
    • Removed several redundancies in Aggressive lawset.
    • +
    • Fixed a few subject-verb disagreements (is -> are).
    • +
    +

    Tayyyyyyy updated:

    +
      +
    • paper supports markdown as well as pencode
    • +
    • Autocomplete for ghost buttons
    • +
    • PMs window scrollable
    • +
    • Fix a bug where a player who reconnects is still shown as disconnected
    • +
    +

    datlo updated:

    +
      +
    • Fix an antag rolling exploit.
    • +
    +

    30 June 2019

    Crazylemon64 updated:

      diff --git a/html/changelogs/.all_changelog.yml b/html/changelogs/.all_changelog.yml index b9801566492..49e86db023d 100644 --- a/html/changelogs/.all_changelog.yml +++ b/html/changelogs/.all_changelog.yml @@ -10415,3 +10415,42 @@ DO NOT EDIT THIS FILE BY HAND! AUTOMATICALLY GENERATED BY ss13_genchangelog.py. 2019-06-30: Crazylemon64: - rscdel: SDQL2 no longer allows a macro argument +2019-07-08: + Arkatos: + - tweak: Clicking on a health doll icon will now check you for injuries + - rscadd: Rechargers now show their contents and charge status on close examine + - tweak: Smartfridge will now try to put an item in your hands after vending, if + able + AzuleUtama: + - bugfix: The cybernetic implant bundle can no longer be bought by traitors. + Citinited: + - rscadd: Alt-clicking the RPD now brings up a radial menu with rotate, flip, and + delete modes accessible. The main interface remains unchanged. + - bugfix: Writing in blood can't be done while dead or incapacitated any more + - bugfix: You can't write stuff in blood at a distance any more + Couls: + - imageadd: lantern sprites + - bugfix: typo in msg + Improvedname: + - bugfix: Explorer suits now properly hide tails + JKnutson101: + - bugfix: Fixed Construction Permits deleting themselves prematurely. + Kyep: + - bugfix: fixed a bug with biogenerator. + Markolie: + - rscadd: Ghosts can now see all PDA messages when enabled through a preference + setting. + - rscdel: The Mask of Nar'Sie transformation buttons have been removed, as the mask + was removed a long time ago. + Shadeykins: + - tweak: 'Changed Quarantine, NT Default, Aggressive, and Corporate AI lawsets. + balance: Reduced the ability for NT Default AI''s to murder people just because.' + - bugfix: Removed several redundancies in Aggressive lawset. + - spellcheck: Fixed a few subject-verb disagreements (is -> are). + Tayyyyyyy: + - tweak: paper supports markdown as well as pencode + - rscadd: Autocomplete for ghost buttons + - tweak: PMs window scrollable + - bugfix: Fix a bug where a player who reconnects is still shown as disconnected + datlo: + - bugfix: Fix an antag rolling exploit. diff --git a/html/changelogs/AutoChangeLog-pr-11449.yml b/html/changelogs/AutoChangeLog-pr-11449.yml deleted file mode 100644 index 3789ca10f13..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11449.yml +++ /dev/null @@ -1,7 +0,0 @@ -author: "Shadeykins" -delete-after: True -changes: - - tweak: "Changed Quarantine, NT Default, Aggressive, and Corporate AI lawsets. -balance: Reduced the ability for NT Default AI's to murder people just because." - - bugfix: "Removed several redundancies in Aggressive lawset." - - spellcheck: "Fixed a few subject-verb disagreements (is -> are)." diff --git a/html/changelogs/AutoChangeLog-pr-11639.yml b/html/changelogs/AutoChangeLog-pr-11639.yml deleted file mode 100644 index f47431f6876..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11639.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "datlo" -delete-after: True -changes: - - bugfix: "Fix an antag rolling exploit." diff --git a/html/changelogs/AutoChangeLog-pr-11663.yml b/html/changelogs/AutoChangeLog-pr-11663.yml deleted file mode 100644 index c1129811f68..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11663.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Markolie" -delete-after: True -changes: - - rscdel: "The Mask of Nar'Sie transformation buttons have been removed, as the mask was removed a long time ago." diff --git a/html/changelogs/AutoChangeLog-pr-11706.yml b/html/changelogs/AutoChangeLog-pr-11706.yml deleted file mode 100644 index 349da8c68a5..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11706.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Improvedname" -delete-after: True -changes: - - bugfix: "Explorer suits now properly hide tails" diff --git a/html/changelogs/AutoChangeLog-pr-11770.yml b/html/changelogs/AutoChangeLog-pr-11770.yml deleted file mode 100644 index 94c44bb97b7..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11770.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "Citinited" -delete-after: True -changes: - - bugfix: "Writing in blood can't be done while dead or incapacitated any more" - - bugfix: "You can't write stuff in blood at a distance any more" diff --git a/html/changelogs/AutoChangeLog-pr-11771.yml b/html/changelogs/AutoChangeLog-pr-11771.yml deleted file mode 100644 index edc2a64f5ab..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11771.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "JKnutson101" -delete-after: True -changes: - - bugfix: "Fixed Construction Permits deleting themselves prematurely." diff --git a/html/changelogs/AutoChangeLog-pr-11786.yml b/html/changelogs/AutoChangeLog-pr-11786.yml deleted file mode 100644 index 53546aede12..00000000000 --- a/html/changelogs/AutoChangeLog-pr-11786.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Kyep" -delete-after: True -changes: - - bugfix: "fixed a bug with biogenerator." diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index ae285a5453a..47cb86a2c89 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index 8b949a8e732..e4630c2764e 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/obj/interface.dmi b/icons/obj/interface.dmi index 3b64561d5e0..631bba214c8 100644 Binary files a/icons/obj/interface.dmi and b/icons/obj/interface.dmi differ