mirror of
https://github.com/ParadiseSS13/Paradise.git
synced 2026-07-15 00:53:23 +01:00
Merge remote-tracking branch 'upstream/master' into diagonal-movement
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
parent.component_click(src, params)
|
||||
|
||||
@@ -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 = "<div style=\"[style]\">"
|
||||
dat += render_prompt(user)
|
||||
dat += render_choices(user)
|
||||
dat += render_prompt()
|
||||
dat += render_choices()
|
||||
dat += "<br>"
|
||||
dat += "<br>"
|
||||
dat += button("Submit", "submit=1", , result == null && !immediate_submit)
|
||||
dat += render_buttons()
|
||||
dat += "</div>"
|
||||
return dat
|
||||
|
||||
/datum/async_input/proc/render_prompt(mob/user)
|
||||
/datum/async_input/proc/render_prompt()
|
||||
return "<h2>[prompt]</h2>"
|
||||
|
||||
/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 "<a class=\"[class]\" href='?src=[UID()];[topic]'>[label]</a>"
|
||||
return "<a class=\"[class]\" id='[id]' href='?src=[UID()];[topic]'>[label]</a>"
|
||||
|
||||
/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 = "<div>"
|
||||
dat += "<table style='margin: auto; text-align: left;'>"
|
||||
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 "<label for='input'>[prompt]</label>"
|
||||
|
||||
/datum/async_input/autocomplete/render_choices()
|
||||
var/dat = "<input list='choices' id='input' name='choices' oninput='updateTopic()' />"
|
||||
dat += "<datalist id='choices'>"
|
||||
for(var/choice in choices)
|
||||
dat += "<option value='[choice]'>"
|
||||
dat += "</datalist>"
|
||||
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
|
||||
|
||||
..()
|
||||
|
||||
@@ -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, \
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
var/open = FALSE
|
||||
var/brightness_on = 14
|
||||
|
||||
/obj/machinery/floodlight/get_cell()
|
||||
return cell
|
||||
|
||||
/obj/machinery/floodlight/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -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, "<span class='warning'>You're too far away to examine [src]'s contents and display!</span>")
|
||||
return
|
||||
|
||||
if(charging)
|
||||
to_chat(user, "<span class='notice'>\The [src] contains:</span>")
|
||||
to_chat(user, "<span class='notice'>- \A [charging].</span>")
|
||||
if(!(stat & (NOPOWER|BROKEN)))
|
||||
var/obj/item/stock_parts/cell/C = charging.get_cell()
|
||||
to_chat(user, "<span class='notice'>The status display reads:<span>")
|
||||
if(using_power)
|
||||
to_chat(user, "<span class='notice'>- Recharging <b>[(C.chargerate/C.maxcharge)*100]%</b> cell charge per cycle.<span>")
|
||||
if(charging)
|
||||
to_chat(user, "<span class='notice'>- \The [charging]'s cell is at <b>[C.percent()]%</b>.<span>")
|
||||
|
||||
// Atlantis: No need for that copy-pasta code, just use var to store icon_states instead.
|
||||
/obj/machinery/recharger/wallcharger
|
||||
name = "wall recharger"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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, "<span class='notice'>You can't do that right now!</span>")
|
||||
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, "<span class='notice'>You set [src]'s mode.</span>")
|
||||
|
||||
/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
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
user.visible_message("<span class='suicide'>[user] is putting the live [name] in [user.p_their()] mouth! It looks like [user.p_theyre()] trying to commit suicide.</span>")
|
||||
return FIRELOSS
|
||||
|
||||
/obj/item/melee/baton/get_cell()
|
||||
return bcell
|
||||
|
||||
/obj/item/melee/baton/New()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
@@ -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 += "<a class='[class]' href='?src=[UID()];newtitle=[title]'>[label]</a>"
|
||||
|
||||
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(@{"<script type='text/javascript'>
|
||||
window.onload = function () {
|
||||
var msgs = document.getElementById('msgs');
|
||||
msgs.scrollTop = msgs.scrollHeight;
|
||||
}
|
||||
</script>"})
|
||||
convo.read = TRUE
|
||||
dat += "<h2>[check_rights(R_ADMIN, FALSE, user) ? fancy_title(current_title) : current_title]</h2>"
|
||||
dat += "<h4>"
|
||||
dat += "<table style='width:950px; border: 3px solid;'>"
|
||||
dat += "<div id='msgs' style='width:950px; border: 3px solid; overflow-y: scroll; height: 350px;'>"
|
||||
dat += "<table>"
|
||||
|
||||
for(var/message in convo.messages)
|
||||
dat += "<tr><td>[message]</td></tr>"
|
||||
|
||||
dat += "</table>"
|
||||
dat += "</div>"
|
||||
if(convo.typing)
|
||||
dat += "<i><span class='typing'>[current_title] is typing</span></i>"
|
||||
dat += "<br>"
|
||||
@@ -327,17 +339,23 @@
|
||||
if(check_rights(R_ADMIN, FALSE, user))
|
||||
dat += "<a href='?src=[UID()];ping=[current_title]'>Ping</a>"
|
||||
|
||||
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)]) (<A HREF='?_src_=holder;check_antagonist=1'>CA</A>)"
|
||||
|
||||
/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
|
||||
|
||||
@@ -455,6 +455,7 @@ var/global/list/special_role_times = list( //minimum age (in days) for accounts
|
||||
dat += "<b>Ghost Ears:</b> <a href='?_src_=prefs;preference=ghost_ears'><b>[(toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</b></a><br>"
|
||||
dat += "<b>Ghost Radio:</b> <a href='?_src_=prefs;preference=ghost_radio'><b>[(toggles & CHAT_GHOSTRADIO) ? "All Chatter" : "Nearest Speakers"]</b></a><br>"
|
||||
dat += "<b>Ghost Sight:</b> <a href='?_src_=prefs;preference=ghost_sight'><b>[(toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]</b></a><br>"
|
||||
dat += "<b>Ghost PDA:</b> <a href='?_src_=prefs;preference=ghost_pda'><b>[(toggles & CHAT_GHOSTPDA) ? "All PDA Messages" : "No PDA Messages"]</b></a><br>"
|
||||
if(check_rights(R_ADMIN,0))
|
||||
dat += "<b>OOC Color:</b> <span style='border: 1px solid #161616; background-color: [ooccolor ? ooccolor : normal_ooc_colour];'> </span> <a href='?_src_=prefs;preference=ooccolor;task=input'><b>Change</b></a><br>"
|
||||
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
|
||||
|
||||
@@ -266,3 +266,11 @@
|
||||
else
|
||||
to_chat(usr, "<span class='notice'>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!
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -97,6 +97,9 @@
|
||||
to_chat(usr, "The maintenance panel is [open ? "open" : "closed"].")
|
||||
to_chat(usr, "Hardsuit systems are [offline ? "<font color='red'>offline</font>" : "<font color='green'>online</font>"].")
|
||||
|
||||
/obj/item/rig/get_cell()
|
||||
return cell
|
||||
|
||||
/obj/item/rig/New()
|
||||
..()
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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("<span class='notice'>[src] examines [].</span>",gender==MALE?"himself":"herself"), \
|
||||
"<span class='notice'>You check yourself for injuries.</span>" \
|
||||
)
|
||||
|
||||
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 <span class='[status == "OK" ? "notice" : "warning"]'>Your [LB.name] is [status].</span>")
|
||||
|
||||
for(var/obj/item/I in LB.embedded_objects)
|
||||
to_chat(src, "\t <a href='byond://?src=[UID()];embedded_object=[I.UID()];embedded_limb=[LB.UID()]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
|
||||
|
||||
for(var/t in missing)
|
||||
to_chat(src, "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>")
|
||||
|
||||
if(H.bleed_rate)
|
||||
to_chat(src, "<span class='danger'>You are bleeding!</span>")
|
||||
if(staminaloss)
|
||||
if(staminaloss > 30)
|
||||
to_chat(src, "<span class='info'>You're completely exhausted.</span>")
|
||||
else
|
||||
to_chat(src, "<span class='info'>You feel fatigued.</span>")
|
||||
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("<span class='notice'>[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("<span class='notice'>[src] examines [].</span>",gender==MALE?"himself":"herself"), \
|
||||
"<span class='notice'>You check yourself for injuries.</span>" \
|
||||
)
|
||||
|
||||
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 <span class='[status == "OK" ? "notice" : "warning"]'>Your [LB.name] is [status].</span>")
|
||||
|
||||
for(var/obj/item/I in LB.embedded_objects)
|
||||
to_chat(src, "\t <a href='byond://?src=[UID()];embedded_object=[I.UID()];embedded_limb=[LB.UID()]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>")
|
||||
|
||||
for(var/t in missing)
|
||||
to_chat(src, "<span class='boldannounce'>Your [parse_zone(t)] is missing!</span>")
|
||||
|
||||
if(H.bleed_rate)
|
||||
to_chat(src, "<span class='danger'>You are bleeding!</span>")
|
||||
if(staminaloss)
|
||||
if(staminaloss > 30)
|
||||
to_chat(src, "<span class='info'>You're completely exhausted.</span>")
|
||||
else
|
||||
to_chat(src, "<span class='info'>You feel fatigued.</span>")
|
||||
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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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, "<span class='danger'>Procedure interrupted. Protocol terminated.</span>")
|
||||
return
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -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 = "<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)][stamps]</BODY></HTML>"
|
||||
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 = "<HTML><HEAD><TITLE>[name]</TITLE></HEAD><BODY>[infolinks ? info_links : info][stamps]</BODY></HTML>"
|
||||
if(view)
|
||||
usr << browse(data, "window=[name];size=[paper_width]x[paper_height]")
|
||||
onclose(usr, "[name]")
|
||||
data = "<div id='markdown'>[infolinks ? info_links : info]</div>[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("<title>[name]</title>")
|
||||
popup.open()
|
||||
return data
|
||||
|
||||
/obj/item/paper/verb/rename()
|
||||
|
||||
@@ -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("<span class='game say'>PDA Message - <span class='name'>[U.key] - [pda.owner]</span> -> <span class='name'>[P.owner]</span>: <span class='message'>[t]</span></span>", "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 = "<span class='name'>[pda.owner]</span> ([ghost_follow_link(pda, ghost=M)]) <span class='game say'>PDA Message</span> --> <span class='name'>[P.owner]</span> ([ghost_follow_link(P, ghost=M)]): <span class='message'>[t]</span>"
|
||||
to_chat(M, "[ghost_message]")
|
||||
|
||||
if(!conversations.Find("\ref[P]"))
|
||||
conversations.Add("\ref[P]")
|
||||
if(!PM.conversations.Find("\ref[pda]"))
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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, "<span class='warning'>A horrible migraine overpowers you.</span>")
|
||||
update_flags |= M.Stun(rand(2,5), FALSE)
|
||||
|
||||
@@ -92,6 +92,8 @@
|
||||
has_paint = 1
|
||||
update_icons()
|
||||
|
||||
/obj/spacepod/get_cell()
|
||||
return battery
|
||||
|
||||
/obj/spacepod/New()
|
||||
. = ..()
|
||||
|
||||
@@ -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.")
|
||||
|
||||
@@ -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;
|
||||
File diff suppressed because one or more lines are too long
@@ -56,6 +56,63 @@
|
||||
-->
|
||||
<div class="commit sansserif">
|
||||
|
||||
<h2 class="date">08 July 2019</h2>
|
||||
<h3 class="author">Arkatos updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Clicking on a health doll icon will now check you for injuries</li>
|
||||
<li class="rscadd">Rechargers now show their contents and charge status on close examine</li>
|
||||
<li class="tweak">Smartfridge will now try to put an item in your hands after vending, if able</li>
|
||||
</ul>
|
||||
<h3 class="author">AzuleUtama updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">The cybernetic implant bundle can no longer be bought by traitors.</li>
|
||||
</ul>
|
||||
<h3 class="author">Citinited updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Alt-clicking the RPD now brings up a radial menu with rotate, flip, and delete modes accessible. The main interface remains unchanged.</li>
|
||||
<li class="bugfix">Writing in blood can't be done while dead or incapacitated any more</li>
|
||||
<li class="bugfix">You can't write stuff in blood at a distance any more</li>
|
||||
</ul>
|
||||
<h3 class="author">Couls updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="imageadd">lantern sprites</li>
|
||||
<li class="bugfix">typo in msg</li>
|
||||
</ul>
|
||||
<h3 class="author">Improvedname updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Explorer suits now properly hide tails</li>
|
||||
</ul>
|
||||
<h3 class="author">JKnutson101 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Fixed Construction Permits deleting themselves prematurely.</li>
|
||||
</ul>
|
||||
<h3 class="author">Kyep updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">fixed a bug with biogenerator.</li>
|
||||
</ul>
|
||||
<h3 class="author">Markolie updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="rscadd">Ghosts can now see all PDA messages when enabled through a preference setting.</li>
|
||||
<li class="rscdel">The Mask of Nar'Sie transformation buttons have been removed, as the mask was removed a long time ago.</li>
|
||||
</ul>
|
||||
<h3 class="author">Shadeykins updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">Changed Quarantine, NT Default, Aggressive, and Corporate AI lawsets. balance: Reduced the ability for NT Default AI's to murder people just because.</li>
|
||||
<li class="bugfix">Removed several redundancies in Aggressive lawset.</li>
|
||||
<li class="spellcheck">Fixed a few subject-verb disagreements (is -> are).</li>
|
||||
</ul>
|
||||
<h3 class="author">Tayyyyyyy updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="tweak">paper supports markdown as well as pencode</li>
|
||||
<li class="rscadd">Autocomplete for ghost buttons</li>
|
||||
<li class="tweak">PMs window scrollable</li>
|
||||
<li class="bugfix">Fix a bug where a player who reconnects is still shown as disconnected</li>
|
||||
</ul>
|
||||
<h3 class="author">datlo updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
<li class="bugfix">Fix an antag rolling exploit.</li>
|
||||
</ul>
|
||||
|
||||
<h2 class="date">30 June 2019</h2>
|
||||
<h3 class="author">Crazylemon64 updated:</h3>
|
||||
<ul class="changes bgimages16">
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "datlo"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Fix an antag rolling exploit."
|
||||
@@ -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."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "Improvedname"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Explorer suits now properly hide tails"
|
||||
@@ -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"
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "JKnutson101"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "Fixed Construction Permits deleting themselves prematurely."
|
||||
@@ -1,4 +0,0 @@
|
||||
author: "Kyep"
|
||||
delete-after: True
|
||||
changes:
|
||||
- bugfix: "fixed a bug with biogenerator."
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 149 KiB After Width: | Height: | Size: 149 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 146 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 6.0 KiB |
Reference in New Issue
Block a user