Merge remote-tracking branch 'citadel/master' into unarmed_parry

This commit is contained in:
silicons
2020-07-16 19:39:46 -07:00
1129 changed files with 38441 additions and 43871 deletions
+19 -1
View File
@@ -101,6 +101,8 @@
stack_trace("Warning: [src]([type]) initialized multiple times!")
flags_1 |= INITIALIZED_1
if(loc)
SEND_SIGNAL(loc, COMSIG_ATOM_CREATED, src) /// Sends a signal that the new atom `src`, has been created at `loc`
//atom color stuff
if(color)
add_atom_colour(color, FIXED_COLOUR_PRIORITY)
@@ -366,6 +368,20 @@
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
/**
* Called when a mob examines (shift click or verb) this atom twice (or more) within EXAMINE_MORE_TIME (default 1.5 seconds)
*
* This is where you can put extra information on something that may be superfluous or not important in critical gameplay
* moments, while allowing people to manually double-examine to take a closer look
*
* Produces a signal [COMSIG_PARENT_EXAMINE_MORE]
*/
/atom/proc/examine_more(mob/user)
. = list()
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE_MORE, user, .)
if(!LAZYLEN(.)) // lol ..length
return list("<span class='notice'><i>You examine [src] closer, but find nothing of interest...</i></span>")
/// Updates the icon of the atom
/atom/proc/update_icon()
// I expect we're going to need more return flags and options in this proc
@@ -727,7 +743,7 @@
flags_1 |= ADMIN_SPAWNED_1
. = ..()
switch(var_name)
if("color")
if(NAMEOF(src, color))
add_atom_colour(color, ADMIN_COLOUR_PRIORITY)
/atom/vv_get_dropdown()
@@ -916,6 +932,8 @@
log_game(log_text)
if(LOG_GAME)
log_game(log_text)
if(LOG_SHUTTLE)
log_shuttle(log_text)
else
stack_trace("Invalid individual logging type: [message_type]. Defaulting to [LOG_GAME] (LOG_GAME).")
log_game(log_text)
+4 -4
View File
@@ -120,25 +120,25 @@
if((var_name in careful_edits) && (var_value % world.icon_size) != 0)
return FALSE
switch(var_name)
if("x")
if(NAMEOF(src, x))
var/turf/T = locate(var_value, y, z)
if(T)
forceMove(T)
return TRUE
return FALSE
if("y")
if(NAMEOF(src, y))
var/turf/T = locate(x, var_value, z)
if(T)
forceMove(T)
return TRUE
return FALSE
if("z")
if(NAMEOF(src, z))
var/turf/T = locate(x, y, var_value)
if(T)
forceMove(T)
return TRUE
return FALSE
if("loc")
if(NAMEOF(src, loc))
if(istype(var_value, /atom))
forceMove(var_value)
return TRUE
+2 -1
View File
@@ -350,8 +350,9 @@ Credit where due:
for(var/entry in changelog)
changelog_contents += "<li>[entry]</li>"
info = replacetext(info, "CLOCKCULTCHANGELOG", changelog_contents)
/*
/obj/item/paper/servant_primer/oui_getcontent(mob/target)
if(!is_servant_of_ratvar(target) && !isobserver(target))
return "<HTML><HEAD><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><TITLE>[name]</TITLE></HEAD><BODY>[stars(info)]<HR>[stamps]</BODY></HTML>"
return ..()
*/
+1 -1
View File
@@ -125,7 +125,7 @@
/datum/objective_item/steal/plasma/check_special_completion(obj/item/tank/T)
var/target_amount = text2num(name)
var/found_amount = 0
found_amount += T.air_contents.gases[/datum/gas/plasma]
found_amount += T.air_contents.get_moles(/datum/gas/plasma)
return found_amount>=target_amount
+3 -2
View File
@@ -209,7 +209,7 @@
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "sleeper", name, 550, 700, master_ui, state)
ui = new(user, src, ui_key, "Sleeper", name, 550, 700, master_ui, state)
ui.open()
/obj/machinery/sleeper/process()
@@ -421,7 +421,8 @@
desc = "A large cryogenics unit built from brass. Its surface is pleasantly cool the touch."
icon_state = "sleeper_clockwork"
enter_message = "<span class='bold inathneq_small'>You hear the gentle hum and click of machinery, and are lulled into a sense of peace.</span>"
possible_chems = list(list("epinephrine", "salbutamol", "bicaridine", "kelotane", "oculine", "inacusiate", "mannitol"))
possible_chems = list(list(/datum/reagent/medicine/epinephrine, /datum/reagent/medicine/salbutamol, /datum/reagent/medicine/bicaridine,
/datum/reagent/medicine/kelotane, /datum/reagent/medicine/oculine, /datum/reagent/medicine/inacusiate, /datum/reagent/medicine/mannitol))
/obj/machinery/sleeper/clockwork/process()
if(occupant && isliving(occupant))
+2 -2
View File
@@ -121,7 +121,7 @@ Class Procs:
var/ui_style // ID of custom TGUI style (optional)
var/ui_x
var/ui_y
var/init_process = TRUE //Stop processing from starting on init
var/interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE
var/fair_market_price = 69
@@ -138,7 +138,7 @@ Class Procs:
circuit = new circuit
circuit.apply_default_parts(src)
if(!speed_process)
if(!speed_process && init_process)
START_PROCESSING(SSmachines, src)
else
START_PROCESSING(SSfastprocess, src)
+48 -60
View File
@@ -39,7 +39,7 @@ GLOBAL_LIST_EMPTY(announcement_systems)
icon_state = (panel_open ? "AAS_Off_Open" : "AAS_Off")
/obj/machinery/announcement_system/update_overlays()
. =..()
. = ..()
if(arrivalToggle)
. += greenlight
@@ -54,19 +54,15 @@ GLOBAL_LIST_EMPTY(announcement_systems)
GLOB.announcement_systems -= src //"OH GOD WHY ARE THERE 100,000 LISTED ANNOUNCEMENT SYSTEMS?!!"
return ..()
/obj/machinery/announcement_system/power_change()
..()
update_icon()
/obj/machinery/announcement_system/attackby(obj/item/P, mob/user, params)
if(istype(P, /obj/item/screwdriver))
if(P.tool_behaviour == TOOL_SCREWDRIVER)
P.play_tool_sound(src)
panel_open = !panel_open
to_chat(user, "<span class='notice'>You [panel_open ? "open" : "close"] the maintenance hatch of [src].</span>")
update_icon()
else if(default_deconstruction_crowbar(P))
return
else if(istype(P, /obj/item/multitool) && panel_open && (stat & BROKEN))
else if(P.tool_behaviour == TOOL_MULTITOOL && panel_open && (stat & BROKEN))
to_chat(user, "<span class='notice'>You reset [src]'s firmware.</span>")
stat &= ~BROKEN
update_icon()
@@ -88,10 +84,6 @@ GLOBAL_LIST_EMPTY(announcement_systems)
message = CompileText(arrival, user, rank)
else if(message_type == "NEWHEAD" && newheadToggle)
message = CompileText(newhead, user, rank)
//CITADEL EDIT for cryopods
else if(message_type == "CRYOSTORAGE")
message = CompileText("%PERSON, %RANK has been moved to cryo storage.", user, rank)
//END EDIT
else if(message_type == "ARRIVALS_BROKEN")
message = "The arrivals shuttle has been damaged. Docking for repairs..."
@@ -103,61 +95,59 @@ GLOBAL_LIST_EMPTY(announcement_systems)
//config stuff
/obj/machinery/announcement_system/ui_interact(mob/user)
/obj/machinery/announcement_system/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
. = ..()
if(!user.canUseTopic(src, !hasSiliconAccessInArea(user)))
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "AutomatedAnnouncement", "Automated Announcement System", 500, 225, master_ui, state)
ui.open()
/obj/machinery/announcement_system/ui_data()
var/list/data = list()
data["arrival"] = arrival
data["arrivalToggle"] = arrivalToggle
data["newhead"] = newhead
data["newheadToggle"] = newheadToggle
return data
/obj/machinery/announcement_system/ui_act(action, param)
. = ..()
if(.)
return
if(!usr.canUseTopic(src, !issilicon(usr)))
return
if(stat & BROKEN)
visible_message("<span class='warning'>[src] buzzes.</span>", "<span class='italics'>You hear a faint buzz.</span>")
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 1)
visible_message("<span class='warning'>[src] buzzes.</span>", "<span class='hear'>You hear a faint buzz.</span>")
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, TRUE)
return
var/contents = "Arrival Announcement: <A href='?src=[REF(src)];ArrivalT-Topic=1'>([(arrivalToggle ? "On" : "Off")])</a><br>\n<A href='?src=[REF(src)];ArrivalTopic=1'>[arrival]</a><br><br>\n"
contents += "Departmental Head Announcement: <A href='?src=[REF(src)];NewheadT-Topic=1'>([(newheadToggle ? "On" : "Off")])</a><br>\n<A href='?src=[REF(src)];NewheadTopic=1'>[newhead]</a><br><br>\n"
var/datum/browser/popup = new(user, "announcement_config", "Automated Announcement Configuration", 370, 220)
popup.set_content(contents)
popup.open()
/obj/machinery/announcement_system/Topic(href, href_list)
if(..())
return
if(!usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
return
if(stat & BROKEN)
visible_message("<span class='warning'>[src] buzzes.</span>", "<span class='italics'>You hear a faint buzz.</span>")
playsound(src.loc, 'sound/machines/buzz-two.ogg', 50, 1)
return
if(href_list["ArrivalTopic"])
var/NewMessage = stripped_input(usr, "Enter in the arrivals announcement configuration.", "Arrivals Announcement Config", arrival)
if(!usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
return
if(NewMessage)
arrival = NewMessage
else if(href_list["NewheadTopic"])
var/NewMessage = stripped_input(usr, "Enter in the departmental head announcement configuration.", "Head Departmental Announcement Config", newhead)
if(!usr.canUseTopic(src, !hasSiliconAccessInArea(usr)))
return
if(NewMessage)
newhead = NewMessage
else if(href_list["NewheadT-Topic"])
newheadToggle = !newheadToggle
update_icon()
else if(href_list["ArrivalT-Topic"])
arrivalToggle = !arrivalToggle
update_icon()
switch(action)
if("ArrivalText")
var/NewMessage = trim(html_encode(param["newText"]), MAX_MESSAGE_LEN)
if(!usr.canUseTopic(src, !issilicon(usr)))
return
if(NewMessage)
arrival = NewMessage
log_game("The arrivals announcement was updated: [NewMessage] by:[key_name(usr)]")
if("NewheadText")
var/NewMessage = trim(html_encode(param["newText"]), MAX_MESSAGE_LEN)
if(!usr.canUseTopic(src, !issilicon(usr)))
return
if(NewMessage)
newhead = NewMessage
log_game("The head announcement was updated: [NewMessage] by:[key_name(usr)]")
if("NewheadToggle")
newheadToggle = !newheadToggle
update_icon()
if("ArrivalToggle")
arrivalToggle = !arrivalToggle
update_icon()
add_fingerprint(usr)
interact(usr)
/obj/machinery/announcement_system/attack_robot(mob/living/silicon/user)
. = attack_ai(user)
/obj/machinery/announcement_system/attack_ai(mob/user)
if(!user.canUseTopic(src, !hasSiliconAccessInArea(user)))
if(!user.canUseTopic(src, !issilicon(user)))
return
if(stat & BROKEN)
to_chat(user, "<span class='warning'>[src]'s firmware appears to be malfunctioning!</span>")
@@ -165,8 +155,8 @@ GLOBAL_LIST_EMPTY(announcement_systems)
interact(user)
/obj/machinery/announcement_system/proc/act_up() //does funny breakage stuff
stat |= BROKEN
update_icon()
if(!obj_break()) // if badmins flag this unbreakable or its already broken
return
arrival = pick("#!@%ERR-34%2 CANNOT LOCAT@# JO# F*LE!", "CRITICAL ERROR 99.", "ERR)#: DA#AB@#E NOT F(*ND!")
newhead = pick("OV#RL()D: \[UNKNOWN??\] DET*#CT)D!", "ER)#R - B*@ TEXT F*O(ND!", "AAS.exe is not responding. NanoOS is searching for a solution to the problem.")
@@ -177,9 +167,7 @@ GLOBAL_LIST_EMPTY(announcement_systems)
act_up()
/obj/machinery/announcement_system/emag_act()
. = ..()
if(obj_flags & EMAGGED)
return
obj_flags |= EMAGGED
act_up()
return TRUE
+1 -1
View File
@@ -64,7 +64,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "bank_machine", name, 320, 165, master_ui, state)
ui = new(user, src, ui_key, "BankMachine", name, 320, 165, master_ui, state)
ui.open()
/obj/machinery/computer/bank_machine/ui_data(mob/user)
+11 -2
View File
@@ -43,7 +43,11 @@
board.one_access = 1
board.accesses = req_one_access
/obj/machinery/button/update_icon_state()
setup_device()
/obj/machinery/button/update_icon()
cut_overlays()
if(panel_open)
icon_state = "button-open"
else if(stat & (NOPOWER|BROKEN))
@@ -129,7 +133,12 @@
A.id = id
initialized_button = 1
/obj/machinery/button/attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags)
/obj/machinery/button/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
if(id && istype(device, /obj/item/assembly/control))
var/obj/item/assembly/control/A = device
A.id = "[idnum][id]"
/obj/machinery/button/attack_hand(mob/user)
. = ..()
if(.)
return
+5
View File
@@ -72,6 +72,11 @@
if(mapload && is_station_level(z) && prob(3) && !start_active)
toggle_cam()
/obj/machinery/camera/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
for(var/i in network)
network -= i
network += "[idnum][i]"
/obj/machinery/camera/Destroy()
if(can_use())
toggle_cam(null, 0) //kick anyone viewing out and remove from the camera chunks
+5 -25
View File
@@ -75,31 +75,6 @@
speed_coeff = max(1, speed_coeff)
heal_level = clamp((efficiency * 10) + 10, MINIMUM_HEAL_LEVEL, 100)
//The return of data disks?? Just for transferring between genetics machine/cloning machine.
//TO-DO: Make the genetics machine accept them.
/obj/item/disk/data
name = "cloning data disk"
icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk.
var/list/fields = list()
var/list/mutations = list()
var/max_mutations = 6
var/read_only = 0 //Well,it's still a floppy disk
//Disk stuff.
/obj/item/disk/data/Initialize()
. = ..()
icon_state = "datadisk[rand(0,6)]"
add_overlay("datadisk_gene")
/obj/item/disk/data/attack_self(mob/user)
read_only = !read_only
to_chat(user, "<span class='notice'>You flip the write-protect tab to [read_only ? "protected" : "unprotected"].</span>")
/obj/item/disk/data/examine(mob/user)
. = ..()
. += "The write-protect tab is set to [read_only ? "protected" : "unprotected"]."
//Clonepod
/obj/machinery/clonepod/examine(mob/user)
@@ -411,6 +386,11 @@
to_chat(occupant, "<span class='notice'><b>There is a bright flash!</b><br><i>You feel like a new being.</i></span>")
mob_occupant.flash_act()
var/list/policies = CONFIG_GET(keyed_list/policyconfig)
var/policy = policies[POLICYCONFIG_ON_CLONE]
if(policy)
to_chat(occupant, policy)
occupant.log_message("revived using cloning.", LOG_GAME)
mob_occupant.adjustOrganLoss(ORGAN_SLOT_BRAIN, mob_occupant.getCloneLoss())
occupant.forceMove(T)
+44 -1
View File
@@ -46,7 +46,7 @@
/obj/machinery/computer/operating/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.not_incapacitated_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "operating_computer", name, 350, 470, master_ui, state)
ui = new(user, src, ui_key, "OperatingComputer", name, 350, 470, master_ui, state)
ui.open()
/obj/machinery/computer/operating/ui_data(mob/user)
@@ -108,6 +108,49 @@
))
else
data["patient"] = null
return data
switch(patient.stat)
if(CONSCIOUS)
data["patient"]["stat"] = "Conscious"
data["patient"]["statstate"] = "good"
if(SOFT_CRIT)
data["patient"]["stat"] = "Conscious"
data["patient"]["statstate"] = "average"
if(UNCONSCIOUS)
data["patient"]["stat"] = "Unconscious"
data["patient"]["statstate"] = "average"
if(DEAD)
data["patient"]["stat"] = "Dead"
data["patient"]["statstate"] = "bad"
data["patient"]["health"] = patient.health
data["patient"]["blood_type"] = patient.dna.blood_type
data["patient"]["maxHealth"] = patient.maxHealth
data["patient"]["minHealth"] = HEALTH_THRESHOLD_DEAD
data["patient"]["bruteLoss"] = patient.getBruteLoss()
data["patient"]["fireLoss"] = patient.getFireLoss()
data["patient"]["toxLoss"] = patient.getToxLoss()
data["patient"]["oxyLoss"] = patient.getOxyLoss()
data["procedures"] = list()
if(patient.surgeries.len)
for(var/datum/surgery/procedure in patient.surgeries)
var/datum/surgery_step/surgery_step = procedure.get_surgery_step()
var/chems_needed = surgery_step.get_chem_list()
var/alternative_step
var/alt_chems_needed = ""
if(surgery_step.repeatable)
var/datum/surgery_step/next_step = procedure.get_surgery_next_step()
if(next_step)
alternative_step = capitalize(next_step.name)
alt_chems_needed = next_step.get_chem_list()
else
alternative_step = "Finish operation"
data["procedures"] += list(list(
"name" = capitalize("[parse_zone(procedure.location)] [procedure.name]"),
"next_step" = capitalize(surgery_step.name),
"chems_needed" = chems_needed,
"alternative_step" = alternative_step,
"alt_chems_needed" = alt_chems_needed
))
return data
/obj/machinery/computer/operating/ui_act(action, params)
+8 -2
View File
@@ -8,6 +8,8 @@
icon_keyboard = "tech_key"
icon_screen = "ai-fixer"
light_color = LIGHT_COLOR_PINK
ui_x = 370
ui_y = 360
/obj/machinery/computer/aifixer/attackby(obj/I, mob/user, params)
if(occupier && istype(I, /obj/item/screwdriver))
@@ -18,8 +20,12 @@
else
return ..()
/obj/machinery/computer/aifixer/ui_interact(mob/user)
. = ..()
/obj/machinery/computer/aifixer/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "AiRestorer", name, ui_x, ui_y, master_ui, state)
ui.open()
var/dat = ""
+14
View File
@@ -136,3 +136,17 @@
empprize = pickweight(prizes)
new empprize(loc)
explosion(loc, -1, 0, 1+num_of_prizes, flame_range = 1+num_of_prizes)
/obj/machinery/computer/arcade/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/stack/arcadeticket))
var/obj/item/stack/arcadeticket/T = O
var/amount = T.get_amount()
if(amount <2)
to_chat(user, "<span class='warning'>You need 2 tickets to claim a prize!</span>")
return
prizevend(user)
T.pay_tickets()
T.update_icon()
O = T
to_chat(user, "<span class='notice'>You turn in 2 tickets to the [src] and claim a prize!</span>")
return
@@ -184,6 +184,15 @@
blocked = FALSE
return
/obj/machinery/computer/arcade/battle/examine_more(mob/user)
to_chat(user, "<span class='notice'>Scribbled on the side of the Arcade Machine you notice some writing...\
\nmagical -> >=50 power\
\nsmart -> defend, defend, light attack\
\nshotgun -> defend, defend, power attack\
\nshort temper -> counter, counter, counter\
\npoisonous -> light attack, light attack, light attack\
\nchonker -> power attack, power attack, power attack</span>")
return ..()
/obj/machinery/computer/arcade/battle/emag_act(mob/user)
. = ..()
+1 -1
View File
@@ -23,7 +23,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmos_alert", name, 350, 300, master_ui, state)
ui = new(user, src, ui_key, "AtmosAlertConsole", name, 350, 300, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_alert/ui_data(mob/user)
@@ -53,14 +53,14 @@
"id_tag" = id_tag,
"timestamp" = world.time,
"pressure" = air_sample.return_pressure(),
"temperature" = air_sample.temperature,
"temperature" = air_sample.return_temperature(),
"gases" = list()
))
var/total_moles = air_sample.total_moles()
if(total_moles)
for(var/gas_id in air_sample.gases)
for(var/gas_id in air_sample.get_gases())
var/gas_name = GLOB.meta_gas_names[gas_id]
signal.data["gases"][gas_name] = air_sample.gases[gas_id] / total_moles * 100
signal.data["gases"][gas_name] = air_sample.get_moles(gas_id) / total_moles * 100
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
@@ -127,7 +127,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state)
ui = new(user, src, ui_key, "AtmosControlConsole", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/ui_data(mob/user)
@@ -269,7 +269,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state)
ui = new(user, src, ui_key, "AtmosControlConsole", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/tank/ui_data(mob/user)
+172 -93
View File
@@ -4,109 +4,166 @@
icon_screen = "cameras"
icon_keyboard = "security_key"
circuit = /obj/item/circuitboard/computer/security
var/last_pic = 1
var/list/network = list("ss13")
var/list/watchers = list() //who's using the console, associated with the camera they're on.
light_color = LIGHT_COLOR_RED
ui_x = 870
ui_y = 708
var/list/network = list("ss13")
var/obj/machinery/camera/active_camera
var/list/concurrent_users = list()
// Stuff needed to render the map
var/map_name
var/const/default_map_size = 15
var/obj/screen/cam_screen
var/obj/screen/plane_master/lighting/cam_plane_master
var/obj/screen/background/cam_background
/obj/machinery/computer/security/Initialize()
. = ..()
// Map name has to start and end with an A-Z character,
// and definitely NOT with a square bracket or even a number.
// I wasted 6 hours on this. :agony:
map_name = "camera_console_[REF(src)]_map"
// Convert networks to lowercase
for(var/i in network)
network -= i
network += lowertext(i)
/obj/machinery/computer/security/check_eye(mob/user)
if(!can_interact(user) || !(user in watchers) || !watchers[user])
user.unset_machine()
return
var/obj/machinery/camera/C = watchers[user]
if(!C.can_use())
user.unset_machine()
return
/obj/machinery/computer/security/on_unset_machine(mob/user)
watchers.Remove(user)
user.reset_perspective(null)
// Initialize map objects
cam_screen = new
cam_screen.name = "screen"
cam_screen.assigned_map = map_name
cam_screen.del_on_map_removal = FALSE
cam_screen.screen_loc = "[map_name]:1,1"
cam_plane_master = new
cam_plane_master.name = "plane_master"
cam_plane_master.assigned_map = map_name
cam_plane_master.del_on_map_removal = FALSE
cam_plane_master.screen_loc = "[map_name]:CENTER"
cam_background = new
cam_background.assigned_map = map_name
cam_background.del_on_map_removal = FALSE
/obj/machinery/computer/security/Destroy()
if(watchers.len)
for(var/mob/M in watchers)
M.unset_machine() //to properly reset the view of the users if the console is deleted.
qdel(cam_screen)
qdel(cam_plane_master)
qdel(cam_background)
return ..()
/obj/machinery/computer/security/can_interact(mob/user)
if((!hasSiliconAccessInArea(user) && !Adjacent(user)) || is_blind(user) || !in_view_range(user, src))
return FALSE
return ..()
/obj/machinery/computer/security/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
for(var/i in network)
network -= i
network += "[idnum][i]"
/obj/machinery/computer/security/interact(mob/user, special_state)
/obj/machinery/computer/security/ui_interact(\
mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
// Update UI
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
// Show static if can't use the camera
if(!active_camera?.can_use())
show_camera_static()
if(!ui)
var/user_ref = REF(user)
var/is_living = isliving(user)
// Ghosts shouldn't count towards concurrent users, which produces
// an audible terminal_on click.
if(is_living)
concurrent_users += user_ref
// Turn on the console
if(length(concurrent_users) == 1 && is_living)
playsound(src, 'sound/machines/terminal_on.ogg', 25, FALSE)
use_power(active_power_usage)
// Register map objects
user.client.register_map_obj(cam_screen)
user.client.register_map_obj(cam_plane_master)
user.client.register_map_obj(cam_background)
// Open UI
ui = new(user, src, ui_key, "CameraConsole", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/security/ui_data()
var/list/data = list()
data["network"] = network
data["activeCamera"] = null
if(active_camera)
data["activeCamera"] = list(
name = active_camera.c_tag,
status = active_camera.status,
)
return data
/obj/machinery/computer/security/ui_static_data()
var/list/data = list()
data["mapRef"] = map_name
var/list/cameras = get_available_cameras()
data["cameras"] = list()
for(var/i in cameras)
var/obj/machinery/camera/C = cameras[i]
data["cameras"] += list(list(
name = C.c_tag,
))
return data
/obj/machinery/computer/security/ui_act(action, params)
. = ..()
if (ismob(user) && !isliving(user)) // ghosts don't need cameras
return
if (!network)
stack_trace("No camera network")
user.unset_machine()
return FALSE
if (!(islist(network)))
stack_trace("Camera network is not a list")
user.unset_machine()
return FALSE
var/list/camera_list = get_available_cameras()
if(!(user in watchers))
for(var/Num in camera_list)
var/obj/machinery/camera/CAM = camera_list[Num]
if(istype(CAM) && CAM.can_use())
watchers[user] = CAM //let's give the user the first usable camera, and then let him change to the camera he wants.
break
if(!(user in watchers))
user.unset_machine() // no usable camera on the network, we disconnect the user from the computer.
return FALSE
playsound(src, 'sound/machines/terminal_prompt.ogg', 25, 0)
use_camera_console(user)
/obj/machinery/computer/security/proc/use_camera_console(mob/user)
var/list/camera_list = get_available_cameras()
var/t = input(user, "Which camera should you change to?") as null|anything in camera_list
if(!src || user.machine != src) //while we were choosing we got disconnected from our computer or are using another machine.
return
if(!t || t == "Cancel")
user.unset_machine()
playsound(src, 'sound/machines/terminal_off.ogg', 25, 0)
if(.)
return
var/obj/machinery/camera/C = camera_list[t]
if(action == "switch_camera")
var/c_tag = params["name"]
var/list/cameras = get_available_cameras()
var/obj/machinery/camera/C = cameras[c_tag]
active_camera = C
playsound(src, get_sfx("terminal_type"), 25, FALSE)
if(!C || !C.can_use() || !can_interact(user))
user.unset_machine()
return FALSE
// Show static if can't use the camera
if(!active_camera?.can_use())
show_camera_static()
return TRUE
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 25, 0)
if(isAI(user))
var/mob/living/silicon/ai/A = user
A.eyeobj.setLoc(get_turf(C))
A.client.eye = A.eyeobj
else
user.reset_perspective(C)
user.overlay_fullscreen("flash", /obj/screen/fullscreen/flash/static)
user.clear_fullscreen("flash", 5)
watchers[user] = C
use_power(50)
addtimer(CALLBACK(src, .proc/use_camera_console, user), 5)
var/list/visible_turfs = list()
for(var/turf/T in (C.isXRay() \
? range(C.view_range, C) \
: view(C.view_range, C)))
visible_turfs += T
//returns the list of cameras accessible from this computer
var/list/bbox = get_bbox_of_atoms(visible_turfs)
var/size_x = bbox[3] - bbox[1] + 1
var/size_y = bbox[4] - bbox[2] + 1
cam_screen.vis_contents = visible_turfs
cam_background.icon_state = "clear"
cam_background.fill_rect(1, 1, size_x, size_y)
return TRUE
/obj/machinery/computer/security/ui_close(mob/user)
var/user_ref = REF(user)
var/is_living = isliving(user)
// Living creature or not, we remove you anyway.
concurrent_users -= user_ref
// Unregister map objects
user.client.clear_map(map_name)
// Turn off the console
if(length(concurrent_users) == 0 && is_living)
active_camera = null
playsound(src, 'sound/machines/terminal_off.ogg', 25, FALSE)
use_power(0)
/obj/machinery/computer/security/proc/show_camera_static()
cam_screen.vis_contents.Cut()
cam_background.icon_state = "scanline2"
cam_background.fill_rect(1, 1, default_map_size, default_map_size)
// Returns the list of cameras accessible from this computer
/obj/machinery/computer/security/proc/get_available_cameras()
var/list/L = list()
for (var/obj/machinery/camera/C in GLOB.cameranet.cameras)
if((is_away_level(z) || is_away_level(C.z)) && (C.z != z))//if on away mission, can only receive feed from same z_level cameras
continue
L.Add(C)
camera_sort(L)
var/list/D = list()
D["Cancel"] = "Cancel"
for(var/obj/machinery/camera/C in L)
if(!C.network)
stack_trace("Camera in a cameranet has no camera network")
@@ -114,9 +171,9 @@
if(!(islist(C.network)))
stack_trace("Camera in a cameranet has a non-list camera network")
continue
var/list/tempnetwork = C.network&network
var/list/tempnetwork = C.network & network
if(tempnetwork.len)
D["[C.c_tag][(C.status ? null : " (Deactivated)")]"] = C
D["[C.c_tag]"] = C
return D
// SECURITY MONITORS
@@ -127,7 +184,6 @@
icon_state = "television"
icon_keyboard = null
icon_screen = "detective_tv"
clockwork = TRUE //it'd look weird
pass_flags = PASSTABLE
/obj/machinery/computer/security/mining
@@ -145,7 +201,7 @@
circuit = /obj/item/circuitboard/computer/research
/obj/machinery/computer/security/hos
name = "Head of Security's camera console"
name = "\improper Head of Security's camera console"
desc = "A custom security console with added access to the labor camp network."
network = list("ss13", "labor")
circuit = null
@@ -157,7 +213,7 @@
circuit = null
/obj/machinery/computer/security/qm
name = "Quartermaster's camera console"
name = "\improper Quartermaster's camera console"
desc = "A console with access to the mining, auxillary base and vault camera networks."
network = list("mine", "auxbase", "vault")
circuit = null
@@ -172,7 +228,6 @@
network = list("thunder")
density = FALSE
circuit = null
clockwork = TRUE //it'd look very weird
light_power = 0
/obj/machinery/computer/security/telescreen/Initialize()
@@ -190,11 +245,35 @@
name = "entertainment monitor"
desc = "Damn, they better have the /tg/ channel on these things."
icon = 'icons/obj/status_display.dmi'
icon_state = "entertainment"
icon_state = "entertainment_blank"
network = list("thunder")
density = FALSE
circuit = null
interaction_flags_atom = NONE // interact() is called by BigClick()
var/icon_state_off = "entertainment_blank"
var/icon_state_on = "entertainment"
/obj/machinery/computer/security/telescreen/entertainment/Initialize()
. = ..()
RegisterSignal(src, COMSIG_CLICK, .proc/BigClick)
// Bypass clickchain to allow humans to use the telescreen from a distance
/obj/machinery/computer/security/telescreen/entertainment/proc/BigClick()
interact(usr)
/obj/machinery/computer/security/telescreen/entertainment/proc/notify(on)
if(on && icon_state == icon_state_off)
say(pick(
"Feats of bravery live now at the thunderdome!",
"Two enter, one leaves! Tune in now!",
"Violence like you've never seen it before!",
"Spears! Camera! Action! LIVE NOW!"))
icon_state = icon_state_on
else
icon_state = icon_state_off
/obj/machinery/computer/security/telescreen/rd
name = "Research Director's telescreen"
name = "\improper Research Director's telescreen"
desc = "Used for watching the AI and the RD's goons from the safety of his office."
network = list("rd", "aicore", "aiupload", "minisat", "xeno", "test")
@@ -202,26 +281,26 @@
name = "circuitry telescreen"
desc = "Used for watching the other eggheads from the safety of the circuitry lab."
network = list("rd")
/obj/machinery/computer/security/telescreen/ce
name = "Chief Engineer's telescreen"
name = "\improper Chief Engineer's telescreen"
desc = "Used for watching the engine, telecommunications and the minisat."
network = list("engine", "singularity", "tcomms", "minisat")
/obj/machinery/computer/security/telescreen/cmo
name = "Chief Medical Officer's telescreen"
name = "\improper Chief Medical Officer's telescreen"
desc = "A telescreen with access to the medbay's camera network."
network = list("medbay")
/obj/machinery/computer/security/telescreen/vault
name = "Vault monitor"
name = "vault monitor"
desc = "A telescreen that connects to the vault's camera network."
network = list("vault")
/obj/machinery/computer/security/telescreen/toxins
name = "Bomb test site monitor"
name = "bomb test site monitor"
desc = "A telescreen that connects to the bomb test site's camera."
network = list("toxin")
network = list("toxins")
/obj/machinery/computer/security/telescreen/engine
name = "engine monitor"
@@ -254,7 +333,7 @@
network = list("minisat")
/obj/machinery/computer/security/telescreen/aiupload
name = "AI upload monitor"
name = "\improper AI upload monitor"
desc = "A telescreen that connects to the AI upload's camera network."
network = list("aiupload")
@@ -29,9 +29,17 @@
if(lock_override & CAMERA_LOCK_REEBE)
z_lock |= SSmapping.levels_by_trait(ZTRAIT_REEBE)
/obj/machinery/computer/camera_advanced/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
for(var/i in networks)
networks -= i
networks += "[idnum][i]"
/obj/machinery/computer/camera_advanced/syndie
icon_keyboard = "syndie_key"
/obj/machinery/computer/camera_advanced/syndie/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
return //For syndie nuke shuttle, to spy for station.
/obj/machinery/computer/camera_advanced/proc/CreateEye()
eyeobj = new()
eyeobj.origin = src
+36 -40
View File
@@ -61,7 +61,7 @@
// main interface
if("main")
state = STATE_DEFAULT
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
if("login")
var/mob/M = usr
@@ -73,19 +73,19 @@
auth_id = "[I.registered_name] ([I.assignment])"
if((ACCESS_CAPTAIN in I.access))
authenticated = 2
playsound(src, 'sound/machines/terminal_on.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE)
if(obj_flags & EMAGGED)
authenticated = 2
auth_id = "Unknown"
to_chat(M, "<span class='warning'>[src] lets out a quiet alarm as its login is overridden.</span>")
playsound(src, 'sound/machines/terminal_on.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_alert.ogg', 25, 0)
playsound(src, 'sound/machines/terminal_on.ogg', 50, FALSE)
playsound(src, 'sound/machines/terminal_alert.ogg', 25, FALSE)
if(prob(25))
for(var/mob/living/silicon/ai/AI in active_ais())
SEND_SOUND(AI, sound('sound/machines/terminal_alert.ogg', volume = 10)) //Very quiet for balance reasons
if("logout")
authenticated = 0
playsound(src, 'sound/machines/terminal_off.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_off.ogg', 50, FALSE)
if("swipeidseclevel")
var/mob/M = usr
@@ -109,7 +109,7 @@
security_level_cd = world.time + 15 SECONDS
if(GLOB.security_level != old_level)
to_chat(usr, "<span class='notice'>Authorization confirmed. Modifying security level.</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
//Only notify people if an actual change happened
var/security_level = NUM2SECLEVEL(GLOB.security_level)
log_game("[key_name(usr)] has changed the security level to [security_level] with [src] at [AREACOORD(usr)].")
@@ -118,28 +118,28 @@
tmp_alertlevel = 0
else
to_chat(usr, "<span class='warning'>You are not authorized to do this!</span>")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
tmp_alertlevel = 0
state = STATE_DEFAULT
else
to_chat(usr, "<span class='warning'>You need to swipe your ID!</span>")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
if("announce")
if(authenticated==2)
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
make_announcement(usr)
if("crossserver")
if(authenticated==2)
if(!checkCCcooldown())
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
var/input = stripped_multiline_input(usr, "Please choose a message to transmit to allied stations. Please be aware that this process is very expensive, and abuse will lead to... termination.", "Send a message to an allied station.", "")
if(!input || !(usr in view(1,src)) || !checkCCcooldown())
return
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
send2otherserver("[station_name()]", input,"Comms_Console")
minor_announce(input, title = "Outgoing message to allied station")
usr.log_talk(input, LOG_SAY, tag="message to the other server")
@@ -168,22 +168,18 @@
if(D)
points_to_check = D.account_balance
if(points_to_check >= S.credit_cost)
var/obj/machinery/shuttle_manipulator/M = locate() in GLOB.machines
if(M)
SSshuttle.shuttle_purchased = TRUE
D.adjust_money(-S.credit_cost)
minor_announce("[usr.real_name] has purchased [S.name] for [S.credit_cost] credits." , "Shuttle Purchase")
message_admins("[ADMIN_LOOKUPFLW(usr)] purchased [S.name].")
SSblackbox.record_feedback("text", "shuttle_purchase", 1, "[S.name]")
M.unload_preview()
M.load_template(S)
M.existing_shuttle = SSshuttle.emergency
M.action_load(S)
message_admins("[S.name] loaded, purchased by [usr]")
else
to_chat(usr, "Something went wrong! The shuttle exchange system seems to be down.")
SSshuttle.shuttle_purchased = TRUE
SSshuttle.unload_preview()
SSshuttle.load_template(S)
SSshuttle.existing_shuttle = SSshuttle.emergency
SSshuttle.action_load(S)
D.adjust_money(-S.credit_cost)
minor_announce("[usr.real_name] has purchased [S.name] for [S.credit_cost] credits." , "Shuttle Purchase")
message_admins("[ADMIN_LOOKUPFLW(usr)] purchased [S.name].")
log_shuttle("[key_name(usr)] has purchased [S.name].")
SSblackbox.record_feedback("text", "shuttle_purchase", 1, "[S.name]")
else
to_chat(usr, "Not enough credits.")
to_chat(usr, "<span class='alert'>Insufficient credits.</span>")
if("callshuttle")
state = STATE_DEFAULT
@@ -268,7 +264,7 @@
// Status display stuff
if("setstat")
playsound(src, "terminal_type", 50, 0)
playsound(src, "terminal_type", 50, FALSE)
switch(href_list["statdisp"])
if("message")
post_status("message", stat_msg1, stat_msg2)
@@ -308,13 +304,13 @@
if("MessageSyndicate")
if((authenticated==2) && (obj_flags & EMAGGED))
if(!checkCCcooldown())
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, 0)
to_chat(usr, "<span class='warning'>Arrays recycling. Please stand by.</span>")
playsound(src, 'sound/machines/terminal_prompt_deny.ogg', 50, FALSE)
return
var/input = stripped_input(usr, "Please choose a message to transmit to \[ABNORMAL ROUTING COORDINATES\] via quantum entanglement. Please be aware that this process is very expensive, and abuse will lead to... termination. Transmission does not guarantee a response.", "Send a message to /??????/.", "")
if(!input || !(usr in view(1,src)) || !checkCCcooldown())
return
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
Syndicate_announce(input, usr)
to_chat(usr, "<span class='danger'>SYSERR @l(19833)of(transmit.dm): !@$ MESSAGE TRANSMITTED TO SYNDICATE COMMAND.</span>")
for(var/client/X in GLOB.admins)
@@ -327,7 +323,7 @@
if("RestoreBackup")
to_chat(usr, "<span class='notice'>Backup routing data restored!</span>")
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
obj_flags &= ~EMAGGED
updateDialog()
@@ -341,7 +337,7 @@
return
Nuke_request(input, usr)
to_chat(usr, "<span class='notice'>Request sent.</span>")
usr.log_message("has requested the nuclear codes from CentCom", LOG_SAY)
usr.log_message("has requested the nuclear codes from CentCom with reason \"[input]\"", LOG_SAY)
priority_announce("The codes for the on-station nuclear self-destruct have been requested by [usr]. Confirmation or denial of this request will be sent shortly.", "Nuclear Self Destruct Codes Requested","commandreport")
CM.lastTimeUsed = world.time
@@ -448,7 +444,7 @@
if(authenticated == 1)
authenticated = 2
to_chat(user, "<span class='danger'>You scramble the communication routing circuits!</span>")
playsound(src, 'sound/machines/terminal_alert.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_alert.ogg', 50, FALSE)
return TRUE
/obj/machinery/computer/communications/ui_interact(mob/user)
@@ -514,16 +510,16 @@
dat += "<BR>\[ <A HREF='?src=[REF(src)];operation=login'>Log In</A> \]"
if(STATE_CALLSHUTTLE)
dat += get_call_shuttle_form()
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
if(STATE_CANCELSHUTTLE)
dat += get_cancel_shuttle_form()
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
if(STATE_MESSAGELIST)
dat += "Messages:"
for(var/i in 1 to messages.len)
var/datum/comm_message/M = messages[i]
dat += "<BR><A HREF='?src=[REF(src)];operation=viewmessage;message-num=[i]'>[M.title]</A>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
if(STATE_VIEWMESSAGE)
if (currmsg)
dat += "<B>[currmsg.title]</B><BR><BR>[currmsg.content]"
@@ -557,7 +553,7 @@
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=redalert'>Red Alert</A> |"
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=lockdown'>Lockdown</A> |"
dat += " <A HREF='?src=[REF(src)];operation=setstat;statdisp=alert;alert=biohazard'>Biohazard</A> \]<BR><HR>"
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, FALSE)
if(STATE_ALERT_LEVEL)
dat += "Current alert level: [NUM2SECLEVEL(GLOB.security_level)]<BR>"
if(GLOB.security_level == SEC_LEVEL_DELTA)
@@ -571,7 +567,7 @@
dat += "Confirm the change to: [NUM2SECLEVEL(tmp_alertlevel)]<BR>"
dat += "<A HREF='?src=[REF(src)];operation=swipeidseclevel'>Swipe ID</A> to confirm change.<BR>"
if(STATE_TOGGLE_EMERGENCY)
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0)
playsound(src, 'sound/machines/terminal_prompt.ogg', 50, FALSE)
if(GLOB.emergency_access == 1)
dat += "<b>Emergency Maintenance Access is currently <font color='red'>ENABLED</font></b>"
dat += "<BR>Restore maintenance access restrictions? <BR>\[ <A HREF='?src=[REF(src)];operation=disableemergency'>OK</A> | <A HREF='?src=[REF(src)];operation=viewmessage'>Cancel</A> \]"
@@ -722,7 +718,7 @@
/obj/machinery/computer/communications/proc/make_announcement(mob/living/user, is_silicon)
if(!SScommunications.can_announce(user, is_silicon))
to_chat(user, "Intercomms recharging. Please stand by.")
to_chat(user, "<span class='alert'>Intercomms recharging. Please stand by.</span>")
return
var/input = stripped_input(user, "Please choose a message to announce to the station crew.", "What?")
if(!input || !user.canUseTopic(src))
+1 -1
View File
@@ -80,7 +80,7 @@ GLOBAL_DATUM_INIT(crewmonitor, /datum/crewmonitor, new)
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if (!ui)
ui = new(user, src, ui_key, "crew", "crew monitor", 800, 600 , master_ui, state)
ui = new(user, src, ui_key, "CrewConsole", "crew monitor", 800, 600 , master_ui, state)
ui.open()
/datum/crewmonitor/proc/show(mob/M, source)
File diff suppressed because it is too large Load Diff
@@ -56,7 +56,7 @@
/obj/machinery/computer/launchpad/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = 0, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "launchpad_console", name, ui_x, ui_y, master_ui, state)
ui = new(user, src, ui_key, "LaunchpadConsole", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/launchpad/ui_data(mob/user)
@@ -25,7 +25,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "gulag_console", name, ui_x, ui_y, master_ui, state)
ui = new(user, src, ui_key, "GulagTeleporterConsole", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/prisoner/gulag_teleporter_computer/ui_data(mob/user)
+87 -127
View File
@@ -5,163 +5,123 @@
icon_keyboard = "rd_key"
req_access = list(ACCESS_ROBOTICS)
circuit = /obj/item/circuitboard/computer/robotics
var/temp = null
light_color = LIGHT_COLOR_PINK
ui_x = 500
ui_y = 460
/obj/machinery/computer/robotics/proc/can_control(mob/user, mob/living/silicon/robot/R)
. = FALSE
if(!istype(R))
return FALSE
return
if(isAI(user))
if (R.connected_ai != user)
return FALSE
if(R.connected_ai != user)
return
if(iscyborg(user))
if (R != user)
return FALSE
if(R != user)
return
if(R.scrambledcodes)
return FALSE
if (hasSiliconAccessInArea(user) && !issilicon(user))
if (!Adjacent(user))
return FALSE
return
return TRUE
/obj/machinery/computer/robotics/ui_interact(mob/user)
. = ..()
if (src.z > 6)
to_chat(user, "<span class='boldannounce'>Unable to establish a connection</span>: \black You're too far away from the station!")
return
user.set_machine(src)
var/dat
var/robots = 0
/obj/machinery/computer/robotics/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "RoboticsControlConsole", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/robotics/ui_data(mob/user)
var/list/data = list()
data["can_hack"] = FALSE
if(issilicon(user))
var/mob/living/silicon/S = user
if(S.hack_software)
data["can_hack"] = TRUE
else if(IsAdminGhost(user))
data["can_hack"] = TRUE
data["cyborgs"] = list()
for(var/mob/living/silicon/robot/R in GLOB.silicon_mobs)
if(!can_control(user, R))
continue
robots++
dat += "[R.name] |"
if(R.stat)
dat += " Not Responding |"
else if(R.locked_down)
dat += " Locked Down |"
else
dat += " Operating Normally |"
if(R.cell)
dat += " Battery Installed ([R.cell.charge]/[R.cell.maxcharge]) |"
else
dat += " No Cell Installed |"
if(R.module)
dat += " Module Installed ([R.module.name]) |"
else
dat += " No Module Installed |"
if(R.connected_ai)
dat += " Slaved to [R.connected_ai.name] |"
else
dat += " Independent from AI |"
if(issilicon(user) && user != R)
var/mob/living/silicon/S = user
if(is_servant_of_ratvar(S))
dat += "<A href='?src=[REF(src)];convert=[REF(R)]'>(<font color=#BE8700><i>Convert</i></font>)</A> "
else if(S.hack_software && !R.emagged)
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
else if(IsAdminGhost(user) && !R.emagged)
dat += "<A href='?src=[REF(src)];magbot=[REF(R)]'>(<font color=blue><i>Hack</i></font>)</A> "
dat += "<A href='?src=[REF(src)];stopbot=[REF(R)]'>(<font color=green><i>[R.locked_down? "Lockdown" : "Release"]</i></font>)</A> "
dat += "<A href='?src=[REF(src)];killbot=[REF(R)]'>(<font color=red><i>Destroy</i></font>)</A>"
dat += "<BR>"
if(z != (get_turf(R)).z)
continue
var/list/cyborg_data = list(
name = R.name,
locked_down = R.locked_down,
status = R.stat,
charge = R.cell ? round(R.cell.percent()) : null,
module = R.module ? "[R.module.name] Module" : "No Module Detected",
synchronization = R.connected_ai,
emagged = R.emagged,
ref = REF(R)
)
data["cyborgs"] += list(cyborg_data)
if(!robots)
dat += "No Cyborg Units detected within access parameters."
dat += "<BR>"
var/drones = 0
data["drones"] = list()
for(var/mob/living/simple_animal/drone/D in GLOB.drones_list)
if(D.hacked)
continue
drones++
dat += "[D.name] |"
if(D.stat)
dat += " Not Responding |"
dat += "<A href='?src=[REF(src)];killdrone=[REF(D)]'>(<font color=red><i>Destroy</i></font>)</A>"
dat += "<BR>"
if(z != (get_turf(D)).z)
continue
var/list/drone_data = list(
name = D.name,
status = D.stat,
ref = REF(D)
)
data["drones"] += list(drone_data)
if(!drones)
dat += "No Drone Units detected within access parameters."
return data
var/datum/browser/popup = new(user, "computer", "Cyborg Control Console", 400, 500)
popup.set_content(dat)
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return
/obj/machinery/computer/robotics/Topic(href, href_list)
/obj/machinery/computer/robotics/ui_act(action, params)
if(..())
return
if (href_list["temp"])
src.temp = null
else if (href_list["killbot"])
if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["killbot"]) in GLOB.silicon_mobs
if(can_control(usr, R))
var/choice = input("Are you certain you wish to detonate [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
switch(action)
if("killbot")
if(allowed(usr))
var/mob/living/silicon/robot/R = locate(params["ref"]) in GLOB.silicon_mobs
if(can_control(usr, R) && !..())
var/turf/T = get_turf(R)
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(R, R.client)] at [ADMIN_VERBOSEJMP(T)]!</span>")
log_game("\<span class='notice'>[key_name(usr)] detonated [key_name(R)]!</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "<br><br><span class='alert'>ALERT - Cyborg detonation detected: [R.name]</span><br>")
R.self_destruct()
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
else if (href_list["stopbot"])
if(src.allowed(usr))
var/mob/living/silicon/robot/R = locate(href_list["stopbot"]) in GLOB.silicon_mobs
if(can_control(usr, R))
var/choice = input("Are you certain you wish to [!R.locked_down ? "lock down" : "release"] [R.name]?") in list("Confirm", "Abort")
if(choice == "Confirm" && can_control(usr, R) && !..())
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [!R.locked_down ? "locked down" : "released"] [key_name(R, R.client)][ADMIN_LOOKUPFLW(R)]!</span>")
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
if("stopbot")
if(allowed(usr))
var/mob/living/silicon/robot/R = locate(params["ref"]) in GLOB.silicon_mobs
if(can_control(usr, R) && !..())
message_admins("<span class='notice'>[ADMIN_LOOKUPFLW(usr)] [!R.locked_down ? "locked down" : "released"] [ADMIN_LOOKUPFLW(R)]!</span>")
log_game("[key_name(usr)] [!R.locked_down ? "locked down" : "released"] [key_name(R)]!")
R.SetLockdown(!R.locked_down)
to_chat(R, "[!R.locked_down ? "<span class='notice'>Your lockdown has been lifted!" : "<span class='alert'>You have been locked down!"]</span>")
if(R.connected_ai)
to_chat(R.connected_ai, "[!R.locked_down ? "<span class='notice'>NOTICE - Cyborg lockdown lifted" : "<span class='alert'>ALERT - Cyborg lockdown detected"]: <a href='?src=[REF(R.connected_ai)];track=[html_encode(R.name)]'>[R.name]</a></span><br>")
else
to_chat(usr, "<span class='danger'>Access Denied.</span>")
else if (href_list["magbot"])
var/mob/living/silicon/S = usr
if((istype(S) && S.hack_software) || IsAdminGhost(usr))
var/mob/living/silicon/robot/R = locate(href_list["magbot"]) in GLOB.silicon_mobs
if(istype(R) && !R.emagged && (R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R))
log_game("[key_name(usr)] emagged [key_name(R)] using robotic console!")
message_admins("[ADMIN_LOOKUPFLW(usr)] emagged cyborg [key_name_admin(R)] using robotic console!")
R.SetEmagged(1)
else if(href_list["convert"])
if(isAI(usr) && is_servant_of_ratvar(usr))
var/mob/living/silicon/robot/R = locate(href_list["convert"]) in GLOB.silicon_mobs
if(istype(R) && !is_servant_of_ratvar(R) && R.connected_ai == usr)
log_game("[key_name(usr)] converted [key_name(R)] using robotic console!")
message_admins("[ADMIN_LOOKUPFLW(usr)] converted cyborg [key_name_admin(R)] using robotic console!")
add_servant_of_ratvar(R)
else if (href_list["killdrone"])
if(src.allowed(usr))
var/mob/living/simple_animal/drone/D = locate(href_list["killdrone"]) in GLOB.mob_list
if(D.hacked)
to_chat(usr, "<span class='danger'>ERROR: [D] is not responding to external commands.</span>")
else
var/turf/T = get_turf(D)
message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(D)] at [ADMIN_VERBOSEJMP(T)]!")
log_game("[key_name(usr)] detonated [key_name(D)]!")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, 1, D)
s.start()
D.visible_message("<span class='danger'>\the [D] self destructs!</span>")
D.gib()
src.updateUsrDialog()
return
to_chat(usr, "<span class='danger'>Access Denied.</span>")
if("magbot")
var/mob/living/silicon/S = usr
if((istype(S) && S.hack_software) || IsAdminGhost(usr))
var/mob/living/silicon/robot/R = locate(params["ref"]) in GLOB.silicon_mobs
if(istype(R) && !R.emagged && (R.connected_ai == usr || IsAdminGhost(usr)) && !R.scrambledcodes && can_control(usr, R))
log_game("[key_name(usr)] emagged [key_name(R)] using robotic console!")
message_admins("[ADMIN_LOOKUPFLW(usr)] emagged cyborg [key_name_admin(R)] using robotic console!")
R.SetEmagged(TRUE)
if("killdrone")
if(allowed(usr))
var/mob/living/simple_animal/drone/D = locate(params["ref"]) in GLOB.mob_list
if(D.hacked)
to_chat(usr, "<span class='danger'>ERROR: [D] is not responding to external commands.</span>")
else
var/turf/T = get_turf(D)
message_admins("[ADMIN_LOOKUPFLW(usr)] detonated [key_name_admin(D)] at [ADMIN_VERBOSEJMP(T)]!")
log_game("[key_name(usr)] detonated [key_name(D)]!")
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
s.set_up(3, TRUE, D)
s.start()
D.visible_message("<span class='danger'>\the [D] self destructs!</span>")
D.gib()
@@ -20,7 +20,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "station_alert", name, 325, 500, master_ui, state)
ui = new(user, src, ui_key, "StationAlertConsole", name, 325, 500, master_ui, state)
ui.open()
/obj/machinery/computer/station_alert/ui_data(mob/user)
+1 -1
View File
@@ -38,7 +38,7 @@ obj/machinery/computer/teleporter/ui_interact(mob/user, ui_key = "main", datum/t
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "teleporter", name, ui_x, ui_y, master_ui, state)
ui = new(user, src, ui_key, "Teleporter", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/teleporter/ui_data(mob/user)
+48 -61
View File
@@ -15,6 +15,7 @@
var/precision_coeff
var/message_cooldown
var/breakout_time = 1200
var/obj/machinery/computer/scan_consolenew/linked_console = null
/obj/machinery/dna_scannernew/RefreshParts()
scan_level = 0
@@ -22,8 +23,8 @@
precision_coeff = 0
for(var/obj/item/stock_parts/scanning_module/P in component_parts)
scan_level += P.rating
for(var/obj/item/stock_parts/matter_bin/P in component_parts)
precision_coeff = P.rating
for(var/obj/item/stock_parts/matter_bin/M in component_parts)
precision_coeff = M.rating
for(var/obj/item/stock_parts/micro_laser/P in component_parts)
damage_coeff = P.rating
@@ -31,11 +32,8 @@
. = ..()
if(in_range(user, src) || isobserver(user))
. += "<span class='notice'>The status display reads: Radiation pulse accuracy increased by factor <b>[precision_coeff**2]</b>.<br>Radiation pulse damage decreased by factor <b>[damage_coeff**2]</b>.</span>"
if(scan_level >= 3)
. += "<span class='notice'>Scanner has been upgraded to support autoprocessing.<span>"
/obj/machinery/dna_scannernew/update_icon_state()
//no power or maintenance
if(stat & (NOPOWER|BROKEN))
icon_state = initial(icon_state)+ (state_open ? "_open" : "") + "_unpowered"
@@ -53,10 +51,6 @@
//running
icon_state = initial(icon_state)+ (state_open ? "_open" : "")
/obj/machinery/dna_scannernew/power_change()
..()
update_icon()
/obj/machinery/dna_scannernew/proc/toggle_open(mob/user)
if(panel_open)
to_chat(user, "<span class='notice'>Close the maintenance panel first.</span>")
@@ -80,7 +74,7 @@
user.last_special = world.time + CLICK_CD_BREAKOUT
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [DisplayTimeText(breakout_time)].)</span>", \
"<span class='italics'>You hear a metallic creaking from [src].</span>")
"<span class='hear'>You hear a metallic creaking from [src].</span>")
if(do_after(user,(breakout_time), target = src))
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open || !locked)
return
@@ -96,33 +90,28 @@
return C
return null
/obj/machinery/dna_scannernew/close_machine(atom/movable/target)
/obj/machinery/dna_scannernew/close_machine(mob/living/carbon/user)
if(!state_open)
return FALSE
..(target)
// search for ghosts, if the corpse is empty and the scanner is connected to a cloner
var/mob/living/mob_occupant = get_mob_or_brainmob(occupant)
if(istype(mob_occupant))
if(locate_computer(/obj/machinery/computer/cloning))
if(!mob_occupant.suiciding && !(HAS_TRAIT(mob_occupant, TRAIT_NOCLONE)) && !mob_occupant.hellbound)
mob_occupant.notify_ghost_cloning("Your corpse has been placed into a cloning scanner. Re-enter your corpse if you want to be cloned!", source = src)
..(user)
// DNA manipulators cannot operate on severed heads or brains
if(isliving(occupant))
var/obj/machinery/computer/scan_consolenew/console = locate_computer(/obj/machinery/computer/scan_consolenew)
if(console)
console.on_scanner_close()
if(iscarbon(occupant))
if(linked_console)
linked_console.on_scanner_close()
return TRUE
/obj/machinery/dna_scannernew/open_machine()
if(state_open || panel_open)
if(state_open)
return FALSE
..()
if(linked_console)
linked_console.on_scanner_open()
return TRUE
/obj/machinery/dna_scannernew/relaymove(mob/user as mob)
@@ -133,51 +122,49 @@
return
open_machine()
/obj/machinery/dna_scannernew/screwdriver_act(mob/living/user, obj/item/I)
. = TRUE
if(..())
return
if(occupant)
to_chat(user, "<span class='warning'>[src] is currently occupied!</span>")
return
if(state_open)
to_chat(user, "<span class='warning'>[src] must be closed to [panel_open ? "close" : "open"] its maintenance hatch!</span>")
return
if(default_deconstruction_screwdriver(user, icon_state, icon_state, I)) //sent icon_state is irrelevant...
update_icon() //..since we're updating the icon here, since the scanner can be unpowered when opened/closed
return
return FALSE
/obj/machinery/dna_scannernew/attackby(obj/item/I, mob/user, params)
/obj/machinery/dna_scannernew/wrench_act(mob/living/user, obj/item/I)
. = ..()
if(default_change_direction_wrench(user, I))
return TRUE
if(!occupant && default_deconstruction_screwdriver(user, icon_state, icon_state, I))//sent icon_state is irrelevant...
update_icon()//..since we're updating the icon here, since the scanner can be unpowered when opened/closed
return
/obj/machinery/dna_scannernew/crowbar_act(mob/living/user, obj/item/I)
. = ..()
if(default_pry_open(I))
return TRUE
if(default_deconstruction_crowbar(I))
return TRUE
return
/obj/machinery/dna_scannernew/default_pry_open(obj/item/I) //wew
. = !(state_open || panel_open || (flags_1 & NODECONSTRUCT_1)) && I.tool_behaviour == TOOL_CROWBAR
if(.)
I.play_tool_sound(src, 50)
visible_message("<span class='notice'>[usr] pries open [src].</span>", "<span class='notice'>You pry open [src].</span>")
open_machine()
if(default_deconstruction_crowbar(I))
return
return ..()
/obj/machinery/dna_scannernew/interact(mob/user)
toggle_open(user)
/obj/machinery/dna_scannernew/AltClick(mob/user)
. = ..()
if(!user.canUseTopic(src, !hasSiliconAccessInArea(user)))
return
interact(user)
return TRUE
/obj/machinery/dna_scannernew/MouseDrop_T(mob/target, mob/user)
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
var/mob/living/L = user
if(user.stat || (isliving(user) && (!(L.mobility_flags & MOBILITY_STAND) || !(L.mobility_flags & MOBILITY_UI))) || !Adjacent(user) || !user.Adjacent(target) || !iscarbon(target) || !user.IsAdvancedToolUser())
return
close_machine(target)
//Just for transferring between genetics machines.
/obj/item/disk/data
name = "DNA data disk"
icon_state = "datadisk0" //Gosh I hope syndies don't mistake them for the nuke disk.
var/list/genetic_makeup_buffer = list()
var/list/fields = list()
var/list/mutations = list()
var/max_mutations = 6
var/read_only = FALSE //Well,it's still a floppy disk
/obj/item/disk/data/Initialize()
. = ..()
icon_state = "datadisk[rand(0,6)]"
add_overlay("datadisk_gene")
/obj/item/disk/data/attack_self(mob/user)
read_only = !read_only
to_chat(user, "<span class='notice'>You flip the write-protect tab to [read_only ? "protected" : "unprotected"].</span>")
/obj/item/disk/data/examine(mob/user)
. = ..()
. += "The write-protect tab is set to [read_only ? "protected" : "unprotected"]."
+7 -3
View File
@@ -93,7 +93,7 @@
var/shuttledocked = 0
var/delayed_close_requested = FALSE // TRUE means the door will automatically close the next time it's opened.
var/air_tight = FALSE //TRUE means density will be set as soon as the door begins to close
air_tight = FALSE
var/prying_so_hard = FALSE
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
@@ -157,6 +157,10 @@
. = ..()
AddComponent(/datum/component/ntnet_interface)
/obj/machinery/door/airlock/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
if(id_tag)
id_tag = "[idnum][id_tag]"
/obj/machinery/door/airlock/proc/update_other_id()
for(var/obj/machinery/door/airlock/A in GLOB.airlocks)
if(A.closeOtherId == closeOtherId && A != src)
@@ -188,7 +192,7 @@
/obj/machinery/door/airlock/vv_edit_var(var_name)
. = ..()
switch (var_name)
if ("cyclelinkeddir")
if (NAMEOF(src, cyclelinkeddir))
cyclelinkairlock()
/obj/machinery/door/airlock/check_access_ntnet(datum/netdata/data)
@@ -1440,7 +1444,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "ai_airlock", name, 500, 390, master_ui, state)
ui = new(user, src, ui_key, "AiAirlock", name, 500, 390, master_ui, state)
ui.open()
return TRUE
@@ -2,10 +2,14 @@
name = "airlock electronics"
req_access = list(ACCESS_MAINT_TUNNELS)
custom_price = PRICE_CHEAP
/// A list of all granted accesses
var/list/accesses = list()
/// If the airlock should require ALL or only ONE of the listed accesses
var/one_access = 0
var/unres_sides = 0 //unrestricted sides, or sides of the airlock that will open regardless of access
/// Unrestricted sides, or sides of the airlock that will open regardless of access
var/unres_sides = 0
/// A holder of the electronics, in case of them working as an integrated part
var/holder
/obj/item/electronics/airlock/examine(mob/user)
. = ..()
@@ -13,31 +17,37 @@
/obj/item/electronics/airlock/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
SStgui.try_update_ui(user, src, ui_key, ui, force_open)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "airlock_electronics", name, 420, 485, master_ui, state)
ui = new(user, src, ui_key, "AirlockElectronics", name, 420, 485, master_ui, state)
ui.open()
/obj/item/electronics/airlock/ui_static_data(mob/user)
var/list/data = list()
var/list/regions = list()
for(var/i in 1 to 7)
var/list/accesses = list()
for(var/access in get_region_accesses(i))
if (get_access_desc(access))
accesses += list(list(
"desc" = replacetext(get_access_desc(access), "&nbsp", " "),
"ref" = access,
))
regions += list(list(
"name" = get_region_accesses_name(i),
"regid" = i,
"accesses" = accesses
))
data["regions"] = regions
return data
/obj/item/electronics/airlock/ui_data()
var/list/data = list()
var/list/regions = list()
for(var/i in 1 to 7)
var/list/region = list()
var/list/accesses = list()
for(var/j in get_region_accesses(i))
var/list/access = list()
access["name"] = get_access_desc(j)
access["id"] = j
access["req"] = (j in src.accesses)
accesses[++accesses.len] = access
region["name"] = get_region_accesses_name(i)
region["accesses"] = accesses
regions[++regions.len] = region
data["regions"] = regions
data["accesses"] = accesses
data["oneAccess"] = one_access
data["unres_direction"] = unres_sides
return data
/obj/item/electronics/airlock/ui_act(action, params)
@@ -48,12 +58,12 @@
accesses = list()
one_access = 0
. = TRUE
if("one_access")
one_access = !one_access
. = TRUE
if("grant_all")
accesses = get_all_accesses()
. = TRUE
if("one_access")
one_access = !one_access
. = TRUE
if("set")
var/access = text2num(params["access"])
if (!(access in accesses))
@@ -65,3 +75,20 @@
var/unres_direction = text2num(params["unres_direction"])
unres_sides ^= unres_direction //XOR, toggles only the bit that was clicked
. = TRUE
if("grant_region")
var/region = text2num(params["region"])
if(isnull(region))
return
accesses |= get_region_accesses(region)
. = TRUE
if("deny_region")
var/region = text2num(params["region"])
if(isnull(region))
return
accesses -= get_region_accesses(region)
. = TRUE
/obj/item/electronics/airlock/ui_host()
if(holder)
return holder
return src
+1 -1
View File
@@ -144,7 +144,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "brig_timer", name, 300, 138, master_ui, state)
ui = new(user, src, ui_key, "BrigTimer", name, 300, 138, master_ui, state)
ui.open()
//icon update function
+36 -7
View File
@@ -17,6 +17,7 @@
interaction_flags_atom = INTERACT_ATOM_UI_INTERACT
var/secondsElectrified = 0
var/air_tight = FALSE //TRUE means density will be set as soon as the door begins to close
var/shockedby
var/visible = TRUE // To explain: Whether the door can block line of sight when closed or not.
var/operating = FALSE
@@ -161,7 +162,7 @@
open()
else
close()
return
return TRUE
if(density)
do_animate("deny")
@@ -181,11 +182,36 @@
/obj/machinery/door/proc/try_to_crowbar(obj/item/I, mob/user)
return
/obj/machinery/door/proc/is_holding_pressure()
var/turf/open/T = loc
if(!T)
return FALSE
if(!density)
return FALSE
// alrighty now we check for how much pressure we're holding back
var/min_moles = T.air.total_moles()
var/max_moles = min_moles
// okay this is a bit hacky. First, we set density to 0 and recalculate our adjacent turfs
density = FALSE
T.ImmediateCalculateAdjacentTurfs()
// then we use those adjacent turfs to figure out what the difference between the lowest and highest pressures we'd be holding is
for(var/turf/open/T2 in T.atmos_adjacent_turfs)
if((flags_1 & ON_BORDER_1) && get_dir(src, T2) != dir)
continue
var/moles = T2.air.total_moles()
if(moles < min_moles)
min_moles = moles
if(moles > max_moles)
max_moles = moles
density = TRUE
T.ImmediateCalculateAdjacentTurfs() // alright lets put it back
return max_moles - min_moles > 20
/obj/machinery/door/attackby(obj/item/I, mob/user, params)
if(user.a_intent != INTENT_HARM && (istype(I, /obj/item/crowbar) || istype(I, /obj/item/fireaxe)))
if(user.a_intent != INTENT_HARM && (I.tool_behaviour == TOOL_CROWBAR || istype(I, /obj/item/fireaxe)))
try_to_crowbar(I, user)
return 1
else if(istype(I, /obj/item/weldingtool))
else if(I.tool_behaviour == TOOL_WELDER)
try_to_weld(I, user)
return 1
else if(!(I.item_flags & NOBLUDGEON) && user.a_intent != INTENT_HARM)
@@ -223,13 +249,13 @@
if(prob(20/severity) && (istype(src, /obj/machinery/door/airlock) || istype(src, /obj/machinery/door/window)) )
INVOKE_ASYNC(src, .proc/open)
if(prob(severity*10 - 20))
if(secondsElectrified == 0)
secondsElectrified = -1
if(secondsElectrified == MACHINE_NOT_ELECTRIFIED)
secondsElectrified = MACHINE_ELECTRIFIED_PERMANENT
LAZYADD(shockedby, "\[[TIME_STAMP("hh:mm:ss", FALSE)]\]EM Pulse")
addtimer(CALLBACK(src, .proc/unelectrify), 300)
/obj/machinery/door/proc/unelectrify()
secondsElectrified = 0
secondsElectrified = MACHINE_NOT_ELECTRIFIED
/obj/machinery/door/update_icon_state()
if(density)
@@ -289,8 +315,11 @@
return
operating = TRUE
do_animate("closing")
layer = closingLayer
if(air_tight)
density = TRUE
sleep(5)
density = TRUE
sleep(5)
@@ -302,7 +331,7 @@
update_freelook_sight()
if(safe)
CheckForMobs()
else
else if(!(flags_1 & ON_BORDER_1))
crush()
return 1
+170 -22
View File
@@ -23,6 +23,8 @@
assemblytype = /obj/structure/firelock_frame
armor = list("melee" = 30, "bullet" = 30, "laser" = 20, "energy" = 20, "bomb" = 10, "bio" = 100, "rad" = 100, "fire" = 95, "acid" = 70)
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
air_tight = TRUE
var/emergency_close_timer = 0
var/nextstate = null
var/boltslocked = TRUE
var/list/affecting_areas
@@ -68,10 +70,14 @@
return ..()
/obj/machinery/door/firedoor/Bumped(atom/movable/AM)
if(panel_open || operating)
if(panel_open || operating || welded)
return
if(!density)
return ..()
if(ismob(AM))
var/mob/user = AM
if(density && !welded && !operating && !(stat & NOPOWER) && (!density || allow_hand_open(user)))
add_fingerprint(user)
open()
return TRUE
return FALSE
@@ -86,6 +92,15 @@
. = ..()
if(.)
return
if(!welded && !operating && !(stat & NOPOWER) && (!density || allow_hand_open(user)))
add_fingerprint(user)
if(density)
emergency_close_timer = world.time + 30 // prevent it from instaclosing again if in space
open()
else
close()
return TRUE
if(operating || !density)
return
user.changeNext_move(CLICK_CD_MELEE)
@@ -100,7 +115,7 @@
return
if(welded)
if(istype(C, /obj/item/wrench))
if(C.tool_behaviour == TOOL_WRENCH)
if(boltslocked)
to_chat(user, "<span class='notice'>There are screws locking the bolts in place!</span>")
return
@@ -114,7 +129,7 @@
"<span class='notice'>You undo [src]'s floor bolts.</span>")
deconstruct(TRUE)
return
if(istype(C, /obj/item/screwdriver))
if(C.tool_behaviour == TOOL_SCREWDRIVER)
user.visible_message("<span class='notice'>[user] [boltslocked ? "unlocks" : "locks"] [src]'s bolts.</span>", \
"<span class='notice'>You [boltslocked ? "unlock" : "lock"] [src]'s floor bolts.</span>")
C.play_tool_sound(src)
@@ -140,10 +155,27 @@
return
if(density)
if(is_holding_pressure())
// tell the user that this is a bad idea, and have a do_after as well
to_chat(user, "<span class='warning'>As you begin crowbarring \the [src] a gush of air blows in your face... maybe you should reconsider?</span>")
if(!do_after(user, 15, TRUE, src)) // give them a few seconds to reconsider their decision.
return
log_game("[key_name_admin(user)] has opened a firelock with a pressure difference at [AREACOORD(loc)]") // there bibby I made it logged just for you. Enjoy.
// since we have high-pressure-ness, close all other firedoors on the tile
whack_a_mole()
if(welded || operating || !density)
return // in case things changed during our do_after
emergency_close_timer = world.time + 60 // prevent it from instaclosing again if in space
open()
else
close()
/obj/machinery/door/firedoor/proc/allow_hand_open(mob/user)
var/area/A = get_area(src)
if(A && A.fire)
return FALSE
return !is_holding_pressure()
/obj/machinery/door/firedoor/attack_ai(mob/user)
add_fingerprint(user)
if(welded || operating || stat & NOPOWER)
@@ -171,20 +203,16 @@
if("closing")
flick("door_closing", src)
/obj/machinery/door/firedoor/update_icon_state()
/obj/machinery/door/firedoor/update_icon()
cut_overlays()
if(density)
icon_state = "door_closed"
if(welded)
add_overlay("welded")
else
icon_state = "door_open"
/obj/machinery/door/firedoor/update_overlays()
. = ..()
if(!welded)
return
if(density)
. += "welded"
else
. += "welded_open"
if(welded)
add_overlay("welded_open")
/obj/machinery/door/firedoor/open()
. = ..()
@@ -194,6 +222,61 @@
. = ..()
latetoggle()
/obj/machinery/door/firedoor/proc/whack_a_mole(reconsider_immediately = FALSE)
set waitfor = 0
for(var/cdir in GLOB.cardinals)
if((flags_1 & ON_BORDER_1) && cdir != dir)
continue
whack_a_mole_part(get_step(src, cdir), reconsider_immediately)
if(flags_1 & ON_BORDER_1)
whack_a_mole_part(get_turf(src), reconsider_immediately)
/obj/machinery/door/firedoor/proc/whack_a_mole_part(turf/start_point, reconsider_immediately)
set waitfor = 0
var/list/doors_to_close = list()
var/list/turfs = list()
turfs[start_point] = 1
for(var/i = 1; (i <= turfs.len && i <= 11); i++) // check up to 11 turfs.
var/turf/open/T = turfs[i]
if(istype(T, /turf/open/space))
return -1
for(var/T2 in T.atmos_adjacent_turfs)
if(turfs[T2])
continue
var/is_cut_by_unopen_door = FALSE
for(var/obj/machinery/door/firedoor/FD in T2)
if((FD.flags_1 & ON_BORDER_1) && get_dir(T2, T) != FD.dir)
continue
if(FD.operating || FD == src || FD.welded || FD.density)
continue
doors_to_close += FD
is_cut_by_unopen_door = TRUE
for(var/obj/machinery/door/firedoor/FD in T)
if((FD.flags_1 & ON_BORDER_1) && get_dir(T, T2) != FD.dir)
continue
if(FD.operating || FD == src || FD.welded || FD.density)
continue
doors_to_close += FD
is_cut_by_unopen_door= TRUE
if(!is_cut_by_unopen_door)
turfs[T2] = 1
if(turfs.len > 10)
return // too big, don't bother
for(var/obj/machinery/door/firedoor/FD in doors_to_close)
FD.emergency_pressure_stop(FALSE)
if(reconsider_immediately)
var/turf/open/T = FD.loc
if(istype(T))
T.ImmediateCalculateAdjacentTurfs()
/obj/machinery/door/firedoor/proc/emergency_pressure_stop(consider_timer = TRUE)
set waitfor = 0
if(density || operating || welded)
return
if(world.time >= emergency_close_timer || !consider_timer)
close()
/obj/machinery/door/firedoor/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
var/obj/structure/firelock_frame/F = new assemblytype(get_turf(src))
@@ -227,6 +310,59 @@
opacity = TRUE
density = TRUE
/obj/machinery/door/firedoor/border_only/close()
if(density)
return TRUE
if(operating || welded)
return
var/turf/T1 = get_turf(src)
var/turf/T2 = get_step(T1, dir)
for(var/mob/living/M in T1)
if(M.stat == CONSCIOUS && M.pulling && M.pulling.loc == T2 && !M.pulling.anchored && M.pulling.move_resist <= M.move_force)
var/mob/living/M2 = M.pulling
if(!istype(M2) || !M2.buckled || !M2.buckled.buckle_prevents_pull)
to_chat(M, "<span class='notice'>You pull [M.pulling] through [src] right as it closes</span>")
M.pulling.forceMove(T1)
M.start_pulling(M2)
for(var/mob/living/M in T2)
if(M.stat == CONSCIOUS && M.pulling && M.pulling.loc == T1 && !M.pulling.anchored && M.pulling.move_resist <= M.move_force)
var/mob/living/M2 = M.pulling
if(!istype(M2) || !M2.buckled || !M2.buckled.buckle_prevents_pull)
to_chat(M, "<span class='notice'>You pull [M.pulling] through [src] right as it closes</span>")
M.pulling.forceMove(T2)
M.start_pulling(M2)
. = ..()
/obj/machinery/door/firedoor/border_only/allow_hand_open(mob/user)
var/area/A = get_area(src)
if((!A || !A.fire) && !is_holding_pressure())
return TRUE
whack_a_mole(TRUE) // WOOP WOOP SIDE EFFECTS
var/turf/T = loc
var/turf/T2 = get_step(T, dir)
if(!T || !T2)
return
var/status1 = check_door_side(T)
var/status2 = check_door_side(T2)
if((status1 == 1 && status2 == -1) || (status1 == -1 && status2 == 1))
to_chat(user, "<span class='warning'>Access denied. Try closing another firedoor to minimize decompression, or using a crowbar.</span>")
return FALSE
return TRUE
/obj/machinery/door/firedoor/border_only/proc/check_door_side(turf/open/start_point)
var/list/turfs = list()
turfs[start_point] = 1
for(var/i = 1; (i <= turfs.len && i <= 11); i++) // check up to 11 turfs.
var/turf/open/T = turfs[i]
if(istype(T, /turf/open/space))
return -1
for(var/T2 in T.atmos_adjacent_turfs)
turfs[T2] = 1
if(turfs.len <= 10)
return 0 // not big enough to matter
return start_point.air.return_pressure() < 20 ? -1 : 1
/obj/machinery/door/firedoor/border_only/CanPass(atom/movable/mover, turf/target)
if(istype(mover) && (mover.pass_flags & PASSGLASS))
return TRUE
@@ -257,6 +393,18 @@
assemblytype = /obj/structure/firelock_frame/heavy
max_integrity = 550
/obj/machinery/door/firedoor/window
name = "window shutter"
icon = 'icons/obj/doors/doorfirewindow.dmi'
desc = "A second window that slides in when the original window is broken, designed to protect against hull breaches. Truly a work of genius by NT engineers."
glass = TRUE
explosion_block = 0
max_integrity = 50
resistance_flags = 0 // not fireproof
heat_proof = FALSE
/obj/machinery/door/firedoor/window/allow_hand_open()
return TRUE
/obj/item/electronics/firelock
name = "firelock circuitry"
@@ -294,7 +442,7 @@
/obj/structure/firelock_frame/attackby(obj/item/C, mob/user)
switch(constructionStep)
if(CONSTRUCTION_PANEL_OPEN)
if(istype(C, /obj/item/crowbar))
if(C.tool_behaviour == TOOL_CROWBAR)
C.play_tool_sound(src)
user.visible_message("<span class='notice'>[user] starts prying something out from [src]...</span>", \
"<span class='notice'>You begin prying out the wire cover...</span>")
@@ -308,7 +456,7 @@
constructionStep = CONSTRUCTION_WIRES_EXPOSED
update_icon()
return
if(istype(C, /obj/item/wrench))
if(C.tool_behaviour == TOOL_WRENCH)
if(locate(/obj/machinery/door/firedoor) in get_turf(src))
to_chat(user, "<span class='warning'>There's already a firelock there.</span>")
return
@@ -350,7 +498,7 @@
return
if(CONSTRUCTION_WIRES_EXPOSED)
if(istype(C, /obj/item/wirecutters))
if(C.tool_behaviour == TOOL_WIRECUTTER)
C.play_tool_sound(src)
user.visible_message("<span class='notice'>[user] starts cutting the wires from [src]...</span>", \
"<span class='notice'>You begin removing [src]'s wires...</span>")
@@ -364,7 +512,7 @@
constructionStep = CONSTRUCTION_GUTTED
update_icon()
return
if(istype(C, /obj/item/crowbar))
if(C.tool_behaviour == TOOL_CROWBAR)
C.play_tool_sound(src)
user.visible_message("<span class='notice'>[user] starts prying a metal plate into [src]...</span>", \
"<span class='notice'>You begin prying the cover plate back onto [src]...</span>")
@@ -379,7 +527,7 @@
update_icon()
return
if(CONSTRUCTION_GUTTED)
if(istype(C, /obj/item/crowbar))
if(C.tool_behaviour == TOOL_CROWBAR)
user.visible_message("<span class='notice'>[user] begins removing the circuit board from [src]...</span>", \
"<span class='notice'>You begin prying out the circuit board from [src]...</span>")
if(!C.use_tool(src, user, 50, volume=50))
@@ -401,7 +549,7 @@
"<span class='notice'>You begin adding wires to [src]...</span>")
playsound(get_turf(src), 'sound/items/deconstruct.ogg', 50, 1)
if(do_after(user, 60, target = src))
if(constructionStep != CONSTRUCTION_GUTTED || !B.use_tool(src, user, 0, 5))
if(constructionStep != CONSTRUCTION_GUTTED || B.get_amount() < 5 || !B)
return
user.visible_message("<span class='notice'>[user] adds wires to [src].</span>", \
"<span class='notice'>You wire [src].</span>")
@@ -410,7 +558,7 @@
update_icon()
return
if(CONSTRUCTION_NOCIRCUIT)
if(istype(C, /obj/item/weldingtool))
if(C.tool_behaviour == TOOL_WELDER)
if(!C.tool_start_check(user, amount=1))
return
user.visible_message("<span class='notice'>[user] begins cutting apart [src]'s frame...</span>", \
+3
View File
@@ -16,6 +16,9 @@
damage_deflection = 70
poddoor = TRUE
/obj/machinery/door/poddoor/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
id = "[idnum][id]"
/obj/machinery/door/poddoor/preopen
icon_state = "open"
density = FALSE
+3
View File
@@ -36,6 +36,9 @@
else
bulb = new(src)
/obj/machinery/flasher/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
id = "[idnum][id]"
/obj/machinery/flasher/Destroy()
QDEL_NULL(bulb)
return ..()
+1 -1
View File
@@ -31,7 +31,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "gulag_item_reclaimer", name, 300, 400, master_ui, state)
ui = new(user, src, ui_key, "GulagItemReclaimer", name, 300, 400, master_ui, state)
ui.open()
/obj/machinery/gulag_item_reclaimer/ui_data(mob/user)
+1 -1
View File
@@ -37,7 +37,7 @@
/obj/machinery/hypnochair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "hypnochair", name, ui_x, ui_y, master_ui, state)
ui = new(user, src, ui_key, "HypnoChair", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/hypnochair/ui_data()
+3
View File
@@ -53,6 +53,9 @@
else
icon_state = "igniter0"
/obj/machinery/igniter/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
id = "[idnum][id]"
// Wall mounted remote-control igniter.
/obj/machinery/sparker
+1 -2
View File
@@ -285,8 +285,7 @@
/obj/item/launchpad_remote/ui_interact(mob/user, ui_key = "launchpad_remote", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "launchpad_remote", "Briefcase Launchpad Remote", 300, 240, master_ui, state) //width, height
ui.set_style("syndicate")
ui = new(user, src, ui_key, "LaunchpadRemote", "Briefcase Launchpad Remote", 300, 240, master_ui, state) //width, height
ui.open()
ui.set_autoupdate(TRUE)
+2
View File
@@ -11,6 +11,8 @@
var/id = 1
var/drive_range = 50 //this is mostly irrelevant since current mass drivers throw into space, but you could make a lower-range mass driver for interstation transport or something I guess.
/obj/machinery/mass_driver/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
id = "[idnum][id]"
/obj/machinery/mass_driver/proc/drive(amount)
if(stat & (BROKEN|NOPOWER))
+1 -1
View File
@@ -225,6 +225,6 @@
/obj/item/paper/guides/recycler
name = "paper - 'garbage duty instructions'"
info = "<h2>New Assignment</h2> You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.<br><br>There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!"
info = "_New Assignment_\n\n You have been assigned to collect garbage from trash bins, located around the station. The crewmembers will put their trash into it and you will collect the said trash.<br><br>There is a recycling machine near your closet, inside maintenance; use it to recycle the trash for a small chance to get useful minerals. Then deliver these minerals to cargo or engineering. You are our last hope for a clean station, do not screw this up!"
#undef SAFETY_COOLDOWN
@@ -130,7 +130,7 @@
var/deltaTemperature = req_power / heat_cap
if(deltaTemperature < 0)
return
env.temperature += deltaTemperature
env.set_temperature(env.return_temperature(),deltaTemperature)
air_update_turf()
/obj/machinery/shuttle/engine/default_change_direction_wrench(mob/user, obj/item/I)
@@ -89,8 +89,8 @@
var/datum/gas_mixture/air_contents = airs[1]
if(!air_contents)
return
air_contents.volume = gas_capacity
air_contents.temperature = T20C
air_contents.set_volume(gas_capacity)
air_contents.set_temperature(T20C)
/obj/machinery/atmospherics/components/unary/shuttle/heater/proc/hasFuel(var/required)
var/datum/gas_mixture/air_contents = airs[1]
+7 -7
View File
@@ -83,9 +83,9 @@
var/datum/gas_mixture/env = L.return_air()
var/newMode = HEATER_MODE_STANDBY
if(setMode != HEATER_MODE_COOL && env.temperature < targetTemperature - temperatureTolerance)
if(setMode != HEATER_MODE_COOL && env.return_temperature() < targetTemperature - temperatureTolerance)
newMode = HEATER_MODE_HEAT
else if(setMode != HEATER_MODE_HEAT && env.temperature > targetTemperature + temperatureTolerance)
else if(setMode != HEATER_MODE_HEAT && env.return_temperature() > targetTemperature + temperatureTolerance)
newMode = HEATER_MODE_COOL
if(mode != newMode)
@@ -96,7 +96,7 @@
return
var/heat_capacity = env.heat_capacity()
var/requiredPower = abs(env.temperature - targetTemperature) * heat_capacity
var/requiredPower = abs(env.return_temperature() - targetTemperature) * heat_capacity
requiredPower = min(requiredPower, heatingPower)
if(requiredPower < 1)
@@ -106,7 +106,7 @@
if(mode == HEATER_MODE_COOL)
deltaTemperature *= -1
if(deltaTemperature)
env.temperature += deltaTemperature
env.set_temperature(env.return_temperature() + deltaTemperature)
air_update_turf()
cell.use(requiredPower / efficiency)
else
@@ -175,7 +175,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "space_heater", name, 400, 305, master_ui, state)
ui = new(user, src, ui_key, "SpaceHeater", name, 400, 305, master_ui, state)
ui.open()
/obj/machinery/space_heater/ui_data()
@@ -194,9 +194,9 @@
var/curTemp
if(istype(L))
var/datum/gas_mixture/env = L.return_air()
curTemp = env.temperature
curTemp = env.return_temperature()
else if(isturf(L))
curTemp = L.temperature
curTemp = L.return_temperature()
if(isnull(curTemp))
data["currentTemp"] = "N/A"
else
+1 -1
View File
@@ -287,7 +287,7 @@
if(!.)
return
switch(var_name)
if("shuttle_id")
if(NAMEOF(src, shuttle_id))
update()
/obj/machinery/status_display/shuttle/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override)
+1 -1
View File
@@ -383,7 +383,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "suit_storage_unit", name, 400, 305, master_ui, state)
ui = new(user, src, ui_key, "SuitStorageUnit", name, 400, 305, master_ui, state)
ui.open()
/obj/machinery/suit_storage_unit/ui_data()
@@ -21,7 +21,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "tcommsserver", "Telecomms Server Monitor", 575, 400, master_ui, state)
ui = new(user, src, ui_key, "TelecommsLogBrowser", "Telecomms Server Monitor", 575, 400, master_ui, state)
ui.open()
/obj/machinery/computer/telecomms/server/ui_data(mob/user)
@@ -41,7 +41,7 @@
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "telepdalog", name, 727, 510, master_ui, state)
ui = new(user, src, ui_key, "TelecommsPDALog", name, 727, 510, master_ui, state)
ui.open()
/obj/machinery/computer/message_monitor/ui_static_data(mob/user)
@@ -389,7 +389,6 @@
/obj/item/paper/monitorkey/proc/print(obj/machinery/telecomms/message_server/server)
info = "<center><h2>Daily Key Reset</h2></center><br>The new message monitor key is '[server.decryptkey]'.<br>Please keep this a secret and away from the clown.<br>If necessary, change the password to a more secure one."
info_links = info
add_overlay("paper_words")
/obj/item/paper/monitorkey/LateInitialize()
@@ -22,7 +22,7 @@
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "telemonitor", name, 575, 400, master_ui, state)
ui = new(user, src, ui_key, "TelecommsMonitor", name, 575, 400, master_ui, state)
ui.open()
/obj/machinery/computer/telecomms/monitor/ui_data(mob/user)
@@ -36,7 +36,7 @@
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "teleinteract", "[name] Access", 520, 500, master_ui, state)
ui = new(user, src, ui_key, "TelecommsInteraction", "[name] Access", 520, 500, master_ui, state)
ui.open()
/obj/machinery/telecomms/ui_data(mob/user)
+2 -2
View File
@@ -21,7 +21,7 @@
var/cell_charge = get_charge()
var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None"
var/tank_temperature = internal_tank ? int_tank_air.temperature : "Unknown"
var/tank_temperature = internal_tank ? int_tank_air.return_temperature() : "Unknown"
var/cabin_pressure = round(return_pressure(),0.01)
var/output = {"[report_internal_damage()]
[integrity<30?"<font color='red'><b>DAMAGE LEVEL CRITICAL</b></font><br>":null]
@@ -155,4 +155,4 @@
var/color=""
for (var/i=0;i<6;i++)
color = color+pick(colors)
return color
return color
@@ -422,13 +422,13 @@
return
var/datum/gas_mixture/GM = new
if(prob(10))
GM.gases[/datum/gas/plasma] += 100
GM.temperature = 1500+T0C //should be enough to start a fire
GM.adjust_moles(/datum/gas/plasma,100)
GM.set_temperature(1500+T0C) //should be enough to start a fire
T.visible_message("[src] suddenly disgorges a cloud of heated plasma.")
qdel(src)
else
GM.gases[/datum/gas/plasma] += 5
GM.temperature = istype(T) ? T.air.return_temperature() : T20C
GM.adjust_moles(/datum/gas/plasma,5)
GM.set_temperature(istype(T) ? T.air.return_temperature() : T20C)
T.visible_message("[src] suddenly disgorges a cloud of plasma.")
T.assume_air(GM)
return
+1 -1
View File
@@ -84,7 +84,7 @@
/obj/machinery/computer/mech_bay_power_console/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "mech_bay_power_console", "Mech Bay Power Control Console", 400, 200, master_ui, state)
ui = new(user, src, ui_key, "MechBayPowerConsole", "Mech Bay Power Control Console", 400, 200, master_ui, state)
ui.open()
/obj/machinery/computer/mech_bay_power_console/ui_act(action, params)
+8 -8
View File
@@ -247,10 +247,10 @@
/obj/mecha/proc/add_cabin()
cabin_air = new
cabin_air.temperature = T20C
cabin_air.volume = 200
cabin_air.gases[/datum/gas/oxygen] = O2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
cabin_air.gases[/datum/gas/nitrogen] = N2STANDARD*cabin_air.volume/(R_IDEAL_GAS_EQUATION*cabin_air.temperature)
cabin_air.set_temperature(T20C)
cabin_air.set_volume(200)
cabin_air.set_moles(/datum/gas/oxygen,O2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
cabin_air.set_moles(/datum/gas/nitrogen,N2STANDARD*cabin_air.return_volume()/(R_IDEAL_GAS_EQUATION*cabin_air.return_temperature()))
return cabin_air
/obj/mecha/proc/add_radio()
@@ -302,9 +302,9 @@
if(int_tank_air.return_pressure() > internal_tank.maximum_pressure && !(internal_damage & MECHA_INT_TANK_BREACH))
setInternalDamage(MECHA_INT_TANK_BREACH)
if(int_tank_air && int_tank_air.return_volume() > 0) //heat the air_contents
int_tank_air.temperature = min(6000+T0C, int_tank_air.temperature+rand(10,15))
int_tank_air.set_temperature(min(6000+T0C, int_tank_air.return_temperature()+rand(10,15)))
if(cabin_air && cabin_air.return_volume()>0)
cabin_air.temperature = min(6000+T0C, cabin_air.return_temperature()+rand(10,15))
cabin_air.set_temperature(min(6000+T0C, cabin_air.return_temperature()+rand(10,15)))
if(cabin_air.return_temperature() > max_temperature/2)
take_damage(4/round(max_temperature/cabin_air.return_temperature(),0.1), BURN, 0, 0)
@@ -329,8 +329,8 @@
if(internal_temp_regulation)
if(cabin_air && cabin_air.return_volume() > 0)
var/delta = cabin_air.temperature - T20C
cabin_air.temperature -= max(-10, min(10, round(delta/4,0.1)))
var/delta = cabin_air.return_temperature() - T20C
cabin_air.set_temperature(cabin_air.return_temperature() - max(-10, min(10, round(delta/4,0.1))))
if(internal_tank)
var/datum/gas_mixture/tank_air = internal_tank.return_air()
+105 -87
View File
@@ -5,62 +5,74 @@
icon_keyboard = "tech_key"
req_access = list(ACCESS_ROBOTICS)
circuit = /obj/item/circuitboard/computer/mecha_control
var/list/located = list()
var/screen = 0
var/stored_data
ui_x = 500
ui_y = 500
/obj/machinery/computer/mecha/ui_interact(mob/user)
. = ..()
var/dat = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>[src.name]</title><style>h3 {margin: 0px; padding: 0px;}</style></head><body>"
if(screen == 0)
dat += "<h3>Tracking beacons data</h3>"
var/list/trackerlist = list()
for(var/obj/mecha/MC in GLOB.mechas_list)
trackerlist += MC.trackers
for(var/obj/item/mecha_parts/mecha_tracking/TR in trackerlist)
var/answer = TR.get_mecha_info()
if(answer)
dat += {"<hr>[answer]<br/>
<a href='?src=[REF(src)];send_message=[REF(TR)]'>Send message</a><br/>
<a href='?src=[REF(src)];get_log=[REF(TR)]'>Show exosuit log</a><br/>
[TR.recharging?"Recharging EMP Pulse...<br>":"<a style='color: #f00;' href='?src=[REF(src)];shock=[REF(TR)]'>(EMP Pulse)</a><br>"]"}
/obj/machinery/computer/mecha/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.default_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "ExosuitControlConsole", name, ui_x, ui_y, master_ui, state)
ui.open()
if(screen==1)
dat += "<h3>Log contents</h3>"
dat += "<a href='?src=[REF(src)];return=1'>Return</a><hr>"
dat += "[stored_data]"
/obj/machinery/computer/mecha/ui_data(mob/user)
var/list/data = list()
dat += "<A href='?src=[REF(src)];refresh=1'>(Refresh)</A><BR>"
dat += "</body></html>"
var/list/trackerlist = list()
for(var/obj/mecha/MC in GLOB.mechas_list)
trackerlist += MC.trackers
user << browse(dat, "window=computer;size=400x500")
onclose(user, "computer")
data["mechs"] = list()
for(var/obj/item/mecha_parts/mecha_tracking/MT in trackerlist)
if(!MT.chassis)
continue
var/obj/mecha/M = MT.chassis
var/list/mech_data = list(
name = M.name,
integrity = round((M.obj_integrity / M.max_integrity) * 100),
charge = M.cell ? round(M.cell.percent()) : null,
airtank = M.internal_tank ? M.return_pressure() : null,
pilot = M.occupant,
location = get_area_name(M, TRUE),
active_equipment = M.selected,
emp_recharging = MT.recharging,
tracker_ref = REF(MT)
)
if(istype(M, /obj/mecha/working/ripley))
var/obj/mecha/working/ripley/RM = M
mech_data += list(
cargo_space = round((RM.cargo.len / RM.cargo_capacity) * 100)
)
/obj/machinery/computer/mecha/Topic(href, href_list)
data["mechs"] += list(mech_data)
return data
/obj/machinery/computer/mecha/ui_act(action, params)
if(..())
return
if(href_list["send_message"])
var/obj/item/mecha_parts/mecha_tracking/MT = locate(href_list["send_message"])
if (!istype(MT))
return
var/message = stripped_input(usr,"Input message","Transmit message")
var/obj/mecha/M = MT.in_mecha()
if(trim(message) && M)
M.occupant_message(message)
return
if(href_list["shock"])
var/obj/item/mecha_parts/mecha_tracking/MT = locate(href_list["shock"])
if (istype(MT))
MT.shock()
if(href_list["get_log"])
var/obj/item/mecha_parts/mecha_tracking/MT = locate(href_list["get_log"])
if(istype(MT))
stored_data = MT.get_mecha_log()
screen = 1
if(href_list["return"])
screen = 0
updateUsrDialog()
return
switch(action)
if("send_message")
var/obj/item/mecha_parts/mecha_tracking/MT = locate(params["tracker_ref"])
if(!istype(MT))
return
var/message = stripped_input(usr, "Input message", "Transmit message")
var/obj/mecha/M = MT.chassis
if(trim(message) && M)
M.occupant_message(message)
to_chat(usr, "<span class='notice'>Message sent.</span>")
. = TRUE
if("shock")
var/obj/item/mecha_parts/mecha_tracking/MT = locate(params["tracker_ref"])
if(!istype(MT))
return
var/obj/mecha/M = MT.chassis
if(M)
MT.shock()
log_game("[key_name(usr)] has activated remote EMP on exosuit [M], located at [loc_name(M)], which is currently [M.occupant? "being piloted by [key_name(M.occupant)]." : "without a pilot."] ")
message_admins("[key_name_admin(usr)][ADMIN_FLW(usr)] has activated remote EMP on exosuit [M][ADMIN_JMP(M)], which is currently [M.occupant ? "being piloted by [key_name_admin(M.occupant)][ADMIN_FLW(M.occupant)]." : "without a pilot."] ")
. = TRUE
/obj/item/mecha_parts/mecha_tracking
name = "exosuit tracking beacon"
@@ -68,24 +80,31 @@
icon = 'icons/obj/device.dmi'
icon_state = "motion2"
w_class = WEIGHT_CLASS_SMALL
var/ai_beacon = FALSE //If this beacon allows for AI control. Exists to avoid using istype() on checking.
var/recharging = 0
/// If this beacon allows for AI control. Exists to avoid using istype() on checking
var/ai_beacon = FALSE
/// Cooldown variable for EMP pulsing
var/recharging = FALSE
/// The Mecha that this tracking beacon is attached to
var/obj/mecha/chassis
/**
* Returns a html formatted string describing attached mech status
*/
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_info()
if(!in_mecha())
return 0
var/obj/mecha/M = src.loc
var/cell_charge = M.get_charge()
var/answer = {"<b>Name:</b> [M.name]
<b>Integrity:</b> [M.obj_integrity/M.max_integrity*100]%
<b>Cell charge:</b> [isnull(cell_charge)?"Not found":"[M.cell.percent()]%"]
<b>Airtank:</b> [M.return_pressure()]kPa
<b>Pilot:</b> [M.occupant||"None"]
<b>Location:</b> [get_area(M)||"Unknown"]
<b>Active equipment:</b> [M.selected||"None"] "}
if(istype(M, /obj/mecha/working/ripley))
var/obj/mecha/working/ripley/RM = M
answer += "<b>Used cargo space:</b> [RM.cargo.len/RM.cargo_capacity*100]%<br>"
if(!chassis)
return FALSE
var/cell_charge = chassis.get_charge()
var/answer = {"<b>Name:</b> [chassis.name]<br>
<b>Integrity:</b> [round((chassis.obj_integrity/chassis.max_integrity * 100), 0.01)]%<br>
<b>Cell Charge:</b> [isnull(cell_charge) ? "Not Found":"[chassis.cell.percent()]%"]<br>
<b>Airtank:</b> [chassis.internal_tank ? "[round(chassis.return_pressure(), 0.01)]" : "Not Equipped"] kPa<br>
<b>Pilot:</b> [chassis.occupant || "None"]<br>
<b>Location:</b> [get_area_name(chassis, TRUE) || "Unknown"]<br>
<b>Active Equipment:</b> [chassis.selected || "None"]"}
if(istype(chassis, /obj/mecha/working/ripley))
var/obj/mecha/working/ripley/RM = chassis
answer += "<br><b>Used Cargo Space:</b> [round((RM.cargo.len / RM.cargo_capacity * 100), 0.01)]%"
return answer
@@ -95,42 +114,41 @@
qdel(src)
/obj/item/mecha_parts/mecha_tracking/Destroy()
if(ismecha(loc))
var/obj/mecha/M = loc
if(src in M.trackers)
M.trackers -= src
if(chassis)
if(src in chassis.trackers)
chassis.trackers -= src
chassis = null
return ..()
/obj/item/mecha_parts/mecha_tracking/proc/in_mecha()
if(ismecha(loc))
return loc
return 0
/obj/item/mecha_parts/mecha_tracking/try_attach_part(mob/user, obj/mecha/M)
if(!..())
return
M.trackers += src
M.diag_hud_set_mechtracking()
chassis = M
/**
* Attempts to EMP mech that the tracker is attached to, if there is one and tracker is not on cooldown
*/
/obj/item/mecha_parts/mecha_tracking/proc/shock()
if(recharging)
return
var/obj/mecha/M = in_mecha()
if(M)
M.emp_act(EMP_HEAVY)
addtimer(CALLBACK(src, /obj/item/mecha_parts/mecha_tracking/proc/recharge), 15 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
recharging = 1
if(chassis)
chassis.emp_act(EMP_HEAVY)
addtimer(CALLBACK(src, /obj/item/mecha_parts/mecha_tracking/proc/recharge), 5 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE)
recharging = TRUE
/**
* Resets recharge variable, allowing tracker to be EMP pulsed again
*/
/obj/item/mecha_parts/mecha_tracking/proc/recharge()
recharging = 0
/obj/item/mecha_parts/mecha_tracking/proc/get_mecha_log()
if(!ismecha(loc))
return 0
var/obj/mecha/M = src.loc
return M.get_log_html()
recharging = FALSE
/obj/item/mecha_parts/mecha_tracking/ai_control
name = "exosuit AI control beacon"
desc = "A device used to transmit exosuit data. Also allows active AI units to take control of said exosuit."
ai_beacon = TRUE
/obj/item/storage/box/mechabeacons
name = "exosuit tracking beacons"
+7
View File
@@ -9,6 +9,13 @@
w_class = WEIGHT_CLASS_GIGANTIC
flags_1 = CONDUCT_1
/obj/item/mecha_parts/proc/try_attach_part(mob/user, obj/mecha/M) //For attaching parts to a finished mech
if(!user.transferItemToLoc(src, M))
to_chat(user, "<span class='warning'>\The [src] is stuck to your hand, you cannot put it in \the [M]!</span>")
return FALSE
user.visible_message("<span class='notice'>[user] attaches [src] to [M].</span>", "<span class='notice'>You attach [src] to [M].</span>")
return TRUE
/obj/item/mecha_parts/chassis
name = "Mecha Chassis"
icon_state = "backbone"
+1 -1
View File
@@ -75,7 +75,7 @@
var/cell_charge = get_charge()
var/datum/gas_mixture/int_tank_air = internal_tank.return_air()
var/tank_pressure = internal_tank ? round(int_tank_air.return_pressure(),0.01) : "None"
var/tank_temperature = internal_tank ? int_tank_air.temperature : "Unknown"
var/tank_temperature = internal_tank ? int_tank_air.return_temperature() : "Unknown"
var/cabin_pressure = round(return_pressure(),0.01)
. = {"[report_internal_damage()]
[integrity<30?"<span class='userdanger'>DAMAGE LEVEL CRITICAL</span><br>":null]
+5
View File
@@ -212,6 +212,11 @@
desc = "A heretical poster depicting the titular star of an equally heretical book."
icon_state = "poster4"
/obj/structure/sign/poster/contraband/post_ratvar
name = "Post This Ratvar"
desc = "Oh what in the hell? Those cultists have animated paper technology and they use it for a meme?"
icon_state = "postvar"
/obj/structure/sign/poster/contraband/syndicate_recruitment
name = "Syndicate Recruitment"
desc = "See the galaxy! Shatter corrupt megacorporations! Join today!"
@@ -40,12 +40,11 @@
if(hotspot && istype(T) && T.air)
qdel(hotspot)
var/datum/gas_mixture/G = T.air
var/plas_amt = min(30,G.gases[/datum/gas/plasma]) //Absorb some plasma
G.gases[/datum/gas/plasma] -= plas_amt
var/plas_amt = min(30,G.get_moles(/datum/gas/plasma)) //Absorb some plasma
G.adjust_moles(/datum/gas/plasma,-plas_amt)
absorbed_plasma += plas_amt
if(G.temperature > T20C)
G.temperature = max(G.temperature/2,T20C)
GAS_GARBAGE_COLLECT(G.gases)
if(G.return_temperature() > T20C)
G.set_temperature(max(G.return_temperature()/2,T20C))
T.air_update_turf()
/obj/effect/particle_effect/foam/firefighting/kill_foam()
@@ -317,15 +316,13 @@
O.ClearWet()
if(O.air)
var/datum/gas_mixture/G = O.air
G.temperature = 293.15
G.set_temperature(293.15)
for(var/obj/effect/hotspot/H in O)
qdel(H)
var/list/G_gases = G.gases
for(var/I in G_gases)
for(var/I in G.get_gases())
if(I == /datum/gas/oxygen || I == /datum/gas/nitrogen)
continue
G_gases[I] = 0
GAS_GARBAGE_COLLECT(G.gases)
G.set_moles(I, 0)
O.air_update_turf()
for(var/obj/machinery/atmospherics/components/unary/U in O)
if(!U.welded)
@@ -166,15 +166,13 @@
if(T.air)
var/datum/gas_mixture/G = T.air
if(!distcheck || get_dist(T, location) < blast) // Otherwise we'll get silliness like people using Nanofrost to kill people through walls with cold air
G.temperature = temperature
G.set_temperature(temperature)
T.air_update_turf()
for(var/obj/effect/hotspot/H in T)
qdel(H)
var/list/G_gases = G.gases
if(G_gases[/datum/gas/plasma])
G_gases[/datum/gas/nitrogen] += (G_gases[/datum/gas/plasma])
G_gases[/datum/gas/plasma] = 0
GAS_GARBAGE_COLLECT(G.gases)
if(G.get_moles(/datum/gas/plasma))
G.adjust_moles(/datum/gas/nitrogen, G.get_moles(/datum/gas/plasma))
G.set_moles(/datum/gas/plasma, 0)
if (weldvents)
for(var/obj/machinery/atmospherics/components/unary/U in T)
if(!isnull(U.welded) && !U.welded) //must be an unwelded vent pump or vent scrubber.
@@ -19,11 +19,11 @@
var/obj/item/tank/internals/plasma/PT = new(V)
var/obj/item/tank/internals/oxygen/OT = new(V)
PT.air_contents.gases[/datum/gas/plasma] = pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p))
PT.air_contents.temperature = CELSIUS_TO_KELVIN(temp_p)
PT.air_contents.set_moles(/datum/gas/plasma, pressure_p*PT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_p)))
PT.air_contents.set_temperature(CELSIUS_TO_KELVIN(temp_p))
OT.air_contents.gases[/datum/gas/oxygen] = pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o))
OT.air_contents.temperature = CELSIUS_TO_KELVIN(temp_o)
OT.air_contents.set_moles(/datum/gas/oxygen, pressure_o*OT.volume/(R_IDEAL_GAS_EQUATION*CELSIUS_TO_KELVIN(temp_o)))
OT.air_contents.set_temperature(CELSIUS_TO_KELVIN(temp_o))
V.tank_one = PT
V.tank_two = OT
@@ -486,4 +486,15 @@
addtimer(CALLBACK(src, .proc/end), 15)
/obj/effect/constructing_effect/proc/end()
qdel(src)
qdel(src)
/obj/effect/temp_visual/dir_setting/space_wind
icon = 'icons/effects/atmospherics.dmi'
icon_state = "space_wind"
layer = FLY_LAYER
duration = 20
mouse_opacity = 0
/obj/effect/temp_visual/dir_setting/space_wind/Initialize(mapload, set_dir, set_alpha = 255)
. = ..()
alpha = set_alpha
+1 -1
View File
@@ -249,7 +249,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
var/datum/asset/assets = get_asset_datum(/datum/asset/spritesheet/pipes)
assets.send(user)
ui = new(user, src, ui_key, "rpd", name, 425, 472, master_ui, state)
ui = new(user, src, ui_key, "RapidPipeDispenser", name, 425, 515, master_ui, state)
ui.open()
/obj/item/pipe_dispenser/ui_data(mob/user)
+31 -10
View File
@@ -113,6 +113,26 @@
. = ..()
. += "<span class='notice'>It has <b>[uses ? uses : "no"]</b> charges left.</span>"
/obj/item/card/id/examine_more(mob/user)
var/list/msg = list("<span class='notice'><i>You examine [src] closer, and note the following...</i></span>")
if(mining_points)
msg += "There's [mining_points] mining equipment redemption point\s loaded onto this card."
if(registered_account)
msg += "The account linked to the ID belongs to '[registered_account.account_holder]' and reports a balance of [registered_account.account_balance] cr."
if(registered_account.account_job)
var/datum/bank_account/D = SSeconomy.get_dep_account(registered_account.account_job.paycheck_department)
if(D)
msg += "The [D.account_holder] reports a balance of [D.account_balance] cr."
msg += "<span class='info'>Alt-Click the ID to pull money from the linked account in the form of holochips.</span>"
msg += "<span class='info'>You can insert credits into the linked account by pressing holochips, cash, or coins against the ID.</span>"
if(registered_account.account_holder == user.real_name)
msg += "<span class='boldnotice'>If you lose this ID card, you can reclaim your account by Alt-Clicking a blank ID card while holding it and entering your account ID number.</span>"
else
msg += "<span class='info'>There is no registered account linked to this card. Alt-Click to add one.</span>"
return msg
/obj/item/card/emag/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/emagrecharge))
var/obj/item/emagrecharge/ER = W
@@ -204,7 +224,7 @@
. = ..()
if(.)
switch(var_name)
if("assignment","registered_name")
if(NAMEOF(src, assignment),NAMEOF(src, registered_name)) //,NAMEOF(src, registered_age))
update_label()
/obj/item/card/id/attack_self(mob/user)
@@ -230,15 +250,13 @@
return ..()
/obj/item/card/id/proc/insert_money(obj/item/I, mob/user, physical_currency)
if(!registered_account)
to_chat(user, "<span class='warning'>[src] doesn't have a linked account to deposit [I] into!</span>")
return
var/cash_money = I.get_item_credit_value()
if(!cash_money)
to_chat(user, "<span class='warning'>[I] doesn't seem to be worth anything!</span>")
return
if(!registered_account)
to_chat(user, "<span class='warning'>[src] doesn't have a linked account to deposit [I] into!</span>")
return
registered_account.adjust_money(cash_money)
if(physical_currency)
to_chat(user, "<span class='notice'>You stuff [I] into [src]. It disappears in a small puff of bluespace smoke, adding [cash_money] credits to the linked account.</span>")
@@ -249,17 +267,20 @@
qdel(I)
/obj/item/card/id/proc/mass_insert_money(list/money, mob/user)
if(!registered_account)
to_chat(user, "<span class='warning'>[src] doesn't have a linked account to deposit into!</span>")
return FALSE
if (!money || !money.len)
return FALSE
var/total = 0
for (var/obj/item/physical_money in money)
var/cash_money = physical_money.get_item_credit_value()
total += physical_money.get_item_credit_value()
CHECK_TICK
total += cash_money
registered_account.adjust_money(cash_money)
registered_account.adjust_money(total)
QDEL_LIST(money)
+5 -5
View File
@@ -53,32 +53,32 @@
/obj/item/chromosome/stabilizer
name = "stabilizer chromosome"
desc = "A chromosome that adjusts to the body to reduce genetic damage by 20%."
desc = "A chromosome that reduces mutation instability by 20%."
icon_state = "stabilizer"
stabilizer_coeff = 0.8
weight = 1
/obj/item/chromosome/synchronizer
name = "synchronizer chromosome"
desc = "A chromosome that gives the mind more controle over the mutation, reducing knockback and downsides by 50%."
desc = "A chromosome that reduces mutation knockback and downsides by 50%."
icon_state = "synchronizer"
synchronizer_coeff = 0.5
/obj/item/chromosome/power
name = "power chromosome"
desc = "A power chromosome for boosting certain mutation's power by 50%."
desc = "A chromosome that increases mutation power by 50%."
icon_state = "power"
power_coeff = 1.5
/obj/item/chromosome/energy
name = "energetic chromosome"
desc = "A chromosome that reduces cooldown on action based mutations by 50%."
desc = "A chromosome that reduces action based mutation cooldowns by by 50%."
icon_state = "energy"
energy_coeff = 0.5
/obj/item/chromosome/reinforcer
name = "reinforcement chromosome"
desc = "Renders the mutation immune to mutadone."
desc = "A chromosome that renders mutations immune to mutadone."
icon_state = "reinforcer"
weight = 3
+3 -3
View File
@@ -246,9 +246,9 @@
/obj/effect/chrono_field/return_air() //we always have nominal air and temperature
var/datum/gas_mixture/GM = new
GM.gases[/datum/gas/oxygen] = MOLES_O2STANDARD
GM.gases[/datum/gas/nitrogen] = MOLES_N2STANDARD
GM.temperature = T20C
GM.set_moles(/datum/gas/oxygen, MOLES_O2STANDARD)
GM.set_moles(/datum/gas/nitrogen, MOLES_N2STANDARD)
GM.set_temperature(T20C)
return GM
/obj/effect/chrono_field/Move()
+1 -1
View File
@@ -152,7 +152,7 @@
SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "crayon", name, 600, 600,
ui = new(user, src, ui_key, "Crayon", name, 600, 600,
master_ui, state)
ui.open()
+7
View File
@@ -619,6 +619,13 @@
if(req_defib)
if(defib.healdisk)
H.heal_overall_damage(25, 25)
var/list/policies = CONFIG_GET(keyed_list/policyconfig)
var/timelimit = CONFIG_GET(number/defib_cmd_time_limit)
var/late = timelimit && (tplus > timelimit)
var/policy = late? policies[POLICYCONFIG_ON_DEFIB_LATE] : policies[POLICYCONFIG_ON_DEFIB_INTACT]
if(policy)
to_chat(H, policy)
H.log_message("revived using a defibrillator, [tplus] deciseconds from time of death, considered [late? "late" : "memory-intact"] revival under configured policy limits.", LOG_GAME)
if(req_defib)
defib.deductcharge(revivecost)
cooldown = 1
+3 -4
View File
@@ -437,7 +437,6 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "Unable to obtain a reading.<br>"
else
var/datum/gas_mixture/environment = T.return_air()
var/list/env_gases = environment.gases
var/pressure = environment.return_pressure()
var/total_moles = environment.total_moles()
@@ -445,12 +444,12 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += "Air Pressure: [round(pressure,0.1)] kPa<br>"
if (total_moles)
for(var/id in env_gases)
var/gas_level = env_gases[id]/total_moles
for(var/id in environment.get_gases())
var/gas_level = environment.get_moles(id)/total_moles
if(gas_level > 0)
dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100, 0.01)]%<br>"
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C<br>"
dat += "Temperature: [round(environment.return_temperature()-T0C)]&deg;C<br>"
dat += "<br>"
else//Else it links to the cart menu proc. Although, it really uses menu hub 4--menu 4 doesn't really exist as it simply redirects to hub.
dat += cartridge.generate_menu()
+1 -1
View File
@@ -58,7 +58,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "intellicard", name, 500, 500, master_ui, state)
ui = new(user, src, ui_key, "Intellicard", name, 500, 500, master_ui, state)
ui.open()
/obj/item/aicard/ui_data()
+1 -1
View File
@@ -76,7 +76,7 @@ GLOBAL_LIST_EMPTY(GPS_list)
// Variable window height, depending on how many GPS units there are
// to show, clamped to relatively safe range.
var/gps_window_height = clamp(325 + GLOB.GPS_list.len * 14, 325, 700)
ui = new(user, src, ui_key, "gps", "Global Positioning System", 470, gps_window_height, master_ui, state) //width, height
ui = new(user, src, ui_key, "Gps", "Global Positioning System", 470, gps_window_height, master_ui, state) //width, height
ui.open()
ui.set_autoupdate(state = updating)
@@ -16,6 +16,9 @@
var/on = TRUE
var/shock_cooldown = FALSE
var/ui_x = 260
var/ui_y = 137
/obj/item/electropack/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] hooks [user.p_them()]self to the electropack and spams the trigger! It looks like [user.p_theyre()] trying to commit suicide!</span>")
return (FIRELOSS)
@@ -128,22 +131,12 @@
if(!ishuman(user))
return
user.set_machine(src)
var/dat = {"
<TT>
Turned [on ? "On" : "Off"] - <A href='?src=[REF(src)];set=power'>Toggle</A><BR>
<B>Frequency/Code</B> for electropack:<BR>
Frequency:
[format_frequency(src.frequency)]
<A href='byond://?src=[REF(src)];set=freq'>Set</A><BR>
Code:
[src.code]
<A href='byond://?src=[REF(src)];set=code'>Set</A><BR>
</TT>"}
user << browse(dat, "window=radio")
onclose(user, "radio")
return
/obj/item/electropack/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "Electropack", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/item/electropack/shockcollar
name = "shock collar"
@@ -119,7 +119,7 @@
ui_height += 6 + channels.len * 21
else
ui_height += 24
ui = new(user, src, ui_key, "radio", name, ui_width, ui_height, master_ui, state)
ui = new(user, src, ui_key, "Radio", name, ui_width, ui_height, master_ui, state)
ui.open()
/obj/item/radio/ui_data(mob/user)
+21 -25
View File
@@ -556,41 +556,38 @@ GENETICS SCANNER
else
to_chat(user, "<span class='alert'>Pressure: [round(pressure, 0.01)] kPa</span>")
if(total_moles)
var/list/env_gases = environment.gases
var/o2_concentration = env_gases[/datum/gas/oxygen]/total_moles
var/n2_concentration = env_gases[/datum/gas/nitrogen]/total_moles
var/co2_concentration = env_gases[/datum/gas/carbon_dioxide]/total_moles
var/plasma_concentration = env_gases[/datum/gas/plasma]/total_moles
var/o2_concentration = environment.get_moles(/datum/gas/oxygen)/total_moles
var/n2_concentration = environment.get_moles(/datum/gas/nitrogen)/total_moles
var/co2_concentration = environment.get_moles(/datum/gas/carbon_dioxide)/total_moles
var/plasma_concentration = environment.get_moles(/datum/gas/plasma)/total_moles
if(abs(n2_concentration - N2STANDARD) < 20)
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen], 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)</span>")
else
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/nitrogen], 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>Nitrogen: [round(n2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/nitrogen), 0.01)] mol)</span>")
if(abs(o2_concentration - O2STANDARD) < 2)
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen], 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)</span>")
else
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/oxygen], 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>Oxygen: [round(o2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/oxygen), 0.01)] mol)</span>")
if(co2_concentration > 0.01)
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide], 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)</span>")
else
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/carbon_dioxide], 0.01)] mol)</span>")
to_chat(user, "<span class='info'>CO2: [round(co2_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/carbon_dioxide), 0.01)] mol)</span>")
if(plasma_concentration > 0.005)
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma], 0.01)] mol)</span>")
to_chat(user, "<span class='alert'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)</span>")
else
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(env_gases[/datum/gas/plasma], 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Plasma: [round(plasma_concentration*100, 0.01)] % ([round(environment.get_moles(/datum/gas/plasma), 0.01)] mol)</span>")
GAS_GARBAGE_COLLECT(environment.gases)
for(var/id in env_gases)
for(var/id in environment.get_gases())
if(id in GLOB.hardcoded_gases)
continue
var/gas_concentration = env_gases[id]/total_moles
to_chat(user, "<span class='alert'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(env_gases[id], 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Temperature: [round(environment.temperature-T0C, 0.01)] &deg;C ([round(environment.temperature, 0.01)] K)</span>")
var/gas_concentration = environment.get_moles(id)/total_moles
to_chat(user, "<span class='alert'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(environment.get_moles(id), 0.01)] mol)</span>")
to_chat(user, "<span class='info'>Temperature: [round(environment.return_temperature()-T0C, 0.01)] &deg;C ([round(environment.return_temperature(), 0.01)] K)</span>")
/obj/item/analyzer/AltClick(mob/user) //Barometer output for measuring when the next storm happens
. = ..()
@@ -669,8 +666,8 @@ GENETICS SCANNER
var/total_moles = air_contents.total_moles()
var/pressure = air_contents.return_pressure()
var/volume = air_contents.return_volume() //could just do mixture.volume... but safety, I guess?
var/temperature = air_contents.temperature
var/volume = air_contents.return_volume()
var/temperature = air_contents.return_temperature()
var/cached_scan_results = air_contents.analyzer_results
if(total_moles > 0)
@@ -678,10 +675,9 @@ GENETICS SCANNER
to_chat(user, "<span class='notice'>Volume: [volume] L</span>")
to_chat(user, "<span class='notice'>Pressure: [round(pressure,0.01)] kPa</span>")
var/list/cached_gases = air_contents.gases
for(var/id in cached_gases)
var/gas_concentration = cached_gases[id]/total_moles
to_chat(user, "<span class='notice'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(cached_gases[id], 0.01)] mol)</span>")
for(var/id in air_contents.get_gases())
var/gas_concentration = air_contents.get_moles(id)/total_moles
to_chat(user, "<span class='notice'>[GLOB.meta_gas_names[id]]: [round(gas_concentration*100, 0.01)] % ([round(air_contents.get_moles(id), 0.01)] mol)</span>")
to_chat(user, "<span class='notice'>Temperature: [round(temperature - T0C,0.01)] &deg;C ([round(temperature, 0.01)] K)</span>")
else
@@ -76,6 +76,9 @@ effective or pretty fucking useless.
var/used = 0 // is it cooling down?
var/stealth = FALSE
var/ui_x = 320
var/ui_y = 335
/obj/item/healthanalyzer/rad_laser/attack(mob/living/M, mob/living/user)
if(!stealth || !irradiate)
..()
@@ -111,7 +114,12 @@ effective or pretty fucking useless.
ui_interact(user)
/obj/item/healthanalyzer/rad_laser/ui_interact(mob/user)
. = ..()
/obj/item/healthanalyzer/rad_laser/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "RadioactiveMicrolaser", "Radioactive Microlaser", ui_x, ui_y, master_ui, state)
ui.open()
var/dat = "Irradiation: <A href='?src=[REF(src)];rad=1'>[irradiate ? "On" : "Off"]</A><br>"
dat += "Stealth Mode (NOTE: Deactivates automatically while Irradiation is off): <A href='?src=[REF(src)];stealthy=[TRUE]'>[stealth ? "On" : "Off"]</A><br>"
@@ -13,6 +13,8 @@
var/mob/attacher = null
var/valve_open = FALSE
var/toggle = 1
var/ui_x = 310
var/ui_y = 320
/obj/item/transfer_valve/IsAssemblyHolder()
return TRUE
@@ -168,8 +170,8 @@
target_self = TRUE
if(change_volume)
if(!target_self)
target.volume += tank_two.volume
target.volume += tank_one.air_contents.volume
target.set_volume(target.return_volume() + tank_two.volume)
target.set_volume(target.return_volume() + tank_one.air_contents.return_volume())
var/datum/gas_mixture/temp
temp = tank_one.air_contents.remove_ratio(1)
target.merge(temp)
@@ -180,11 +182,11 @@
/obj/item/transfer_valve/proc/split_gases()
if (!valve_open || !tank_one || !tank_two)
return
var/ratio1 = tank_one.air_contents.volume/tank_two.air_contents.volume
var/ratio1 = tank_one.air_contents.return_volume()/tank_two.air_contents.return_volume()
var/datum/gas_mixture/temp
temp = tank_two.air_contents.remove_ratio(ratio1)
tank_one.air_contents.merge(temp)
tank_two.air_contents.volume -= tank_one.air_contents.volume
tank_two.air_contents.set_volume(tank_two.air_contents.return_volume() - tank_one.air_contents.return_volume())
/*
Exadv1: I know this isn't how it's going to work, but this was just to check
@@ -235,3 +237,52 @@
// eventually maybe have it update icon to show state (timer, prox etc.) like old bombs
/obj/item/transfer_valve/proc/c_state()
return
/obj/item/transfer_valve/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "TransferValve", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/item/transfer_valve/ui_data(mob/user)
var/list/data = list()
data["tank_one"] = tank_one
data["tank_two"] = tank_two
data["attached_device"] = attached_device
data["valve"] = valve_open
return data
/obj/item/transfer_valve/ui_act(action, params)
if(..())
return
switch(action)
if("tankone")
if(tank_one)
split_gases()
valve_open = FALSE
tank_one.forceMove(drop_location())
tank_one = null
. = TRUE
if("tanktwo")
if(tank_two)
split_gases()
valve_open = FALSE
tank_two.forceMove(drop_location())
tank_two = null
. = TRUE
if("toggle")
toggle_valve()
. = TRUE
if("device")
if(attached_device)
attached_device.attack_self(usr)
. = TRUE
if("remove_device")
if(attached_device)
attached_device.on_detach()
attached_device = null
. = TRUE
update_icon()
+1 -1
View File
@@ -196,7 +196,7 @@
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "eightball", name, 400, 600, master_ui, state)
ui = new(user, src, ui_key, "EightBallVote", name, 400, 600, master_ui, state)
ui.open()
/obj/item/toy/eightball/haunted/ui_data(mob/user)
+2 -3
View File
@@ -204,11 +204,10 @@
//TODO: DEFERRED Consider checking to make sure tank pressure is high enough before doing this...
//Transfer 5% of current tank air contents to turf
var/datum/gas_mixture/air_transfer = ptank.air_contents.remove_ratio(release_amount)
if(air_transfer.gases[/datum/gas/plasma])
air_transfer.gases[/datum/gas/plasma] *= 5
air_transfer.set_moles(/datum/gas/plasma, air_transfer.get_moles(/datum/gas/plasma) * 5)
target.assume_air(air_transfer)
//Burn it based on transfered gas
target.hotspot_expose((ptank.air_contents.temperature*2) + 380,500)
target.hotspot_expose((ptank.air_contents.return_temperature()*2) + 380,500)
//location.hotspot_expose(1000,500,1)
SSair.add_to_active(target, 0)
+8
View File
@@ -54,6 +54,14 @@
else
return ..()
/obj/item/kitchen/fork/throwing
name = "throwing fork"
desc = "A fork, sharpened to perfection, making it a great weapon for throwing."
throwforce = 15
throw_speed = 4
throw_range = 6
embedding = list("pain_mult" = 2, "embed_chance" = 100, "fall_chance" = 0, "embed_chance_turf_mod" = 15)
sharpness = IS_SHARP
/obj/item/kitchen/knife
name = "kitchen knife"
+97 -17
View File
@@ -22,6 +22,11 @@
var/occupant_weight = 0
var/max_occupants = 3 //Hard-cap so you can't have infinite mice or something in one carrier
var/max_occupant_weight = MOB_SIZE_SMALL //This is calculated from the mob sizes of occupants
var/entrance_name = "door" //name of the entrance to the item
var/escape_time = 200 //how long it takes for mobs above small sizes to escape (for small sizes, its randomly 1.5 to 2x this)
var/load_time = 30 //how long it takes for mobs to be loaded into the pet carrier
var/has_lock_sprites = TRUE //whether to load the lock overlays or not
var/allows_hostiles = FALSE //does the pet carrier allow hostile entities to be held within it?
/obj/item/pet_carrier/Destroy()
if(occupants.len)
@@ -51,20 +56,20 @@
else
. += "<span class='notice'>It has nothing inside.</span>"
if(user.canUseTopic(src))
. += "<span class='notice'>Activate it in your hand to [open ? "close" : "open"] its door.</span>"
. += "<span class='notice'>Activate it in your hand to [open ? "close" : "open"] its [entrance_name].</span>"
if(!open)
. += "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"] its door.</span>"
. += "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"] its [entrance_name].</span>"
/obj/item/pet_carrier/attack_self(mob/living/user)
if(open)
to_chat(user, "<span class='notice'>You close [src]'s door.</span>")
to_chat(user, "<span class='notice'>You close [src]'s [entrance_name].</span>")
playsound(user, 'sound/effects/bin_close.ogg', 50, TRUE)
open = FALSE
else
if(locked)
to_chat(user, "<span class='warning'>[src] is locked!</span>")
return
to_chat(user, "<span class='notice'>You open [src]'s door.</span>")
to_chat(user, "<span class='notice'>You open [src]'s [entrance_name].</span>")
playsound(user, 'sound/effects/bin_open.ogg', 50, TRUE)
open = TRUE
update_icon()
@@ -86,7 +91,7 @@
if(user.a_intent == INTENT_HARM)
return ..()
if(!open)
to_chat(user, "<span class='warning'>You need to open [src]'s door!</span>")
to_chat(user, "<span class='warning'>You need to open [src]'s [entrance_name]!</span>")
return
if(target.mob_size > max_occupant_weight)
if(ishuman(target))
@@ -94,13 +99,15 @@
if(iscatperson(H))
to_chat(user, "<span class='warning'>You'd need a lot of catnip and treats, plus maybe a laser pointer, for that to work.</span>")
else
to_chat(user, "<span class='warning'>Humans, generally, do not fit into pet carriers.</span>")
to_chat(user, "<span class='warning'>Humans, generally, do not fit into [name]s.</span>")
else
to_chat(user, "<span class='warning'>You get the feeling [target] isn't meant for a [name].</span>")
return
if(user == target)
to_chat(user, "<span class='warning'>Why would you ever do that?</span>")
return
if(ishostile(target) && (!allows_hostiles || istype(target, /mob/living/simple_animal/hostile/carp/cayenne)) || target.move_resist < MOVE_FORCE_VERY_STRONG) //don't allow goliaths into pet carriers, but let cayenne in!
to_chat(user, "<span class='warning'>You have a feeling you shouldn't keep this as a pet.</span>")
load_occupant(user, target)
/obj/item/pet_carrier/relaymove(mob/living/user, direction)
@@ -110,8 +117,8 @@
remove_occupant(user)
return
else if(!locked)
loc.visible_message("<span class='notice'>[user] pushes open the door to [src]!</span>", \
"<span class='warning'>[user] pushes open the door of [src]!</span>")
loc.visible_message("<span class='notice'>[user] pushes open the [entrance_name] to [src]!</span>", \
"<span class='warning'>[user] pushes open the [entrance_name] of [src]!</span>")
open = TRUE
update_icon()
return
@@ -119,12 +126,19 @@
container_resist(user)
/obj/item/pet_carrier/container_resist(mob/living/user)
//don't do the whole resist timer thing if it's open!
if(open)
loc.visible_message("<span class='notice'>[user] climbs out of [src]!</span>", \
"<span class='warning'>[user] jumps out of [src]!</span>")
remove_occupant(user)
return
user.changeNext_move(CLICK_CD_BREAKOUT)
user.last_special = world.time + CLICK_CD_BREAKOUT
if(user.mob_size <= MOB_SIZE_SMALL)
to_chat(user, "<span class='notice'>You poke a limb through [src]'s bars and start fumbling for the lock switch... (This will take some time.)</span>")
to_chat(loc, "<span class='warning'>You see [user] reach through the bars and fumble for the lock switch!</span>")
if(!do_after(user, rand(300, 400), target = user) || open || !locked || !(user in occupants))
to_chat(user, "<span class='notice'>You begin to try escaping the [src] and start fumbling for the lock switch... (This will take some time.)</span>")
to_chat(loc, "<span class='warning'>You see [user] attempting to unlock the [src]!</span>")
if(!do_after(user, rand(escape_time * 1.5, escape_time * 2), target = user) || open || !locked || !(user in occupants))
return
loc.visible_message("<span class='warning'>[user] flips the lock switch on [src] by reaching through!</span>", null, null, null, user)
to_chat(user, "<span class='boldannounce'>Bingo! The lock pops open!</span>")
@@ -132,12 +146,12 @@
playsound(src, 'sound/machines/boltsup.ogg', 30, TRUE)
update_icon()
else
loc.visible_message("<span class='warning'>[src] starts rattling as something pushes against the door!</span>", null, null, null, user)
loc.visible_message("<span class='warning'>[src] starts rattling as something pushes against the [entrance_name]!</span>", null, null, null, user)
to_chat(user, "<span class='notice'>You start pushing out of [src]... (This will take about 20 seconds.)</span>")
if(!do_after(user, 200, target = user) || open || !locked || !(user in occupants))
if(!do_after(user, escape_time, target = user) || open || !locked || !(user in occupants))
return
loc.visible_message("<span class='warning'>[user] shoves out of [src]!</span>", null, null, null, user)
to_chat(user, "<span class='notice'>You shove open [src]'s door against the lock's resistance and fall out!</span>")
to_chat(user, "<span class='notice'>You shove open [src]'s [entrance_name] against the lock's resistance and fall out!</span>")
locked = FALSE
open = TRUE
update_icon()
@@ -151,7 +165,7 @@
/obj/item/pet_carrier/update_overlays()
. = ..()
if(!open)
if(!open && has_lock_sprites)
. += "[locked ? "" : "un"]locked"
/obj/item/pet_carrier/MouseDrop(atom/over_atom)
@@ -170,7 +184,7 @@
user.visible_message("<span class='notice'>[user] starts loading [target] into [src].</span>", \
"<span class='notice'>You start loading [target] into [src]...</span>", null, null, target)
to_chat(target, "<span class='userdanger'>[user] starts loading you into [user.p_their()] [name]!</span>")
if(!do_mob(user, target, 30))
if(!do_mob(user, target, load_time))
return
if(target in occupants)
return
@@ -192,9 +206,75 @@
/obj/item/pet_carrier/proc/remove_occupant(mob/living/occupant, turf/new_turf)
if(!(occupant in occupants) || !istype(occupant))
return
occupant.forceMove(new_turf ? new_turf : drop_location())
occupant.forceMove(new_turf ? new_turf : get_turf(src))
occupants -= occupant
occupant_weight -= occupant.mob_size
occupant.setDir(SOUTH)
//bluespace jar, a reskin of the pet carrier that can fit people and smashes when thrown
/obj/item/pet_carrier/bluespace
name = "bluespace jar"
desc = "A jar, that seems to be bigger on the inside, somehow allowing lifeforms to fit through its narrow entrance."
open = FALSE //starts closed so it looks better on menus
icon_state = "bluespace_jar"
item_state = "bluespace_jar"
lefthand_file = ""
righthand_file = ""
max_occupant_weight = MOB_SIZE_HUMAN //can fit people, like a bluespace bodybag!
load_time = 40 //loading things into a jar takes longer than a regular pet carrier
entrance_name = "lid"
w_class = WEIGHT_CLASS_SMALL //it's a jar
throw_speed = 3
throw_range = 7
max_occupants = 1 //far less than a regular carrier or bluespace bodybag, because it can be thrown to release the contents
allows_hostiles = TRUE //can fit hostile creatures, with the move resist restrictions in place, this means they still cannot take things like legions/goliaths/etc regardless
has_lock_sprites = FALSE //jar doesn't show the regular lock overlay
custom_materials = list(/datum/material/glass = 1000, /datum/material/bluespace = 600)
escape_time = 10 //half the time of a bluespace bodybag
var/datum/gas_mixture/occupant_gas_supply
/obj/item/pet_carrier/bluespace/update_icon_state()
if(open)
icon_state = "bluespace_jar_open"
else
icon_state = "bluespace_jar"
/obj/item/pet_carrier/bluespace/throw_impact()
. = ..()
//delete the item upon impact, releasing the creature inside (this is handled by its deletion)
if(occupants.len)
loc.visible_message("<span class='warning'>The bluespace jar smashes, releasing [occupants[1]]!</span>")
playsound(src, "shatter", 70, 1)
qdel(src)
/obj/item/pet_carrier/bluespace/add_occupant(mob/living/occupant) //update the gas supply as required, this acts like magical internals
. = ..()
if(!occupant_gas_supply)
occupant_gas_supply = new
if(isanimal(occupant))
var/mob/living/simple_animal/animal = occupant
occupant_gas_supply[/datum/gas/oxygen] = 0.0064 //make sure it has some gas in so it isn't depressurized
occupant_gas_supply.set_temperature(animal.minbodytemp) //simple animals only care about temperature/pressure when their turf isnt a location
else
if(ishuman(occupant)) //humans require resistance to cold/heat and living in no air while inside, and lose this when outside
ADD_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist")
ADD_TRAIT(occupant, TRAIT_RESISTHEAT, "bluespace_container_heat_resist")
ADD_TRAIT(occupant, TRAIT_NOBREATH, "bluespace_container_no_breath")
ADD_TRAIT(occupant, TRAIT_RESISTHIGHPRESSURE, "bluespace_container_resist_high_pressure")
ADD_TRAIT(occupant, TRAIT_RESISTLOWPRESSURE, "bluespace_container_resist_low_pressure")
/obj/item/pet_carrier/bluespace/remove_occupant(mob/living/occupant)
. = ..()
if(ishuman(occupant))
REMOVE_TRAIT(occupant, TRAIT_RESISTCOLD, "bluespace_container_cold_resist")
REMOVE_TRAIT(occupant, TRAIT_RESISTHEAT, "bluespace_container_heat_resist")
REMOVE_TRAIT(occupant, TRAIT_NOBREATH, "bluespace_container_no_breath")
REMOVE_TRAIT(occupant, TRAIT_RESISTHIGHPRESSURE, "bluespace_container_resist_high_pressure")
REMOVE_TRAIT(occupant, TRAIT_RESISTLOWPRESSURE, "bluespace_container_resist_low_pressure")
/obj/item/pet_carrier/bluespace/return_air()
if(!occupant_gas_supply)
occupant_gas_supply = new
return occupant_gas_supply
#undef pet_carrier_full
@@ -566,7 +566,7 @@
/obj/item/borg/upgrade/expand/deactivate(mob/living/silicon/robot/R, user = usr)
. = ..()
if (.)
if (. && R.hasExpanded)
R.resize = 0.5
R.hasExpanded = FALSE
R.update_transform()
@@ -244,6 +244,7 @@ GLOBAL_LIST_INIT(wood_recipes, list ( \
new/datum/stack_recipe("rifle stock", /obj/item/weaponcrafting/stock, 10, time = 20), \
new/datum/stack_recipe("rolling pin", /obj/item/kitchen/rollingpin, 2, time = 30), \
new/datum/stack_recipe("wooden bucket", /obj/item/reagent_containers/glass/bucket/wood, 2, time = 30), \
new/datum/stack_recipe("painting frame", /obj/item/wallframe/painting, 1, time = 10),\
new/datum/stack_recipe("wooden buckler", /obj/item/shield/riot/buckler, 20, time = 40), \
new/datum/stack_recipe("baseball bat", /obj/item/melee/baseball_bat, 5, time = 15),\
null, \
+12 -2
View File
@@ -15,6 +15,9 @@
var/list/conferred_embed = EMBED_HARMLESS
var/overwrite_existing = FALSE
var/endless = FALSE
var/apply_time = 30
/obj/item/stack/sticky_tape/afterattack(obj/item/I, mob/living/user)
if(!istype(I))
return
@@ -25,17 +28,24 @@
user.visible_message("<span class='notice'>[user] begins wrapping [I] with [src].</span>", "<span class='notice'>You begin wrapping [I] with [src].</span>")
if(do_after(user, 30, target=I))
if(do_after(user, apply_time, target=I))
I.embedding = conferred_embed
I.updateEmbedding()
to_chat(user, "<span class='notice'>You finish wrapping [I] with [src].</span>")
use(1)
if(!endless)
use(1)
I.name = "[prefix] [I.name]"
if(istype(I, /obj/item/grenade))
var/obj/item/grenade/sticky_bomb = I
sticky_bomb.sticky = TRUE
/obj/item/stack/sticky_tape/infinite //endless tape that applies far faster, for maximum honks
name = "endless sticky tape"
desc = "This roll of sticky tape somehow has no end."
endless = TRUE
apply_time = 10
/obj/item/stack/sticky_tape/super
name = "super sticky tape"
singular_name = "super sticky tape"
@@ -4,6 +4,7 @@
singular_name = "telecrystal"
icon = 'icons/obj/telescience.dmi'
icon_state = "telecrystal"
grind_results = list(/datum/reagent/telecrystal = 20)
w_class = WEIGHT_CLASS_TINY
max_amount = 50
item_flags = NOBLUDGEON
+31
View File
@@ -0,0 +1,31 @@
/obj/item/stack/arcadeticket
name = "arcade tickets"
desc = "Wow! With enough of these, you could buy a bike! ...Pssh, yeah right."
singular_name = "arcade ticket"
icon_state = "arcade-ticket"
item_state = "tickets"
w_class = WEIGHT_CLASS_TINY
max_amount = 30
/obj/item/stack/arcadeticket/Initialize(mapload, new_amount, merge = TRUE)
. = ..()
update_icon()
/obj/item/stack/arcadeticket/update_icon()
var/amount = get_amount()
if((amount >= 12) && (amount > 0))
icon_state = "arcade-ticket_4"
else if((amount >= 6) && (amount > 0))
icon_state = "arcade-ticket_3"
else if((amount >= 2) && (amount > 0))
icon_state = "arcade-ticket_2"
else
icon_state = "arcade-ticket"
/obj/item/stack/arcadeticket/proc/pay_tickets()
amount -= 2
if (amount == 0)
qdel(src)
/obj/item/stack/arcadeticket/thirty
amount = 30
+13 -2
View File
@@ -48,7 +48,8 @@
STR.max_w_class = WEIGHT_CLASS_SMALL
STR.max_combined_w_class = 30
STR.max_items = 30
STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear))
STR.can_hold_extra = typecacheof(list(/obj/item/organ/lungs, /obj/item/organ/liver, /obj/item/organ/stomach, /obj/item/clothing/shoes)) - typesof(/obj/item/clothing/shoes/magboots, /obj/item/clothing/shoes/clown_shoes, /obj/item/clothing/shoes/jackboots, /obj/item/clothing/shoes/workboots)
STR.cant_hold = typecacheof(list(/obj/item/disk/nuclear, /obj/item/storage/wallet, /obj/item/organ/brain))
STR.limited_random_access = TRUE
STR.limited_random_access_stack_position = 3
@@ -326,6 +327,7 @@
w_class = WEIGHT_CLASS_BULKY
flags_1 = CONDUCT_1
custom_materials = list(/datum/material/iron=3000)
var/max_items = 7
/obj/item/storage/bag/tray/ComponentInitialize()
. = ..()
@@ -333,6 +335,7 @@
STR.max_w_class = WEIGHT_CLASS_NORMAL
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food, /obj/item/reagent_containers/glass, /datum/reagent/consumable, /obj/item/kitchen/knife, /obj/item/kitchen/rollingpin, /obj/item/kitchen/fork, /obj/item/storage/box)) //Should cover: Bottles, Beakers, Bowls, Booze, Glasses, Food, Kitchen Tools, and ingredient boxes.
STR.insert_preposition = "on"
STR.max_items = max_items
/obj/item/storage/bag/tray/attack(mob/living/M, mob/living/user)
. = ..()
@@ -373,6 +376,14 @@
. = ..()
update_icon()
//bluespace tray, holds more items
/obj/item/storage/bag/tray/bluespace
name = "bluespace tray"
icon_state = "bluespace_tray"
desc = "A tray created using bluespace technology to fit more food on it."
max_items = 30 // far more items
custom_materials = list(/datum/material/iron = 2000, /datum/material/bluespace = 500)
/*
* Chemistry bag
*/
@@ -462,4 +473,4 @@
STR.max_combined_w_class = INFINITY
STR.max_items = 2
STR.display_numerical_stacking = TRUE
STR.can_hold = typecacheof(list(/obj/item/rcd_ammo, /obj/item/stack/sheet))
STR.can_hold = typecacheof(list(/obj/item/rcd_ammo, /obj/item/stack/sheet))
+6
View File
@@ -1418,3 +1418,9 @@ obj/item/storage/box/stingbangs
new /obj/item/reagent_containers/glass/beaker/meta(src)
new /obj/item/reagent_containers/glass/beaker/noreact(src)
new /obj/item/reagent_containers/glass/beaker/bluespace(src)
/obj/item/storage/box/strange_seeds_5pack
/obj/item/storage/box/strange_seeds_5pack/PopulateContents()
for(var/i in 1 to 5)
new /obj/item/seeds/random(src)
+1 -1
View File
@@ -21,7 +21,7 @@
/obj/item/tank/jetpack/populate_gas()
if(gas_type)
air_contents.gases[gas_type] = ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C))
air_contents.set_moles(gas_type, ((6 * ONE_ATMOSPHERE) * volume / (R_IDEAL_GAS_EQUATION * T20C)))
/obj/item/tank/jetpack/ui_action_click(mob/user, action)
+21 -12
View File
@@ -18,8 +18,9 @@
force = 10
dog_fashion = /datum/dog_fashion/back
/obj/item/tank/internals/oxygen/populate_gas()
air_contents.gases[/datum/gas/oxygen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.set_moles(/datum/gas/oxygen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
@@ -47,8 +48,9 @@
force = 10
/obj/item/tank/internals/anesthetic/populate_gas()
air_contents.gases[/datum/gas/oxygen] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
air_contents.gases[/datum/gas/nitrous_oxide] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
air_contents.set_moles(/datum/gas/oxygen, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
air_contents.set_moles(/datum/gas/nitrous_oxide, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
return
/*
* Air
@@ -62,8 +64,9 @@
dog_fashion = /datum/dog_fashion/back
/obj/item/tank/internals/air/populate_gas()
air_contents.gases[/datum/gas/oxygen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD
air_contents.gases[/datum/gas/nitrogen] = (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD
air_contents.set_moles(/datum/gas/oxygen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD)
air_contents.set_moles(/datum/gas/nitrogen, (6*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD)
return
/*
@@ -79,7 +82,8 @@
/obj/item/tank/internals/plasma/populate_gas()
air_contents.gases[/datum/gas/plasma] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.set_moles(/datum/gas/plasma, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
/obj/item/tank/internals/plasma/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/flamethrower))
@@ -93,12 +97,16 @@
F.update_icon()
else
return ..()
/obj/item/tank/internals/plasma/full/populate_gas()
air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
//Makes empty oxygen tanks spawn without gas
/obj/item/tank/internals/plasma/empty/populate_gas()
return
/obj/item/tank/internals/plasma/full/populate_gas()
air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
/*
* Plasmaman Plasma Tank
@@ -113,10 +121,11 @@
distribute_pressure = TANK_DEFAULT_RELEASE_PRESSURE
/obj/item/tank/internals/plasmaman/populate_gas()
air_contents.gases[/datum/gas/plasma] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.set_moles(/datum/gas/plasma, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
/obj/item/tank/internals/plasmaman/full/populate_gas()
air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
@@ -129,7 +138,7 @@
w_class = WEIGHT_CLASS_SMALL //thanks i forgot this
/obj/item/tank/internals/plasmaman/belt/full/populate_gas()
air_contents.gases[/datum/gas/plasma] = (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.set_moles(/datum/gas/plasma, (10*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
//makes empty plasma tanks spawn without gas.
@@ -152,7 +161,7 @@
/obj/item/tank/internals/emergency_oxygen/populate_gas()
air_contents.gases[/datum/gas/oxygen] = (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C)
air_contents.set_moles(/datum/gas/oxygen, (3*ONE_ATMOSPHERE)*volume/(R_IDEAL_GAS_EQUATION*T20C))
return
/obj/item/tank/internals/emergency_oxygen/empty/populate_gas()
@@ -172,4 +181,4 @@
volume = 10
/obj/item/tank/internals/emergency_oxygen/double/empty/populate_gas()
return
return
+4 -4
View File
@@ -64,7 +64,7 @@
. = ..()
air_contents = new(volume) //liters
air_contents.temperature = T20C
air_contents.set_temperature(T20C)
populate_gas()
@@ -92,7 +92,7 @@
. += "<span class='notice'>The pressure gauge reads [round(src.air_contents.return_pressure(),0.01)] kPa.</span>"
var/celsius_temperature = src.air_contents.temperature-T0C
var/celsius_temperature = src.air_contents.return_temperature()-T0C
var/descriptive
if (celsius_temperature < 20)
@@ -168,7 +168,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "tanks", name, 400, 120, master_ui, state)
ui = new(user, src, ui_key, "Tank", name, 400, 120, master_ui, state)
ui.open()
/obj/item/tank/ui_data(mob/user)
@@ -235,7 +235,7 @@
if(tank_pressure < distribute_pressure)
distribute_pressure = tank_pressure
var/moles_needed = distribute_pressure*volume_to_return/(R_IDEAL_GAS_EQUATION*air_contents.temperature)
var/moles_needed = distribute_pressure*volume_to_return/(R_IDEAL_GAS_EQUATION*air_contents.return_temperature())
return remove_air(moles_needed)
+1 -5
View File
@@ -37,13 +37,9 @@
if("anchored")
setAnchored(vval)
return TRUE
if("obj_flags")
if(NAMEOF(src, obj_flags))
if ((obj_flags & DANGEROUS_POSSESSION) && !(vval & DANGEROUS_POSSESSION))
return FALSE
if("control_object")
var/obj/O = vval
if(istype(O) && (O.obj_flags & DANGEROUS_POSSESSION))
return FALSE
return ..()
/obj/Initialize()
+1 -1
View File
@@ -80,7 +80,7 @@
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "canvas", name, ui_x, ui_y, master_ui, state)
ui = new(user, src, ui_key, "Canvas", name, ui_x, ui_y, master_ui, state)
ui.set_autoupdate(FALSE)
ui.open()
+2 -2
View File
@@ -94,7 +94,7 @@
alpha = 150
resistance_flags = FIRE_PROOF
/obj/structure/holosign/barrier/firelock/blocksTemperature()
/obj/structure/holosign/barrier/firelock/BlockSuperconductivity()
return TRUE
/obj/structure/holosign/barrier/combifan
@@ -110,7 +110,7 @@
CanAtmosPass = ATMOS_PASS_NO
resistance_flags = FIRE_PROOF
/obj/structure/holosign/barrier/combifan/blocksTemperature()
/obj/structure/holosign/barrier/combifan/BlockSuperconductivity()
return TRUE
/obj/structure/holosign/barrier/combifan/Initialize()
+9 -1
View File
@@ -225,7 +225,15 @@ GLOBAL_LIST_EMPTY(crematoriums)
GLOB.crematoriums.Add(src)
..()
/obj/structure/bodycontainer/crematorium/update_icon_state()
/obj/structure/bodycontainer/crematorium/Initialize()
. = ..()
connected = new /obj/structure/tray/c_tray(src)
connected.connected = src
/obj/structure/bodycontainer/crematorium/connect_to_shuttle(obj/docking_port/mobile/port, obj/docking_port/stationary/dock, idnum, override=FALSE)
id = "[idnum][id]"
/obj/structure/bodycontainer/crematorium/update_icon()
if(!connected || connected.loc != src)
icon_state = "crema0"
else
@@ -71,7 +71,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.physical_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "tank_dispenser", name, 275, 103, master_ui, state)
ui = new(user, src, ui_key, "TankDispenser", name, 275, 103, master_ui, state)
ui.open()
/obj/structure/tank_dispenser/ui_data(mob/user)
@@ -152,8 +152,8 @@
pod_moving = 0
if(!QDELETED(pod))
var/datum/gas_mixture/floor_mixture = loc.return_air()
ARCHIVE(floor_mixture)
ARCHIVE(pod.air_contents)
floor_mixture.archive()
pod.air_contents.archive()
pod.air_contents.share(floor_mixture, 1) //mix the pod's gas mixture with the tile it's on
air_update_turf()
@@ -10,9 +10,9 @@
/obj/structure/transit_tube_pod/Initialize()
. = ..()
air_contents.gases[/datum/gas/oxygen] = MOLES_O2STANDARD
air_contents.gases[/datum/gas/nitrogen] = MOLES_N2STANDARD
air_contents.temperature = T20C
air_contents.set_moles(/datum/gas/oxygen, MOLES_O2STANDARD)
air_contents.set_moles(/datum/gas/nitrogen, MOLES_N2STANDARD)
air_contents.set_temperature(T20C)
/obj/structure/transit_tube_pod/Destroy()
@@ -181,4 +181,4 @@
return
/obj/structure/transit_tube_pod/return_temperature()
return air_contents.temperature
return air_contents.return_temperature()
+4
View File
@@ -110,6 +110,8 @@ GLOBAL_LIST_INIT(freqtospan, list(
/// Quirky citadel proc for our custom sayverbs to strip the verb out. Snowflakey as hell, say rewrite 3.0 when?
/atom/movable/proc/quoteless_say_quote(input, list/spans = list(speech_span), message_mode)
if((input[1] == "!") && (length_char(input) > 1))
return ""
var/pos = findtext(input, "*")
return pos? copytext(input, pos + 1) : input
@@ -144,6 +146,8 @@ GLOBAL_LIST_INIT(freqtospan, list(
return "[copytext_char("[freq]", 1, 4)].[copytext_char("[freq]", 4, 5)]"
/atom/movable/proc/attach_spans(input, list/spans)
if((input[1] == "!") && (length(input) > 2))
return
var/customsayverb = findtext(input, "*")
if(customsayverb)
input = capitalize(copytext(input, customsayverb + length(input[customsayverb])))
+3 -12
View File
@@ -148,6 +148,7 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
. = ..()
if (!.) // changeturf failed or didn't do anything
QDEL_NULL(stashed_air)
update_air_ref()
return
var/turf/open/newTurf = .
newTurf.air.copy_from(stashed_air)
@@ -308,24 +309,14 @@ GLOBAL_LIST_INIT(blacklisted_automated_baseturfs, typecacheof(list(
return
var/datum/gas_mixture/total = new//Holders to assimilate air from nearby turfs
var/list/total_gases = total.gases
for(var/T in atmos_adjacent_turfs)
var/turf/open/S = T
if(!S.air)
continue
var/list/S_gases = S.air.gases
for(var/id in S_gases)
total_gases[id] += S_gases[id]
total.temperature += S.air.temperature
total.merge(S.air)
air.copy_from(total)
var/list/air_gases = air.gases
for(var/id in air_gases)
air_gases[id] /= turf_count //Averages contents of the turfs, ignoring walls and the like
air.temperature /= turf_count
air.copy_from(total.remove_ratio(1/turf_count))
SSair.add_to_active(src)
/turf/proc/ReplaceWithLattice()
+6 -1
View File
@@ -7,9 +7,14 @@
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
rad_insulation = RAD_MEDIUM_INSULATION
/turf/closed/Initialize()
. = ..()
update_air_ref()
/turf/closed/AfterChange()
. = ..()
SSair.high_pressure_delta -= src
update_air_ref()
/turf/closed/get_smooth_underlay_icon(mutable_appearance/underlay_appearance, turf/asking_turf, adjacency_dir)
return FALSE
@@ -78,7 +83,7 @@
. = ..()
if(.)
switch(var_name)
if("icon")
if(NAMEOF(src, icon))
SStitle.icon = icon
/turf/closed/indestructible/riveted

Some files were not shown because too many files have changed in this diff Show More