yeehaw it's done

This commit is contained in:
Seris02
2020-02-05 16:54:57 +08:00
633 changed files with 38003 additions and 6217 deletions
+9 -3
View File
@@ -505,9 +505,8 @@
return final_rgb
/atom/proc/clean_blood()
if(islist(blood_DNA))
blood_DNA = null
return TRUE
. = blood_DNA? TRUE : FALSE
blood_DNA = null
/atom/proc/wash_cream()
return TRUE
@@ -728,6 +727,13 @@
/atom/proc/multitool_act(mob/living/user, obj/item/I)
return
/atom/proc/multitool_check_buffer(user, obj/item/I, silent = FALSE)
if(!istype(I, /obj/item/multitool))
if(user && !silent)
to_chat(user, "<span class='warning'>[I] has no data buffer!</span>")
return FALSE
return TRUE
/atom/proc/screwdriver_act(mob/living/user, obj/item/I)
SEND_SIGNAL(src, COMSIG_ATOM_SCREWDRIVER_ACT, user, I)
+19 -19
View File
@@ -57,10 +57,8 @@
/obj/item/melee/transforming/energy/sword/bananium
name = "bananium sword"
desc = "An elegant weapon, for a more civilized age."
force = 0
throwforce = 0
force_on = 0
throwforce_on = 0
force_on = 15
throwforce_on = 15
hitsound = null
attack_verb_on = list("slipped")
clumsy_check = FALSE
@@ -69,24 +67,26 @@
heat = 0
light_color = "#ffff00"
var/next_trombone_allowed = 0
var/datum/component/slippery/slipper
/obj/item/melee/transforming/energy/sword/bananium/Initialize()
. = ..()
AddComponent(/datum/component/slippery, 60, GALOSHES_DONT_HELP)
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
slipper = LoadComponent(/datum/component/slippery, 81, GALOSHES_DONT_HELP)
slipper.signal_enabled = active
/obj/item/melee/transforming/energy/sword/bananium/attack(mob/living/M, mob/living/user)
..()
if(active)
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
slipper.Slip(M)
slipper.lube_flags |= FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING
slipper.Slip(src, M)
slipper.lube_flags &= ~(FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING)
/obj/item/melee/transforming/energy/sword/bananium/throw_impact(atom/hit_atom, throwingdatum)
. = ..()
if(active)
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
slipper.Slip(hit_atom)
slipper.lube_flags |= FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING
slipper.Slip(src, hit_atom)
slipper.lube_flags &= ~(FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING)
/obj/item/melee/transforming/energy/sword/bananium/attackby(obj/item/I, mob/living/user, params)
if((world.time > next_trombone_allowed) && istype(I, /obj/item/melee/transforming/energy/sword/bananium))
@@ -98,7 +98,6 @@
/obj/item/melee/transforming/energy/sword/bananium/transform_weapon(mob/living/user, supress_message_text)
..()
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
slipper.signal_enabled = active
/obj/item/melee/transforming/energy/sword/bananium/ignition_effect(atom/A, mob/user)
@@ -108,8 +107,9 @@
if(!active)
transform_weapon(user, TRUE)
user.visible_message("<span class='suicide'>[user] is [pick("slitting [user.p_their()] stomach open with", "falling on")] [src]! It looks like [user.p_theyre()] trying to commit seppuku, but the blade slips off of [user.p_them()] harmlessly!</span>")
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
slipper.Slip(user)
slipper.lube_flags |= FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING
slipper.Slip(src, user)
slipper.lube_flags &= ~(FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING)
return SHAME
//BANANIUM SHIELD
@@ -126,16 +126,15 @@
on_force = 0
on_throwforce = 0
on_throw_speed = 1
var/datum/component/slippery/slipper
/obj/item/shield/energy/bananium/Initialize()
. = ..()
AddComponent(/datum/component/slippery, 60, GALOSHES_DONT_HELP)
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
slipper = LoadComponent(/datum/component/slippery, 81, GALOSHES_DONT_HELP)
slipper.signal_enabled = active
/obj/item/shield/energy/bananium/attack_self(mob/living/carbon/human/user)
..()
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
slipper.signal_enabled = active
/obj/item/shield/energy/bananium/throw_at(atom/target, range, speed, mob/thrower, spin=1, diagonals_first = 0, datum/callback/callback)
@@ -149,8 +148,9 @@
if(active)
var/caught = hit_atom.hitby(src, FALSE, FALSE, throwingdatum=throwingdatum)
if(iscarbon(hit_atom) && !caught)//if they are a carbon and they didn't catch it
var/datum/component/slippery/slipper = GetComponent(/datum/component/slippery)
slipper.Slip(hit_atom)
slipper.lube_flags |= FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING
slipper.Slip(src, hit_atom)
slipper.lube_flags &= ~(FLYING_DOESNT_HELP|SLIP_WHEN_CRAWLING)
if(thrownby && !caught)
throw_at(thrownby, throw_range+2, throw_speed, null, 1)
else
@@ -212,7 +212,7 @@
M.equip_to_slot_or_del(the_stash, SLOT_WEAR_MASK, TRUE, TRUE, TRUE, TRUE)
/obj/item/clothing/mask/fakemoustache/sticky
var/unstick_time = 600
var/unstick_time = 2 MINUTES
/obj/item/clothing/mask/fakemoustache/sticky/Initialize()
. = ..()
+5
View File
@@ -113,6 +113,11 @@ Class Procs:
var/atom/movable/occupant = null
var/speed_process = FALSE // Process as fast as possible?
var/obj/item/circuitboard/circuit // Circuit to be created and inserted when the machinery is created
// For storing and overriding ui id and dimensions
var/tgui_id // ID of TGUI interface
var/ui_style // ID of custom TGUI style (optional)
var/ui_x
var/ui_y
var/interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_SET_MACHINE
+28 -25
View File
@@ -46,34 +46,37 @@
new /obj/item/stack/spacecash/c200(drop_location()) // will autostack
playsound(src.loc, 'sound/items/poster_being_created.ogg', 100, 1)
SSshuttle.points -= 200
if(next_warning < world.time && prob(15))
var/area/A = get_area(loc)
var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!"
radio.talk_into(src, message, radio_channel)
next_warning = world.time + minimum_time_between_warnings
if(next_warning < world.time && prob(15))
var/area/A = get_area(loc)
var/message = "Unauthorized credit withdrawal underway in [A.map_name]!!"
radio.talk_into(src, message, radio_channel)
next_warning = world.time + minimum_time_between_warnings
/obj/machinery/computer/bank_machine/ui_interact(mob/user)
. = ..()
var/dat = "[station_name()] secure vault. Authorized personnel only.<br>"
dat += "Current Balance: [SSshuttle.points] credits.<br>"
if(!siphoning)
dat += "<A href='?src=[REF(src)];siphon=1'>Siphon Credits</A><br>"
else
dat += "<A href='?src=[REF(src)];halt=1'>Halt Credit Siphon</A><br>"
/obj/machinery/computer/bank_machine/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, "bank_machine", name, 320, 165, master_ui, state)
ui.open()
dat += "<a href='?src=[REF(user)];mach_close=computer'>Close</a>"
/obj/machinery/computer/bank_machine/ui_data(mob/user)
var/list/data = list()
data["current_balance"] = SSshuttle.points
data["siphoning"] = siphoning
data["station_name"] = station_name()
var/datum/browser/popup = new(user, "computer", "Bank Vault", 300, 200)
popup.set_content("<center>[dat]</center>")
popup.set_title_image(usr.browse_rsc_icon(src.icon, src.icon_state))
popup.open()
return data
/obj/machinery/computer/bank_machine/Topic(href, href_list)
/obj/machinery/computer/bank_machine/ui_act(action, params)
if(..())
return
if(href_list["siphon"])
say("Siphon of station credits has begun!")
siphoning = TRUE
if(href_list["halt"])
say("Station credit withdrawal halted.")
siphoning = FALSE
switch(action)
if("siphon")
say("Siphon of station credits has begun!")
siphoning = TRUE
. = TRUE
if("halt")
say("Station credit withdrawal halted.")
siphoning = FALSE
. = TRUE
+3 -8
View File
@@ -11,7 +11,6 @@
var/obj/structure/table/optable/table
var/list/advanced_surgeries = list()
var/datum/techweb/linked_techweb
var/menu = MENU_OPERATION
light_color = LIGHT_COLOR_BLUE
/obj/machinery/computer/operating/Initialize()
@@ -54,8 +53,6 @@
var/list/data = list()
data["table"] = table
if(table)
data["menu"] = menu
var/list/surgeries = list()
for(var/X in advanced_surgeries)
var/datum/surgery/S = X
@@ -64,9 +61,8 @@
surgery["desc"] = initial(S.desc)
surgeries += list(surgery)
data["surgeries"] = surgeries
data["patient"] = list()
if(table.check_patient())
data["patient"] = list()
patient = table.patient
switch(patient.stat)
if(CONSCIOUS)
@@ -110,15 +106,14 @@
"alternative_step" = alternative_step,
"alt_chems_needed" = alt_chems_needed
))
else
data["patient"] = null
return data
/obj/machinery/computer/operating/ui_act(action, params)
if(..())
return
switch(action)
if("change_menu")
menu = text2num(params["menu"])
. = TRUE
if("sync")
sync_surgeries()
. = TRUE
+1 -1
View File
@@ -198,7 +198,7 @@
/obj/machinery/computer/apc_control/proc/log_activity(log_text)
var/op_string = operator && !(obj_flags & EMAGGED) ? operator : "\[NULL OPERATOR\]"
LAZYADD(logs, "<b>([STATION_TIME_TIMESTAMP("hh:mm:ss")])</b> [op_string] [log_text]")
LAZYADD(logs, "<b>([STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)])</b> [op_string] [log_text]")
/mob/proc/using_power_flow_console()
for(var/obj/machinery/computer/apc_control/A in range(1, src))
+31 -12
View File
@@ -91,6 +91,8 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
icon_screen = "tank"
icon_keyboard = "atmos_key"
circuit = /obj/item/circuitboard/computer/atmos_control
ui_x = 400
ui_y = 925
var/frequency = FREQ_ATMOS_STORAGE
var/list/sensors = list(
@@ -125,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, 400, 925, master_ui, state)
ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/ui_data(mob/user)
@@ -161,6 +163,20 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
frequency = new_frequency
radio_connection = SSradio.add_object(src, frequency, RADIO_ATMOSIA)
//Incinerator sensor only
/obj/machinery/computer/atmos_control/incinerator
name = "Incinerator Air Control"
sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber")
ui_x = 400
ui_y = 300
//Toxins mix sensor only
/obj/machinery/computer/atmos_control/toxinsmix
name = "Toxins Mixing Air Control"
sensors = list(ATMOS_GAS_MONITOR_SENSOR_TOXINS_LAB = "Toxins Mixing Chamber")
ui_x = 400
ui_y = 300
/////////////////////////////////////////////////////////////
// LARGE TANK CONTROL
/////////////////////////////////////////////////////////////
@@ -174,6 +190,9 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
var/list/input_info
var/list/output_info
ui_x = 500
ui_y = 315
/obj/machinery/computer/atmos_control/tank/oxygen_tank
name = "Oxygen Supply Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_O2
@@ -216,12 +235,6 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
output_tag = ATMOS_GAS_MONITOR_OUTPUT_CO2
sensors = list(ATMOS_GAS_MONITOR_SENSOR_CO2 = "Carbon Dioxide Tank")
/obj/machinery/computer/atmos_control/tank/incinerator
name = "Incinerator Air Control"
input_tag = ATMOS_GAS_MONITOR_INPUT_INCINERATOR
output_tag = ATMOS_GAS_MONITOR_OUTPUT_INCINERATOR
sensors = list(ATMOS_GAS_MONITOR_SENSOR_INCINERATOR = "Incinerator Chamber")
// This hacky madness is the evidence of the fact that a lot of machines were never meant to be constructable, im so sorry you had to see this
/obj/machinery/computer/atmos_control/tank/proc/reconnect(mob/user)
var/list/IO = list()
@@ -235,7 +248,7 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
IO |= text[1]
if(!IO.len)
to_chat(user, "<span class='alert'>No machinery detected.</span>")
var/S = input("Select the device set: ", "Selection", IO[1]) as anything in IO
var/S = input("Select the device set: ", "Selection", IO[1]) as anything in sortList(IO)
if(src)
src.input_tag = "[S]_in"
src.output_tag = "[S]_out"
@@ -256,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, 500, 305, master_ui, state)
ui = new(user, src, ui_key, "atmos_control", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/atmos_control/tank/ui_data(mob/user)
@@ -280,13 +293,19 @@ GLOBAL_LIST_EMPTY(atmos_air_controllers)
if("input")
signal.data += list("tag" = input_tag, "power_toggle" = TRUE)
. = TRUE
if("rate")
var/target = text2num(params["rate"])
if(!isnull(target))
target = CLAMP(target, 0, MAX_TRANSFER_RATE)
signal.data += list("tag" = input_tag, "set_volume_rate" = target)
. = TRUE
if("output")
signal.data += list("tag" = output_tag, "power_toggle" = TRUE)
. = TRUE
if("pressure")
var/target = input("New target pressure:", name, output_info ? output_info["internal"] : 0) as num|null
if(!isnull(target) && !..())
target = CLAMP(target, 0, 50 * ONE_ATMOSPHERE)
var/target = text2num(params["pressure"])
if(!isnull(target))
target = CLAMP(target, 0, MAX_OUTPUT_PRESSURE)
signal.data += list("tag" = output_tag, "set_internal_pressure" = target)
. = TRUE
radio_connection.post_signal(src, signal, filter = RADIO_ATMOSIA)
+1 -1
View File
@@ -482,7 +482,7 @@
R.fields["ckey"] = mob_occupant.ckey
R.fields["name"] = mob_occupant.real_name
R.fields["id"] = copytext(md5(mob_occupant.real_name), 2, 6)
R.fields["id"] = copytext_char(md5(mob_occupant.real_name), 2, 6)
R.fields["UE"] = dna.unique_enzymes
R.fields["UI"] = dna.uni_identity
R.fields["SE"] = dna.struc_enzymes
@@ -443,7 +443,7 @@
var/dat = ""
if(SSshuttle.emergency.mode == SHUTTLE_CALL)
var/timeleft = SSshuttle.emergency.timeLeft()
dat += "<B>Emergency shuttle</B>\n<BR>\nETA: [timeleft / 60 % 60]:[add_zero(num2text(timeleft % 60), 2)]"
dat += "<B>Emergency shuttle</B>\n<BR>\nETA: [timeleft / 60 % 60]:[add_leading(num2text(timeleft % 60), 2, "0")]"
var/datum/browser/popup = new(user, "communications", "Communications Console", 400, 500)
+27 -17
View File
@@ -274,13 +274,18 @@
var/max_line_len = 7*DNA_BLOCK_SIZE
if(viable_occupant)
temp_html += "<div class='dnaBlockNumber'>1</div>"
var/len = length(viable_occupant.dna.uni_identity)
for(var/i=1, i<=len, i++)
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulseui;num=[i];'>[copytext(viable_occupant.dna.uni_identity,i,i+1)]</a>"
if ((i % max_line_len) == 0)
var/char = ""
var/ui_text = viable_occupant.dna.uni_identity
var/len_byte = length(ui_text)
var/char_it = 0
for(var/byte_it = 1, byte_it <= len_byte, byte_it += length(char))
char_it++
char = ui_text[byte_it]
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulseui;num=[char_it];'>[char]</a>"
if((char_it % max_line_len) == 0)
temp_html += "</div><div class='clearBoth'>"
if((i % DNA_BLOCK_SIZE) == 0 && i < len)
temp_html += "<div class='dnaBlockNumber'>[(i / DNA_BLOCK_SIZE) + 1]</div>"
if((char_it % DNA_BLOCK_SIZE) == 0 && byte_it < len_byte)
temp_html += "<div class='dnaBlockNumber'>[(char_it / DNA_BLOCK_SIZE) + 1]</div>"
else
temp_html += "----"
temp_html += "</div></div></div><br>"
@@ -288,13 +293,18 @@
temp_html += "<br><div class='line'><div class='statusLabel'>Structural Enzymes:</div><div class='statusValue'><div class='clearBoth'>"
if(viable_occupant)
temp_html += "<div class='dnaBlockNumber'>1</div>"
var/len = length(viable_occupant.dna.struc_enzymes)
for(var/i=1, i<=len, i++)
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulsese;num=[i];'>[copytext(viable_occupant.dna.struc_enzymes,i,i+1)]</a>"
if ((i % max_line_len) == 0)
var/char = ""
var/se_text = viable_occupant.dna.struc_enzymes
var/len_byte = length(se_text)
var/char_it = 0
for(var/byte_it = 1, byte_it <= len_byte, byte_it += length(char))
char_it++
char = se_text[byte_it]
temp_html += "<a class='dnaBlock' href='?src=[REF(src)];task=pulsese;num=[char_it];'>[char]</a>"
if((char_it % max_line_len) == 0)
temp_html += "</div><div class='clearBoth'>"
if((i % DNA_BLOCK_SIZE) == 0 && i < len)
temp_html += "<div class='dnaBlockNumber'>[(i / DNA_BLOCK_SIZE) + 1]</div>"
if((char_it % DNA_BLOCK_SIZE) == 0 && byte_it < len_byte)
temp_html += "<div class='dnaBlockNumber'>[(char_it / DNA_BLOCK_SIZE) + 1]</div>"
else
temp_html += "----"
temp_html += "</div></div></div>"
@@ -465,7 +475,7 @@
viable_occupant.radiation += (RADIATION_IRRADIATION_MULTIPLIER*radduration*radstrength)/(connected.damage_coeff ** 2) //Read comment in "transferbuffer" section above for explanation
switch(href_list["task"]) //Same thing as there but values are even lower, on best part they are about 0.0*, effectively no damage
if("pulseui")
var/len = length(viable_occupant.dna.uni_identity)
var/len = length_char(viable_occupant.dna.uni_identity)
num = WRAP(num, 1, len+1)
num = randomize_radiation_accuracy(num, radduration + (connected.precision_coeff ** 2), len) //Each manipulator level above 1 makes randomization as accurate as selected time + manipulator lvl^2
//Value is this high for the same reason as with laser - not worth the hassle of upgrading if the bonus is low
@@ -473,12 +483,12 @@
var/subblock = num - block*DNA_BLOCK_SIZE
last_change = "UI #[block]-[subblock]; "
var/hex = copytext(viable_occupant.dna.uni_identity, num, num+1)
var/hex = copytext_char(viable_occupant.dna.uni_identity, num, num+1)
last_change += "[hex]"
hex = scramble(hex, radstrength, radduration)
last_change += "->[hex]"
viable_occupant.dna.uni_identity = copytext(viable_occupant.dna.uni_identity, 1, num) + hex + copytext(viable_occupant.dna.uni_identity, num+1, 0)
viable_occupant.dna.uni_identity = copytext_char(viable_occupant.dna.uni_identity, 1, num) + hex + copytext_char(viable_occupant.dna.uni_identity, num + 1)
viable_occupant.updateappearance(mutations_overlay_update=1)
if("pulsese")
var/len = length(viable_occupant.dna.struc_enzymes)
@@ -489,12 +499,12 @@
var/subblock = num - block*DNA_BLOCK_SIZE
last_change = "SE #[block]-[subblock]; "
var/hex = copytext(viable_occupant.dna.struc_enzymes, num, num+1)
var/hex = copytext_char(viable_occupant.dna.struc_enzymes, num, num+1)
last_change += "[hex]"
hex = scramble(hex, radstrength, radduration)
last_change += "->[hex]"
viable_occupant.dna.struc_enzymes = copytext(viable_occupant.dna.struc_enzymes, 1, num) + hex + copytext(viable_occupant.dna.struc_enzymes, num+1, 0)
viable_occupant.dna.struc_enzymes = copytext_char(viable_occupant.dna.struc_enzymes, 1, num) + hex + copytext_char(viable_occupant.dna.struc_enzymes, num + 1)
viable_occupant.domutcheck()
else
current_screen = "mainmenu"
+85 -112
View File
@@ -1,11 +1,13 @@
/obj/machinery/computer/launchpad
name = "\improper launchpad control console"
name = "launchpad control console"
desc = "Used to teleport objects to and from a launchpad."
icon_screen = "teleport"
icon_keyboard = "teleport_key"
circuit = /obj/item/circuitboard/computer/launchpad_console
var/sending = TRUE
var/current_pad //current pad viewed on the screen
ui_x = 475
ui_y = 260
var/selected_id
var/list/obj/machinery/launchpad/launchpads
var/maximum_pads = 4
@@ -18,7 +20,9 @@
return
/obj/machinery/computer/launchpad/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/multitool))
if(W.tool_behaviour == TOOL_MULTITOOL)
if(!multitool_check_buffer(user, W))
return
var/obj/item/multitool/M = W
if(M.buffer && istype(M.buffer, /obj/machinery/launchpad))
if(LAZYLEN(launchpads) < maximum_pads)
@@ -36,55 +40,7 @@
return FALSE
return TRUE
/obj/machinery/computer/launchpad/proc/get_pad(number)
var/obj/machinery/launchpad/pad = launchpads[number]
return pad
/obj/machinery/computer/launchpad/ui_interact(mob/user)
. = ..()
var/list/t = list()
if(!LAZYLEN(launchpads))
obj_flags &= ~IN_USE //Yeah so if you deconstruct teleporter while its in the process of shooting it wont disable the console
t += "<div class='statusDisplay'>No launchpad located.</div><BR>"
else
for(var/i in 1 to LAZYLEN(launchpads))
if(pad_exists(i))
var/obj/machinery/launchpad/pad = get_pad(i)
if(pad.stat & NOPOWER)
t+= "<span class='linkOff'>[pad.display_name]</span>"
else
t+= "<A href='?src=[REF(src)];choose_pad=1;pad=[i]'>[pad.display_name]</A>"
else
launchpads -= get_pad(i)
t += "<BR>"
if(current_pad)
var/obj/machinery/launchpad/pad = get_pad(current_pad)
t += "<div class='statusDisplay'><b>[pad.display_name]</b></div>"
t += "<A href='?src=[REF(src)];change_name=1;pad=[current_pad]'>Rename</A>"
t += "<A href='?src=[REF(src)];remove=1;pad=[current_pad]'>Remove</A><BR><BR>"
t += "<A href='?src=[REF(src)];raisey=1;lowerx=1;pad=[current_pad]'>O</A>" //up-left
t += "<A href='?src=[REF(src)];raisey=1;pad=[current_pad]'>^</A>" //up
t += "<A href='?src=[REF(src)];raisey=1;raisex=1;pad=[current_pad]'>O</A><BR>" //up-right
t += "<A href='?src=[REF(src)];lowerx=1;pad=[current_pad]'><</A>"//left
t += "<A href='?src=[REF(src)];reset=1;pad=[current_pad]'>R</A>"//reset to 0
t += "<A href='?src=[REF(src)];raisex=1;pad=[current_pad]'>></A><BR>"//right
t += "<A href='?src=[REF(src)];lowery=1;lowerx=1;pad=[current_pad]'>O</A>"//down-left
t += "<A href='?src=[REF(src)];lowery=1;pad=[current_pad]'>v</A>"//down
t += "<A href='?src=[REF(src)];lowery=1;raisex=1;pad=[current_pad]'>O</A><BR>"//down-right
t += "<BR>"
t += "<div class='statusDisplay'>Current offset:</div><BR>"
t += "<div class='statusDisplay'>[abs(pad.y_offset)] [pad.y_offset > 0 ? "N":"S"] <a href='?src=[REF(src)];sety=1;pad=[current_pad]'>\[SET\]</a></div><BR>"
t += "<div class='statusDisplay'>[abs(pad.x_offset)] [pad.x_offset > 0 ? "E":"W"] <a href='?src=[REF(src)];setx=1;pad=[current_pad]'>\[SET\]</a></div><BR>"
t += "<BR><A href='?src=[REF(src)];launch=1;pad=[current_pad]'>Launch</A>"
t += " <A href='?src=[REF(src)];pull=1;pad=[current_pad]'>Pull</A>"
var/datum/browser/popup = new(user, "launchpad", name, 300, 500)
popup.set_content(t.Join())
popup.open()
/obj/machinery/computer/launchpad/proc/teleport(mob/user, obj/machinery/launchpad/pad)
/obj/machinery/computer/launchpad/proc/teleport(mob/user, obj/machinery/launchpad/pad, sending)
if(QDELETED(pad))
to_chat(user, "<span class='warning'>ERROR: Launchpad not responding. Check launchpad integrity.</span>")
return
@@ -93,66 +49,83 @@
return
pad.doteleport(user, sending)
/obj/machinery/computer/launchpad/Topic(href, href_list)
var/obj/machinery/launchpad/pad
if(href_list["pad"])
pad = get_pad(text2num(href_list["pad"]))
/obj/machinery/computer/launchpad/proc/get_pad(number)
var/obj/machinery/launchpad/pad = launchpads[number]
return pad
/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.open()
/obj/machinery/computer/launchpad/ui_data(mob/user)
var/list/data = list()
var/list/pad_list = list()
for(var/i in 1 to LAZYLEN(launchpads))
if(pad_exists(i))
var/obj/machinery/launchpad/pad = get_pad(i)
var/list/this_pad = list()
this_pad["name"] = pad.display_name
this_pad["id"] = i
if(pad.stat & NOPOWER)
this_pad["inactive"] = TRUE
pad_list += list(this_pad)
else
launchpads -= get_pad(i)
data["launchpads"] = pad_list
data["selected_id"] = selected_id
if(selected_id)
var/obj/machinery/launchpad/current_pad = launchpads[selected_id]
data["x"] = current_pad.x_offset
data["y"] = current_pad.y_offset
data["pad_name"] = current_pad.display_name
data["range"] = current_pad.range
data["selected_pad"] = current_pad
if(QDELETED(current_pad) || (current_pad.stat & NOPOWER))
data["pad_active"] = FALSE
return data
data["pad_active"] = TRUE
return data
/obj/machinery/computer/launchpad/ui_act(action, params)
if(..())
return
if(!LAZYLEN(launchpads))
updateDialog()
return
var/obj/machinery/launchpad/current_pad = launchpads[selected_id]
switch(action)
if("select_pad")
selected_id = text2num(params["id"])
. = TRUE
if("set_pos")
var/new_x = text2num(params["x"])
var/new_y = text2num(params["y"])
current_pad.set_offset(new_x, new_y)
. = TRUE
if("move_pos")
var/plus_x = text2num(params["x"])
var/plus_y = text2num(params["y"])
current_pad.set_offset(
x = current_pad.x_offset + plus_x,
y = current_pad.y_offset + plus_y
)
. = TRUE
if("rename")
. = TRUE
var/new_name = params["name"]
if(!new_name)
return
current_pad.display_name = new_name
if("remove")
if(usr && alert(usr, "Are you sure?", "Unlink Launchpad", "I'm Sure", "Abort") != "Abort")
launchpads -= current_pad
selected_id = null
. = TRUE
if("launch")
teleport(usr, current_pad, TRUE)
. = TRUE
if(href_list["choose_pad"])
current_pad = text2num(href_list["pad"])
if(href_list["raisex"])
if(pad.x_offset < pad.range)
pad.x_offset++
if(href_list["lowerx"])
if(pad.x_offset > (pad.range * -1))
pad.x_offset--
if(href_list["raisey"])
if(pad.y_offset < pad.range)
pad.y_offset++
if(href_list["lowery"])
if(pad.y_offset > (pad.range * -1))
pad.y_offset--
if(href_list["reset"])
pad.y_offset = 0
pad.x_offset = 0
if(href_list["change_name"])
var/new_name = stripped_input(usr, "What do you wish to name the launchpad?", "Launchpad", pad.display_name, 15)
if(!new_name)
return
pad.display_name = new_name
if(href_list["setx"])
var/newx = input(usr, "Input new x offset", pad.display_name, pad.x_offset) as null|num
if(!isnull(newx))
pad.x_offset = CLAMP(newx, -pad.range, pad.range)
if(href_list["sety"])
var/newy = input(usr, "Input new y offset", pad.display_name, pad.y_offset) as null|num
if(!isnull(newy))
pad.y_offset = CLAMP(newy, -pad.range, pad.range)
if(href_list["remove"])
if(usr && alert(usr, "Are you sure?", "Remove Launchpad", "I'm Sure", "Abort") != "Abort")
launchpads -= pad
if(href_list["launch"])
sending = TRUE
teleport(usr, pad)
if(href_list["pull"])
sending = FALSE
teleport(usr, pad)
updateDialog()
if("pull")
teleport(usr, current_pad, FALSE)
. = TRUE
. = TRUE
+1 -1
View File
@@ -478,7 +478,7 @@
var/counter = 1
while(active2.fields[text("com_[]", counter)])
counter++
active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []<BR>[]", authenticated, rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []<BR>[]", authenticated, rank, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
else if(href_list["del_c"])
if((istype(active2, /datum/data/record) && active2.fields[text("com_[]", href_list["del_c"])]))
@@ -6,6 +6,9 @@
icon_keyboard = "security_key"
req_access = list(ACCESS_ARMORY)
circuit = /obj/item/circuitboard/computer/gulag_teleporter_console
ui_x = 350
ui_y = 295
var/default_goal = 200
var/obj/machinery/gulag_teleporter/teleporter = null
var/obj/structure/gulag_beacon/beacon = null
@@ -22,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, 455, 440, master_ui, state)
ui = new(user, src, ui_key, "gulag_console", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/prisoner/gulag_teleporter_computer/ui_data(mob/user)
@@ -50,13 +53,19 @@
data["teleporter_location"] = "([teleporter.x], [teleporter.y], [teleporter.z])"
data["teleporter_lock"] = teleporter.locked
data["teleporter_state_open"] = teleporter.state_open
else
data["teleporter"] = null
if(beacon)
data["beacon"] = beacon
data["beacon_location"] = "([beacon.x], [beacon.y], [beacon.z])"
else
data["beacon"] = null
if(contained_id)
data["id"] = contained_id
data["id_name"] = contained_id.registered_name
data["goal"] = contained_id.goal
else
data["id"] = null
data["can_teleport"] = can_teleport
return data
@@ -72,36 +81,41 @@
switch(action)
if("scan_teleporter")
teleporter = findteleporter()
return TRUE
if("scan_beacon")
beacon = findbeacon()
return TRUE
if("handle_id")
if(contained_id)
id_eject(usr)
else
id_insert(usr)
return TRUE
if("set_goal")
var/new_goal = input("Set the amount of points:", "Points", contained_id.goal) as num|null
var/new_goal = text2num(params["value"])
if(!isnum(new_goal))
return
if(!new_goal)
new_goal = default_goal
if (new_goal > 1000)
to_chat(usr, "The entered amount of points is too large. Points have instead been set to the maximum allowed amount.")
contained_id.goal = CLAMP(new_goal, 0, 1000) //maximum 1000 points
return TRUE
if("toggle_open")
if(teleporter.locked)
to_chat(usr, "The teleporter is locked")
to_chat(usr, "<span class='alert'>The teleporter must be unlocked first.</span>")
return
teleporter.toggle_open()
return TRUE
if("teleporter_lock")
if(teleporter.state_open)
to_chat(usr, "Close the teleporter before locking!")
to_chat(usr, "<span class='alert'>The teleporter must be closed first.</span>")
return
teleporter.locked = !teleporter.locked
return TRUE
if("teleport")
if(!teleporter || !beacon)
return
addtimer(CALLBACK(src, .proc/teleport, usr), 5)
return TRUE
/obj/machinery/computer/prisoner/gulag_teleporter_computer/proc/scan_machinery()
teleporter = findteleporter()
@@ -129,12 +143,12 @@
say("[contained_id]'s ID card goal defaulting to [contained_id.goal] points.")
log_game("[key_name(user)] teleported [key_name(prisoner)] to the Labor Camp [COORD(beacon)] for [id_goal_not_set ? "default goal of ":""][contained_id.goal] points.")
teleporter.handle_prisoner(contained_id, temporary_record)
playsound(src, 'sound/weapons/emitter.ogg', 50, 1)
playsound(src, 'sound/weapons/emitter.ogg', 50, TRUE)
prisoner.forceMove(get_turf(beacon))
prisoner.Stun(40) // small travel dizziness
to_chat(prisoner, "<span class='warning'>The teleportation makes you a little dizzy.</span>")
new /obj/effect/particle_effect/sparks(get_turf(prisoner))
playsound(src, "sparks", 50, 1)
playsound(src, "sparks", 50, TRUE)
if(teleporter.locked)
teleporter.locked = FALSE
teleporter.toggle_open()
@@ -125,7 +125,7 @@
to_chat(usr, "<span class='danger'>Unauthorized access.</span>")
else if(href_list["warn"])
var/warning = copytext(sanitize(input(usr,"Message:","Enter your message here!","")),1,MAX_MESSAGE_LEN)
var/warning = stripped_input(usr, "Message:", "Enter your message here!", "", MAX_MESSAGE_LEN)
if(!warning)
return
var/obj/item/implant/I = locate(href_list["warn"]) in GLOB.tracked_implants
+4 -4
View File
@@ -456,7 +456,7 @@ What a mess.*/
var/counter = 1
while(active2.fields[text("com_[]", counter)])
counter++
active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []<BR>[]", src.authenticated, src.rank, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
active2.fields[text("com_[]", counter)] = text("Made by [] ([]) on [] [], []<BR>[]", src.authenticated, src.rank, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
if("Delete Record (ALL)")
if(active1)
@@ -544,7 +544,7 @@ What a mess.*/
switch(href_list["field"])
if("name")
if(istype(active1, /datum/data/record) || istype(active2, /datum/data/record))
var/t1 = copytext(sanitize(input("Please input name:", "Secure. records", active1.fields["name"], null) as text),1,MAX_MESSAGE_LEN)
var/t1 = stripped_input(usr, "Please input name:", "Secure. records", active1.fields["name"], MAX_MESSAGE_LEN)
if(!canUseSecurityRecordsConsole(usr, t1, a1))
return
if(istype(active1, /datum/data/record))
@@ -636,7 +636,7 @@ What a mess.*/
var/t2 = stripped_input(usr, "Please input minor crime details:", "Secure. records", "", null)
if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss"))
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time))
GLOB.data_core.addMinorCrime(active1.fields["id"], crime)
investigate_log("New Minor Crime: <strong>[t1]</strong>: [t2] | Added to [active1.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS)
if("mi_crim_delete")
@@ -651,7 +651,7 @@ What a mess.*/
var/t2 = stripped_input(usr, "Please input major crime details:", "Secure. records", "", null)
if(!canUseSecurityRecordsConsole(usr, t1, null, a2))
return
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss"))
var/crime = GLOB.data_core.createCrimeEntry(t1, t2, authenticated, STATION_TIME_TIMESTAMP("hh:mm:ss", world.time))
GLOB.data_core.addMajorCrime(active1.fields["id"], crime)
investigate_log("New Major Crime: <strong>[t1]</strong>: [t2] | Added to [active1.fields["name"]] by [key_name(usr)]", INVESTIGATE_RECORDS)
if("ma_crim_delete")
@@ -20,17 +20,18 @@
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, 300, 500, master_ui, state)
ui = new(user, src, ui_key, "station_alert", name, 325, 500, master_ui, state)
ui.open()
/obj/machinery/computer/station_alert/ui_data(mob/user)
. = list()
var/list/data = list()
.["alarms"] = list()
data["alarms"] = list()
for(var/class in alarms)
.["alarms"][class] = list()
data["alarms"][class] = list()
for(var/area in alarms[class])
.["alarms"][class] += area
data["alarms"][class] += area
return data
/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source)
if(source.z != z)
@@ -136,7 +136,7 @@ GLOBAL_LIST_INIT(possible_uplinker_IDs, list("Alfa","Bravo","Charlie","Delta","E
var/list/transferlog = list()
/obj/machinery/computer/telecrystals/boss/proc/logTransfer(logmessage)
transferlog += ("<b>[STATION_TIME_TIMESTAMP("hh:mm:ss")]</b> [logmessage]")
transferlog += ("<b>[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]</b> [logmessage]")
/obj/machinery/computer/telecrystals/boss/proc/scanUplinkers()
for(var/obj/machinery/computer/telecrystals/uplinker/A in urange(scanrange, src.loc))
+53 -54
View File
@@ -5,6 +5,8 @@
icon_keyboard = "teleport_key"
light_color = LIGHT_COLOR_BLUE
circuit = /obj/item/circuitboard/computer/teleporter
ui_x = 475
ui_y = 130
var/regime_set = "Teleporter"
var/id
var/obj/machinery/teleport/station/power_station
@@ -32,34 +34,30 @@
break
return power_station
/obj/machinery/computer/teleporter/ui_interact(mob/user)
. = ..()
var/data = "<h3>Teleporter Status</h3>"
if(!power_station)
data += "<div class='statusDisplay'>No power station linked.</div>"
else if(!power_station.teleporter_hub)
data += "<div class='statusDisplay'>No hub linked.</div>"
obj/machinery/computer/teleporter/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, "teleporter", name, ui_x, ui_y, master_ui, state)
ui.open()
/obj/machinery/computer/teleporter/ui_data(mob/user)
var/list/data = list()
data["power_station"] = power_station ? TRUE : FALSE
data["teleporter_hub"] = power_station?.teleporter_hub ? TRUE : FALSE
data["regime_set"] = regime_set
data["target"] = !target ? "None" : "[get_area(target)] [(regime_set != "Gate") ? "" : "Teleporter"]"
data["calibrating"] = calibrating
if(power_station?.teleporter_hub?.calibrated || power_station?.teleporter_hub?.accuracy >= 3)
data["calibrated"] = TRUE
else
data += "<div class='statusDisplay'>Current regime: [regime_set]<BR>"
data += "Current target: [(!target) ? "None" : "[get_area(target)] [(regime_set != "Gate") ? "" : "Teleporter"]"]<BR>"
if(calibrating)
data += "Calibration: <font color='yellow'>In Progress</font>"
else if(power_station.teleporter_hub.calibrated || power_station.efficiency >= 3)
data += "Calibration: <font color='green'>Optimal</font>"
else
data += "Calibration: <font color='red'>Sub-Optimal</font>"
data += "</div><BR>"
data["calibrated"] = FALSE
data += "<A href='?src=[REF(src)];regimeset=1'>Change regime</A><BR>"
data += "<A href='?src=[REF(src)];settarget=1'>Set target</A><BR>"
return data
data += "<BR><A href='?src=[REF(src)];calibrate=1'>Calibrate Hub</A>"
var/datum/browser/popup = new(user, "teleporter", name, 400, 400)
popup.set_content(data)
popup.open()
/obj/machinery/computer/teleporter/Topic(href, href_list)
/obj/machinery/computer/teleporter/ui_act(action, params)
if(..())
return
@@ -70,38 +68,39 @@
say("Error: Calibration in progress. Stand by.")
return
if(href_list["regimeset"])
power_station.engaged = 0
power_station.teleporter_hub.update_icon()
power_station.teleporter_hub.calibrated = 0
reset_regime()
if(href_list["settarget"])
power_station.engaged = 0
power_station.teleporter_hub.update_icon()
power_station.teleporter_hub.calibrated = 0
set_target(usr)
if(href_list["calibrate"])
if(!target)
say("Error: No target set to calibrate to.")
return
if(power_station.teleporter_hub.calibrated || power_station.efficiency >= 3)
say("Hub is already calibrated!")
return
say("Processing hub calibration to target...")
switch(action)
if("regimeset")
power_station.engaged = FALSE
power_station.teleporter_hub.update_icon()
power_station.teleporter_hub.calibrated = FALSE
reset_regime()
. = TRUE
if("settarget")
power_station.engaged = FALSE
power_station.teleporter_hub.update_icon()
power_station.teleporter_hub.calibrated = FALSE
set_target(usr)
. = TRUE
if("calibrate")
if(!target)
say("Error: No target set to calibrate to.")
return
if(power_station.teleporter_hub.calibrated || power_station.teleporter_hub.accuracy >= 3)
say("Hub is already calibrated!")
return
calibrating = 1
power_station.update_icon()
spawn(50 * (3 - power_station.efficiency)) //Better parts mean faster calibration
calibrating = 0
if(check_hub_connection())
power_station.teleporter_hub.calibrated = 1
say("Calibration complete.")
else
say("Error: Unable to detect hub.")
say("Processing hub calibration to target...")
calibrating = TRUE
power_station.update_icon()
updateDialog()
updateDialog()
spawn(50 * (3 - power_station.teleporter_hub.accuracy)) //Better parts mean faster calibration
calibrating = FALSE
if(check_hub_connection())
power_station.teleporter_hub.calibrated = TRUE
say("Calibration complete.")
else
say("Error: Unable to detect hub.")
power_station.update_icon()
. = TRUE
/obj/machinery/computer/teleporter/proc/check_hub_connection()
if(!power_station)
+27 -105
View File
@@ -1434,7 +1434,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, 550, 456, master_ui, state)
ui = new(user, src, ui_key, "ai_airlock", name, 500, 390, master_ui, state)
ui.open()
return TRUE
@@ -1503,83 +1503,24 @@
if("shock-perm")
shock_perm(usr)
. = TRUE
if("idscan-on")
if(wires.is_cut(WIRE_IDSCAN))
to_chat(usr, "You can't enable IdScan - The IdScan wire has been cut.")
else if(src.aiDisabledIdScanner)
aiDisabledIdScanner = FALSE
else
to_chat(usr, "The IdScan feature is not disabled.")
if("idscan-toggle")
aiDisabledIdScanner = !aiDisabledIdScanner
. = TRUE
if("idscan-off")
if(wires.is_cut(WIRE_IDSCAN))
to_chat(usr, "The IdScan wire has been cut - So, you can't disable it, but it is already disabled anyways.")
else if(aiDisabledIdScanner)
to_chat(usr, "You've already disabled the IdScan feature.")
else
aiDisabledIdScanner = TRUE
if("emergency-toggle")
toggle_emergency(usr)
. = TRUE
if("emergency-on")
emergency_on(usr)
if("bolt-toggle")
toggle_bolt(usr)
. = TRUE
if("emergency-off")
emergency_off(usr)
if("light-toggle")
lights = !lights
update_icon()
. = TRUE
if("bolt-raise")
bolt_raise(usr)
if("safe-toggle")
safe = !safe
. = TRUE
if("bolt-drop")
bolt_drop(usr)
. = TRUE
if("light-on")
if(wires.is_cut(WIRE_LIGHT))
to_chat(usr, "Control to door bolt lights has been severed.")
else if (!src.lights)
lights = TRUE
update_icon()
else
to_chat(usr, text("Door bolt lights are already enabled!"))
. = TRUE
if("light-off")
if(wires.is_cut(WIRE_LIGHT))
to_chat(usr, "Control to door bolt lights has been severed.")
else if (lights)
lights = FALSE
update_icon()
else
to_chat(usr, "Door bolt lights are already disabled!")
. = TRUE
if("safe-on")
if(wires.is_cut(WIRE_SAFETY))
to_chat(usr, "Control to door sensors is disabled.")
else if (!src.safe)
safe = TRUE
else
to_chat(usr, "Firmware reports safeties already in place.")
. = TRUE
if("safe-off")
if(wires.is_cut(WIRE_SAFETY))
to_chat(usr, "Control to door sensors is disabled.")
else if (safe)
safe = FALSE
else
to_chat(usr, "Firmware reports safeties already overridden.")
. = TRUE
if("speed-on")
if(wires.is_cut(WIRE_TIMING))
to_chat(usr, "Control to door timing circuitry has been severed.")
else if (!src.normalspeed)
normalspeed = 1
else
to_chat(usr,"Door timing circuitry currently operating normally.")
. = TRUE
if("speed-off")
if(wires.is_cut(WIRE_TIMING))
to_chat(usr, "Control to door timing circuitry has been severed.")
else if (normalspeed)
normalspeed = 0
else
to_chat(usr, "Door timing circuitry already accelerated.")
if("speed-toggle")
normalspeed = !normalspeed
. = TRUE
if("open-close")
@@ -1617,45 +1558,26 @@
log_combat(user, src, "electrified")
set_electrified(ELECTRIFIED_PERMANENT)
/obj/machinery/door/airlock/proc/emergency_on(mob/user)
if(!user_allowed(user))
return
if (!emergency)
emergency = TRUE
update_icon()
else
to_chat(user, "Emergency access is already enabled!")
/obj/machinery/door/airlock/proc/emergency_off(mob/user)
if(!user_allowed(user))
return
if (emergency)
emergency = FALSE
update_icon()
else
to_chat(user, "Emergency access is already disabled!")
/obj/machinery/door/airlock/proc/bolt_raise(mob/user)
/obj/machinery/door/airlock/proc/toggle_bolt(mob/user)
if(!user_allowed(user))
return
if(wires.is_cut(WIRE_BOLTS))
to_chat(user, "The door bolt drop wire is cut - you can't raise the door bolts")
else if(!src.locked)
to_chat(user, "The door bolts are already up")
else
if(src.hasPower())
unbolt()
to_chat(user, "<span class='warning'>The door bolt drop wire is cut - you can't toggle the door bolts.</span>")
return
if(locked)
if(!hasPower())
to_chat(user, "<span class='warning'>The door has no power - you can't raise the door bolts.</span>")
else
to_chat(user, "Cannot raise door bolts due to power failure")
/obj/machinery/door/airlock/proc/bolt_drop(mob/user)
if(!user_allowed(user))
return
if(wires.is_cut(WIRE_BOLTS))
to_chat(user, "You can't drop the door bolts - The door bolt dropping wire has been cut.")
unbolt()
else
bolt()
/obj/machinery/door/airlock/proc/toggle_emergency(mob/user)
if(!user_allowed(user))
return
emergency = !emergency
update_icon()
/obj/machinery/door/airlock/proc/user_toggle_open(mob/user)
if(!user_allowed(user))
return
@@ -14,7 +14,7 @@
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.hands_state)
SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "airlock_electronics", name, 975, 420, master_ui, state)
ui = new(user, src, ui_key, "airlock_electronics", name, 420, 485, master_ui, state)
ui.open()
/obj/item/electronics/airlock/ui_data()
@@ -43,13 +43,16 @@
if(..())
return
switch(action)
if("clear")
if("clear_all")
accesses = list()
one_access = 0
. = TRUE
if("one_access")
one_access = !one_access
. = TRUE
if("grant_all")
accesses = get_all_accesses()
. = TRUE
if("set")
var/access = text2num(params["access"])
if (!(access in accesses))
+2 -2
View File
@@ -149,7 +149,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, 200, master_ui, state)
ui = new(user, src, ui_key, "brig_timer", name, 300, 138, master_ui, state)
ui.open()
//icon update function
@@ -168,7 +168,7 @@
if(timing)
var/disp1 = id
var/time_left = time_left(seconds = TRUE)
var/disp2 = "[add_zero(num2text((time_left / 60) % 60),2)]~[add_zero(num2text(time_left % 60), 2)]"
var/disp2 = "[add_leading(num2text((time_left / 60) % 60), 2, "0")]:[add_leading(num2text(time_left % 60), 2, "0")]"
if(length(disp2) > CHARS_PER_LINE)
disp2 = "Error"
update_display(disp1, disp2)
+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, 455, 440, master_ui, state)
ui = new(user, src, ui_key, "gulag_item_reclaimer", name, 300, 400, master_ui, state)
ui.open()
/obj/machinery/gulag_item_reclaimer/ui_data(mob/user)
+59 -73
View File
@@ -16,6 +16,7 @@
var/power_efficiency = 1
var/x_offset = 0
var/y_offset = 0
var/indicator_icon = "launchpad_target"
/obj/machinery/launchpad/RefreshParts()
var/E = 0
@@ -34,17 +35,28 @@
return
if(panel_open)
if(istype(I, /obj/item/multitool))
if(I.tool_behaviour == TOOL_MULTITOOL)
if(!multitool_check_buffer(user, I))
return
var/obj/item/multitool/M = I
M.buffer = src
to_chat(user, "<span class='notice'>You save the data in the [I.name]'s buffer.</span>")
return 1
return TRUE
if(default_deconstruction_crowbar(I))
return
return ..()
/obj/machinery/launchpad/attack_ghost(mob/dead/observer/ghost)
. = ..()
if(.)
return
var/target_x = x + x_offset
var/target_y = y + y_offset
var/turf/target = locate(target_x, target_y, z)
ghost.forceMove(target)
/obj/machinery/launchpad/proc/isAvailable()
if(stat & NOPOWER)
return FALSE
@@ -52,6 +64,14 @@
return FALSE
return TRUE
/obj/machinery/launchpad/proc/set_offset(x, y)
if(teleporting)
return
if(!isnull(x))
x_offset = CLAMP(x, -range, range)
if(!isnull(y))
y_offset = CLAMP(y, -range, range)
/obj/machinery/launchpad/proc/doteleport(mob/user, sending)
if(teleporting)
to_chat(user, "<span class='warning'>ERROR: Launchpad busy.</span>")
@@ -69,12 +89,22 @@
var/area/A = get_area(target)
flick(icon_teleport, src)
playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, 1)
//Change the indicator's icon to show that we're teleporting
if(sending)
indicator_icon = "launchpad_launch"
else
indicator_icon = "launchpad_pull"
playsound(get_turf(src), 'sound/weapons/flash.ogg', 25, TRUE)
teleporting = TRUE
sleep(teleport_speed)
//Set the indicator icon back to normal
indicator_icon = "launchpad_target"
if(QDELETED(src) || !isAvailable())
return
@@ -91,25 +121,25 @@
source = dest
dest = target
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, 1)
playsound(get_turf(src), 'sound/weapons/emitter2.ogg', 25, TRUE)
var/first = TRUE
for(var/atom/movable/ROI in source)
if(ROI == src)
continue
// if it's anchored, don't teleport
if(!istype(ROI) || isdead(ROI) || iscameramob(ROI) || istype(ROI, /obj/effect/dummy/phased_mob))
continue//don't teleport these
var/on_chair = ""
if(ROI.anchored)
if(ROI.anchored)// if it's anchored, don't teleport
if(isliving(ROI))
var/mob/living/L = ROI
if(L.buckled)
// TP people on office chairs
if(L.buckled.anchored)
continue
on_chair = " (on a chair)"
else
continue
else if(!isobserver(ROI))
else
continue
if(!first)
log_msg += ", "
@@ -158,11 +188,11 @@
var/obj/item/storage/briefcase/launchpad/briefcase
/obj/machinery/launchpad/briefcase/Initialize(mapload, briefcase)
. = ..()
if(!briefcase)
log_game("[src] has been spawned without a briefcase.")
return INITIALIZE_HINT_QDEL
src.briefcase = briefcase
. = ..()
if(!briefcase)
log_game("[src] has been spawned without a briefcase.")
return INITIALIZE_HINT_QDEL
src.briefcase = briefcase
/obj/machinery/launchpad/briefcase/Destroy()
QDEL_NULL(briefcase)
@@ -255,7 +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", 550, 400, master_ui, state) //width, height
ui = new(user, src, ui_key, "launchpad_remote", "Briefcase Launchpad Remote", 300, 240, master_ui, state) //width, height
ui.set_style("syndicate")
ui.open()
@@ -270,10 +300,9 @@
return data
data["pad_name"] = pad.display_name
data["abs_x"] = abs(pad.x_offset)
data["abs_y"] = abs(pad.y_offset)
data["north_south"] = pad.y_offset > 0 ? "N":"S"
data["east_west"] = pad.x_offset > 0 ? "E":"W"
data["range"] = pad.range
data["x"] = pad.x_offset
data["y"] = pad.y_offset
return data
/obj/item/launchpad_remote/proc/teleport(mob/user, obj/machinery/launchpad/pad)
@@ -289,76 +318,33 @@
if(..())
return
switch(action)
if("right")
if(pad.x_offset < pad.range)
pad.x_offset++
if("set_pos")
var/new_x = text2num(params["x"])
var/new_y = text2num(params["y"])
pad.set_offset(new_x, new_y)
. = TRUE
if("left")
if(pad.x_offset > (pad.range * -1))
pad.x_offset--
if("move_pos")
var/plus_x = text2num(params["x"])
var/plus_y = text2num(params["y"])
pad.set_offset(
x = pad.x_offset + plus_x,
y = pad.y_offset + plus_y
)
. = TRUE
if("up")
if(pad.y_offset < pad.range)
pad.y_offset++
. = TRUE
if("down")
if(pad.y_offset > (pad.range * -1))
pad.y_offset--
. = TRUE
if("up-right")
if(pad.y_offset < pad.range)
pad.y_offset++
if(pad.x_offset < pad.range)
pad.x_offset++
. = TRUE
if("up-left")
if(pad.y_offset < pad.range)
pad.y_offset++
if(pad.x_offset > (pad.range * -1))
pad.x_offset--
. = TRUE
if("down-right")
if(pad.y_offset > (pad.range * -1))
pad.y_offset--
if(pad.x_offset < pad.range)
pad.x_offset++
. = TRUE
if("down-left")
if(pad.y_offset > (pad.range * -1))
pad.y_offset--
if(pad.x_offset > (pad.range * -1))
pad.x_offset--
. = TRUE
if("reset")
pad.y_offset = 0
pad.x_offset = 0
. = TRUE
if("rename")
. = TRUE
var/new_name = stripped_input(usr, "How do you want to rename the launchpad?", "Launchpad", pad.display_name, 15)
var/new_name = params["name"]
if(!new_name)
return
pad.display_name = new_name
if("remove")
. = TRUE
if(usr && alert(usr, "Are you sure?", "Unlink Launchpad", "I'm Sure", "Abort") != "Abort")
pad = null
if("launch")
sending = TRUE
teleport(usr, pad)
. = TRUE
if("pull")
sending = FALSE
teleport(usr, pad)
+13 -7
View File
@@ -306,7 +306,7 @@
if(speed <= 0)
speed = 1
if("setpath")
var/newpath = copytext(sanitize(input(usr, "Please define a new path!",,path) as text|null),1,MAX_MESSAGE_LEN)
var/newpath = stripped_input(usr, "Please define a new path!", "New Path", path, MAX_MESSAGE_LEN)
if(newpath && newpath != "")
moving = 0 // stop moving
path = newpath
@@ -368,13 +368,19 @@
// Generates the rpath variable using the path string, think of this as "string2list"
// Doesn't use params2list() because of the akward way it stacks entities
rpath = list() // clear rpath
var/maximum_character = min( 50, length(path) ) // chooses the maximum length of the iterator. 50 max length
var/maximum_characters = 50
for(var/i=1, i<=maximum_character, i++) // iterates through all characters in path
var/lentext = length(path)
var/nextchar = ""
var/charcount = 0
var/nextchar = copytext(path, i, i+1) // find next character
if(!(nextchar in list(";", "&", "*", " "))) // if char is a separator, ignore
rpath += copytext(path, i, i+1) // else, add to list
for(var/i = 1, i <= lentext, i += length(nextchar)) // iterates through all characters in path
nextchar = path[i] // find next character
if(nextchar in list(";", "&", "*", " ")) // if char is a separator, ignore
continue
rpath += nextchar // else, add to list
// there doesn't HAVE to be separators but it makes paths syntatically visible
charcount++
if(charcount >= maximum_characters)
break
+2 -2
View File
@@ -62,7 +62,7 @@
var/index = findtext(e, "=") // format is "key=value"
if(index)
var/key = copytext(e, 1, index)
var/val = copytext(e, index+1)
var/val = copytext(e, index + length(e[index]))
codes[key] = val
else
codes[e] = "1"
@@ -167,7 +167,7 @@ Transponder Codes:<UL>"}
usr.set_machine(src)
if(href_list["locedit"])
var/newloc = copytext(sanitize(input("Enter New Location", "Navigation Beacon", location) as text|null),1,MAX_MESSAGE_LEN)
var/newloc = stripped_input(usr, "Enter New Location", "Navigation Beacon", location, MAX_MESSAGE_LEN)
if(newloc)
location = newloc
updateDialog()
+4 -6
View File
@@ -122,7 +122,7 @@ GLOBAL_LIST_EMPTY(allCasters)
var/datum/newscaster/feed_message/newMsg = new /datum/newscaster/feed_message
newMsg.author = author
newMsg.body = msg
newMsg.time_stamp = "[STATION_TIME_TIMESTAMP("hh:mm:ss")]"
newMsg.time_stamp = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)
newMsg.is_admin_message = adminMessage
newMsg.locked = !allow_comments
if(picture)
@@ -162,7 +162,7 @@ GLOBAL_LIST_EMPTY(allCasters)
NEWSCASTER.update_icon()
/datum/newscaster/feed_network/proc/save_photo(icon/photo)
var/photo_file = copytext(md5("\icon[photo]"), 1, 6)
var/photo_file = copytext_char(md5("\icon[photo]"), 1, 6)
if(!fexists("[GLOB.log_directory]/photos/[photo_file].png"))
//Clean up repeated frames
var/icon/clean = new /icon()
@@ -514,8 +514,6 @@ GLOBAL_LIST_EMPTY(allCasters)
scan_user(usr)
if(href_list["set_channel_name"])
channel_name = stripped_input(usr, "Provide a Feed Channel Name", "Network Channel Handler", "", MAX_NAME_LEN)
while (findtext(channel_name," ") == 1)
channel_name = copytext(channel_name,2,length(channel_name)+1)
updateUsrDialog()
else if(href_list["set_channel_lock"])
c_locked = !c_locked
@@ -690,13 +688,13 @@ GLOBAL_LIST_EMPTY(allCasters)
updateUsrDialog()
else if(href_list["new_comment"])
var/datum/newscaster/feed_message/FM = locate(href_list["new_comment"])
var/cominput = copytext(stripped_input(usr, "Write your message:", "New comment", null),1,141)
var/cominput = copytext_char(stripped_input(usr, "Write your message:", "New comment", null), 140)
if(cominput)
scan_user(usr)
var/datum/newscaster/feed_comment/FC = new/datum/newscaster/feed_comment
FC.author = scanned_user
FC.body = cominput
FC.time_stamp = STATION_TIME_TIMESTAMP("hh:mm:ss")
FC.time_stamp = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)
FM.comments += FC
usr.log_message("(as [scanned_user]) commented on message [FM.returnBody(-1)] -- [FC.body]", LOG_COMMENT)
updateUsrDialog()
+6 -8
View File
@@ -263,10 +263,9 @@ GLOBAL_LIST_EMPTY(allConsoles)
usr.set_machine(src)
add_fingerprint(usr)
if(reject_bad_text(href_list["write"]))
dpt = ckey(href_list["write"]) //write contains the string of the receiving department's name
var/new_message = copytext(reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")),1,MAX_MESSAGE_LEN)
if(href_list["write"])
dpt = ckey(reject_bad_text(href_list["write"])) //write contains the string of the receiving department's name
var/new_message = stripped_input(usr, "Write your message:", "Awaiting Input", "", MAX_MESSAGE_LEN)
if(new_message)
message = new_message
screen = 9
@@ -282,7 +281,7 @@ GLOBAL_LIST_EMPTY(allConsoles)
priority = -1
if(href_list["writeAnnouncement"])
var/new_message = copytext(reject_bad_text(input(usr, "Write your message:", "Awaiting Input", "")),1,MAX_MESSAGE_LEN)
var/new_message = reject_bad_text(stripped_input(usr, "Write your message:", "Awaiting Input", "", MAX_MESSAGE_LEN))
if(new_message)
message = new_message
if (text2num(href_list["priority"]) < 2)
@@ -438,9 +437,8 @@ GLOBAL_LIST_EMPTY(allConsoles)
return
/obj/machinery/requests_console/say_mod(input, message_mode)
var/ending = copytext(input, length(input) - 2)
if (ending == "!!!")
. = "blares"
if(spantext_char(input, "!", -3))
return "blares"
else
. = ..()
+11 -11
View File
@@ -55,14 +55,14 @@
/// Call with no arguments to disable.
/obj/machinery/status_display/proc/set_message(m1, m2)
if(m1)
index1 = (length(m1) > CHARS_PER_LINE)
index1 = (length_char(m1) > CHARS_PER_LINE)
message1 = m1
else
message1 = ""
index1 = 0
if(m2)
index2 = (length(m2) > CHARS_PER_LINE)
index2 = (length_char(m2) > CHARS_PER_LINE)
message2 = m2
else
message2 = ""
@@ -77,19 +77,19 @@
var/line1 = message1
if(index1)
line1 = copytext("[message1]|[message1]", index1, index1+CHARS_PER_LINE)
var/message1_len = length(message1)
line1 = copytext_char("[message1]|[message1]", index1, index1+CHARS_PER_LINE)
var/message1_len = length_char(message1)
index1 += SCROLL_SPEED
if(index1 > message1_len)
index1 -= message1_len
if(index1 > message1_len + 1)
index1 -= (message1_len + 1)
var/line2 = message2
if(index2)
line2 = copytext("[message2]|[message2]", index2, index2+CHARS_PER_LINE)
line2 = copytext_char("[message2]|[message2]", index2, index2+CHARS_PER_LINE)
var/message2_len = length(message2)
index2 += SCROLL_SPEED
if(index2 > message2_len)
index2 -= message2_len
if(index2 > message2_len + 1)
index2 -= (message2_len + 1)
update_display(line1, line2)
if (!index1 && !index2)
@@ -130,7 +130,7 @@
var/line1 = "-[shuttle.getModeStr()]-"
var/line2 = shuttle.getTimerStr()
if(length(line2) > CHARS_PER_LINE)
if(length_char(line2) > CHARS_PER_LINE)
line2 = "error"
update_display(line1, line2)
else
@@ -242,7 +242,7 @@
else
line1 = "CARGO"
line2 = SSshuttle.supply.getTimerStr()
if(length(line2) > CHARS_PER_LINE)
if(length_char(line2) > CHARS_PER_LINE)
line2 = "Error"
update_display(line1, line2)
+12 -2
View File
@@ -266,7 +266,7 @@
for(var/atom/movable/AM in things_to_clear) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
SEND_SIGNAL(AM, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRONG)
AM.clean_blood()
AM.fingerprints = list()
AM.fingerprints = null
var/datum/component/radioactive/contamination = AM.GetComponent(/datum/component/radioactive)
if(contamination)
qdel(contamination)
@@ -390,14 +390,24 @@
data["uv_super"] = uv_super
if(helmet)
data["helmet"] = helmet.name
else
data["helmet"] = null
if(suit)
data["suit"] = suit.name
else
data["suit"] = null
if(mask)
data["mask"] = mask.name
else
data["mask"] = null
if(storage)
data["storage"] = storage.name
else
data["storage"] = null
if(occupant)
data["occupied"] = 1
data["occupied"] = TRUE
else
data["occupied"] = FALSE
return data
/obj/machinery/suit_storage_unit/ui_act(action, params)
@@ -132,7 +132,7 @@
set waitfor = FALSE
// Perform final composition steps on the message.
var/message = copytext(data["message"], 1, MAX_BROADCAST_LEN)
var/message = copytext_char(data["message"], 1, MAX_BROADCAST_LEN)
if(!message)
return
var/compression = data["compression"]
@@ -179,7 +179,7 @@
if("id")
var/newid = copytext(reject_bad_text(input(usr, "Specify the new ID for this machine", src, id) as null|text),1,MAX_MESSAGE_LEN)
var/newid = reject_bad_text(stripped_input(usr, "Specify the new ID for this machine", src, id, MAX_MESSAGE_LEN))
if(newid && canAccess(usr))
id = newid
temp = "<font color = #666633>-% New ID assigned: \"[id]\" %-</font color>"
+2 -2
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, 170, master_ui, state)
ui = new(user, src, ui_key, "mech_bay_power_console", "Mech Bay Power Control Console", 400, 200, master_ui, state)
ui.open()
/obj/machinery/computer/mech_bay_power_console/ui_act(action, params)
@@ -101,7 +101,7 @@
if(recharge_port && !QDELETED(recharge_port))
data["recharge_port"] = list("mech" = null)
if(recharge_port.recharging_mech && !QDELETED(recharge_port.recharging_mech))
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "maxhealth" = recharge_port.recharging_mech.max_integrity, "cell" = null)
data["recharge_port"]["mech"] = list("health" = recharge_port.recharging_mech.obj_integrity, "maxhealth" = recharge_port.recharging_mech.max_integrity, "cell" = null, "name" = recharge_port.recharging_mech.name,)
if(recharge_port.recharging_mech.cell && !QDELETED(recharge_port.recharging_mech.cell))
data["recharge_port"]["mech"]["cell"] = list(
"critfail" = recharge_port.recharging_mech.cell.crit_fail,
+1 -1
View File
@@ -416,7 +416,7 @@
return ..()
/obj/machinery/mecha_part_fabricator/proc/material2name(ID)
return copytext(ID,2)
return copytext_char(ID,2)
/obj/machinery/mecha_part_fabricator/proc/is_insertion_ready(mob/user)
if(panel_open)
+1 -1
View File
@@ -1030,7 +1030,7 @@
/obj/mecha/log_message(message as text, message_type=LOG_GAME, color=null, log_globally)
log.len++
log[log.len] = list("time"="[STATION_TIME_TIMESTAMP("hh:mm:ss")]","date","year"="[GLOB.year_integer]","message"="[color?"<font color='[color]'>":null][message][color?"</font>":null]")
log[log.len] = list("time"="[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]","date","year"="[GLOB.year_integer]","message"="[color?"<font color='[color]'>":null][message][color?"</font>":null]")
..()
return log.len
+5 -5
View File
@@ -294,11 +294,11 @@
onclose(occupant, "exosuit_log")
if (href_list["change_name"])
var/newname = stripped_input(occupant,"Choose new exosuit name","Rename exosuit","", MAX_NAME_LEN)
if(newname && trim(newname))
name = newname
else
alert(occupant, "nope.avi")
var/userinput = stripped_input(occupant,"Choose new exosuit name","Rename exosuit","", MAX_NAME_LEN)
if(!userinput || usr != occupant || usr.incapacitated())
return
name = userinput
return
if (href_list["toggle_id_upload"])
add_req_access = !add_req_access
+1 -1
View File
@@ -128,7 +128,7 @@
if (smooth & SMOOTH_DIAGONAL)
for (var/O in overlays)
var/image/I = O
if (copytext(I.icon_state, 1, 3) == "d-")
if(copytext(I.icon_state, 1, 3) == "d-") //3 == length("d-") + 1
return
var/stuff_on_wall = 0
@@ -29,13 +29,19 @@
var/list/diseases = list()
SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
var/direction = pick(directions)
for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
sleep(2)
if(i > 0)
var/dist = 0
if(prob(50)) //yes this and the one below are different for a reason.
if(prob(25))
dist = 2
else
dist = 1
if(dist)
for(var/i in 1 to dist)
sleep(2)
var/obj/effect/decal/cleanable/blood/splatter/xeno/splat = new /obj/effect/decal/cleanable/blood/splatter/xeno(loc, diseases)
splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
if(!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/xeno/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
@@ -5,6 +5,7 @@
layer = LOW_OBJ_LAYER
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6")
mergeable_decal = FALSE
bloodiness = 0 //This isn't supposed to be bloody.
var/body_colors = "#e3ba84" //a default color just in case.
var/gibs_reagent_id = /datum/reagent/liquidgibs
var/gibs_bloodtype = "A+"
@@ -19,7 +20,6 @@
add_blood_DNA(list("Non-human DNA" = gibs_bloodtype, diseases))
update_icon()
/obj/effect/decal/cleanable/blood/gibs/update_icon()
add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY)
cut_overlays()
@@ -44,13 +44,18 @@
var/list/diseases = list()
SEND_SIGNAL(src, COMSIG_GIBS_STREAK, directions, diseases)
var/direction = pick(directions)
for(var/i in 0 to pick(0, 200; 1, 150; 2, 50))
sleep(2)
if(i > 0)
var/dist = 0
if(prob(50)) //yes this and the one below are different for a reason.
if(prob(25))
dist = 2
else
dist = 1
if(dist)
for(var/i in 1 to dist)
var/obj/effect/decal/cleanable/blood/splatter/splat = new /obj/effect/decal/cleanable/blood/splatter(loc, diseases)
splat.transfer_blood_dna(blood_DNA, diseases)
if(!step_to(src, get_step(src, direction), 0))
break
if(!step_to(src, get_step(src, direction), 0))
break
/obj/effect/decal/cleanable/blood/gibs/up
random_icon_states = list("gib1", "gib2", "gib3", "gib4", "gib5", "gib6","gibup1","gibup1","gibup1")
@@ -5,12 +5,12 @@
icon_state = "floor1"
random_icon_states = list("floor1", "floor2", "floor3", "floor4", "floor5", "floor6", "floor7")
blood_state = BLOOD_STATE_BLOOD
bloodiness = MAX_SHOE_BLOODINESS
bloodiness = BLOOD_AMOUNT_PER_DECAL
color = BLOOD_COLOR_HUMAN //default so we don't have white splotches everywhere.
/obj/effect/decal/cleanable/blood/replace_decal(obj/effect/decal/cleanable/blood/C)
if (C.blood_DNA)
blood_DNA |= C.blood_DNA.Copy()
blood_DNA |= C.blood_DNA
update_icon()
..()
+21
View File
@@ -273,6 +273,27 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player)
GLOB.newplayer_start += loc
return INITIALIZE_HINT_QDEL
/obj/effect/landmark/start/nuclear_equipment
name = "bomb or clown beacon spawner"
var/nukie_path = /obj/item/sbeacondrop/bomb
var/clown_path = /obj/item/sbeacondrop/clownbomb
/obj/effect/landmark/start/nuclear_equipment/after_round_start()
var/npath = nukie_path
if(istype(SSticker.mode, /datum/game_mode/nuclear/clown_ops))
npath = clown_path
else if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/D = SSticker.mode
if(locate(/datum/dynamic_ruleset/roundstart/nuclear/clown_ops) in D.current_rules)
npath = clown_path
new npath(loc)
return ..()
/obj/effect/landmark/start/nuclear_equipment/minibomb
name = "minibomb or bombanana spawner"
nukie_path = /obj/item/storage/box/minibombs
clown_path = /obj/item/storage/box/bombananas
/obj/effect/landmark/latejoin
name = "JoinLate"
+1 -1
View File
@@ -109,4 +109,4 @@
/obj/effect/abstract/proximity_checker/Crossed(atom/movable/AM)
set waitfor = FALSE
monitor.hasprox_receiver.HasProximity(AM)
monitor?.hasprox_receiver.HasProximity(AM)
+3 -4
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, 515, master_ui, state)
ui = new(user, src, ui_key, "rpd", name, 425, 472, master_ui, state)
ui.open()
/obj/item/pipe_dispenser/ui_data(mob/user)
@@ -316,9 +316,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
playeffect = FALSE
if("mode")
var/n = text2num(params["mode"])
if(n == 2 && !(mode&1) && !(mode&2))
mode |= 3
else if(mode&n)
if(mode & n)
mode &= ~n
else
mode |= n
@@ -327,6 +325,7 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
spark_system.start()
effectcooldown = world.time + 100
playsound(get_turf(src), 'sound/effects/pop.ogg', 50, 0)
return TRUE
/obj/item/pipe_dispenser/pre_attack(atom/A, mob/user)
var/turf/T = get_turf(A)
+3 -6
View File
@@ -269,14 +269,11 @@ update_label("John Doe", "Clowny")
if(isliving(user) && user.mind)
if(user.mind.special_role || anyone)
if(alert(user, "Action", "Agent ID", "Show", "Forge") == "Forge")
var/t = copytext(sanitize(input(user, "What name would you like to put on this card?", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name))as text | null),1,26)
if(!t || t == "Unknown" || t == "floor" || t == "wall" || t == "r-wall") //Same as mob/dead/new_player/prefrences.dm
if (t)
alert("Invalid name.")
var/input_name = reject_bad_name(stripped_input(user, "What name would you like to put on this card?", "Agent card name", registered_name ? registered_name : (ishuman(user) ? user.real_name : user.name), MAX_NAME_LEN), TRUE)
if(!input_name)
return
registered_name = t
var/u = copytext(sanitize(input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant")as text | null),1,MAX_MESSAGE_LEN)
var/u = stripped_input(user, "What occupation would you like to put on this card?\nNote: This will not grant any access levels other than Maintenance.", "Agent card job assignment", "Assistant", MAX_MESSAGE_LEN)
if(!u)
registered_name = ""
return
+1 -1
View File
@@ -407,7 +407,7 @@
to_chat(user, "<span class='notice'>You spray a [temp] on \the [target.name]</span>")
if(length(text_buffer) > 1)
text_buffer = copytext(text_buffer,2)
text_buffer = copytext(text_buffer, length(text_buffer[1]) + 1)
SStgui.update_uis(src)
if(post_noise)
+3 -3
View File
@@ -292,7 +292,7 @@ GLOBAL_LIST_EMPTY(PDAs)
dat += text("ID: <a href='?src=[REF(src)];choice=Authenticate'>[id ? "[id.registered_name], [id.assignment]" : "----------"]")
dat += text("<br><a href='?src=[REF(src)];choice=UpdateInfo'>[id ? "Update PDA Info" : ""]</A><br><br>")
dat += "[STATION_TIME_TIMESTAMP("hh:mm:ss")]<br>" //:[world.time / 100 % 6][world.time / 100 % 10]"
dat += "[STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]<br>" //:[world.time / 100 % 6][world.time / 100 % 10]"
dat += "[time2text(world.realtime, "MMM DD")] [GLOB.year_integer]"
dat += "<br><br>"
@@ -641,13 +641,13 @@ GLOBAL_LIST_EMPTY(PDAs)
if("Clear")//Clears messages
tnote = null
if("Ringtone")
var/t = input(U, "Please enter new ringtone", name, ttone) as text
var/t = stripped_input(U, "Please enter new ringtone", name, ttone, 20)
if(in_range(src, U) && loc == U && t)
if(SEND_SIGNAL(src, COMSIG_PDA_CHANGE_RINGTONE, U, t) & COMPONENT_STOP_RINGTONE_CHANGE)
U << browse(null, "window=pda")
return
else
ttone = copytext(sanitize(t), 1, 20)
ttone = t
else
U << browse(null, "window=pda")
return
+7 -2
View File
@@ -309,9 +309,14 @@ Code:
var/list/S = list(" Off","AOff"," On", " AOn")
var/list/chg = list("N","C","F")
//Neither copytext nor copytext_char is appropriate here; neither 30 UTF-8 code units nor 30 code points equates to 30 columns of output.
//Some glyphs are very tall or very wide while others are small or even take up no space at all.
//Emojis can take modifiers which are many characters but render as only one glyph.
//A proper solution here (as far as Unicode goes, maybe not ideal as far as markup goes, a table would be better)
//would be to use <span style="width: NNNpx; overflow: none;">[A.area.name]</span>
for(var/obj/machinery/power/apc/A in L)
menu += copytext(add_tspace(A.area.name, 30), 1, 30)
menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_lspace(DisplayPower(A.lastused_total), 6)] [A.cell ? "[add_lspace(round(A.cell.percent()), 3)]% [chg[A.charging+1]]" : " N/C"]<BR>"
menu += copytext_char(add_trailing(A.area.name, 30, " "), 1, 30)
menu += " [S[A.equipment+1]] [S[A.lighting+1]] [S[A.environ+1]] [add_leading(DisplayPower(A.lastused_total), 6, " ")] [A.cell ? "[add_leading(round(A.cell.percent()), 3, " ")]% [chg[A.charging+1]]" : " N/C"]<BR>"
menu += "</FONT></PRE>"
+7 -9
View File
@@ -73,8 +73,10 @@ GLOBAL_LIST_EMPTY(GPS_list)
return
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
var/gps_window_height = 300 + GLOB.GPS_list.len * 20 // Variable window height, depending on how many GPS units there are to show
ui = new(user, src, ui_key, "gps", "Global Positioning System", 600, gps_window_height, master_ui, state) //width, height
// 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.open()
ui.set_autoupdate(state = updating)
@@ -91,6 +93,8 @@ GLOBAL_LIST_EMPTY(GPS_list)
var/turf/curr = get_turf(src)
data["current"] = "[get_area_name(curr, TRUE)] ([curr.x], [curr.y], [curr.z])"
data["currentArea"] = "[get_area_name(curr, TRUE)]"
data["currentCoords"] = "[curr.x], [curr.y], [curr.z]"
var/list/signals = list()
data["signals"] = list()
@@ -104,16 +108,10 @@ GLOBAL_LIST_EMPTY(GPS_list)
continue
var/list/signal = list()
signal["entrytag"] = G.gpstag //Name or 'tag' of the GPS
signal["area"] = get_area_name(G, TRUE)
signal["coord"] = "[pos.x], [pos.y], [pos.z]"
signal["coords"] = "[pos.x], [pos.y], [pos.z]"
if(pos.z == curr.z) //Distance/Direction calculations for same z-level only
signal["dist"] = max(get_dist(curr, pos), 0) //Distance between the src and remote GPS turfs
signal["degrees"] = round(Get_Angle(curr, pos)) //0-360 degree directional bearing, for more precision.
var/direction = uppertext(dir2text(get_dir(curr, pos))) //Direction text (East, etc). Not as precise, but still helpful.
if(!direction)
direction = "CENTER"
signal["degrees"] = "N/A"
signal["direction"] = direction
signals += list(signal) //Add this signal to the list of signals
data["signals"] = signals
+1 -1
View File
@@ -101,7 +101,7 @@
if(href_list["reset_radio_short"])
pai.unshort_radio()
if(href_list["setlaws"])
var/newlaws = copytext(sanitize(input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", pai.laws.supplied[1]) as message),1,MAX_MESSAGE_LEN)
var/newlaws = stripped_multiline_input("Enter any additional directives you would like your pAI personality to follow. Note that these directives will not override the personality's allegiance to its imprinted master. Conflicting directives will be ignored.", "pAI Directive Configuration", MAX_MESSAGE_LEN)
if(newlaws && pai)
pai.add_supplied_law(0,newlaws)
if(href_list["toggle_holo"])
@@ -61,7 +61,7 @@
var/mob/living/carbon/C = usr
if(usr.stat || usr.restrained() || C.back == src)
return
if(!usr.canUseTopic(src, BE_CLOSE))
usr << browse(null, "window=radio")
onclose(usr, "radio")
@@ -127,7 +127,7 @@
/obj/item/electropack/ui_interact(mob/user)
if(!ishuman(user))
return
user.set_machine(src)
var/dat = {"
<TT>
@@ -200,14 +200,14 @@ Code:
/obj/item/electropack/shockcollar/attackby(obj/item/W, mob/user, params) //moves it here because on_click is being bad
if(istype(W, /obj/item/pen))
var/t = input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot") as null|text
var/t = stripped_input(user, "Would you like to change the name on the tag?", "Name your new pet", tagname ? tagname : "Spot", MAX_NAME_LEN)
if(t)
tagname = copytext(sanitize(t), 1, MAX_NAME_LEN)
name = "[initial(name)] - [tagname]"
tagname = t
name = "[initial(name)] - [t]"
else
return ..()
/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this
/obj/item/electropack/shockcollar/ui_interact(mob/user) //on_click calls this
var/dat = {"
<TT>
<B>Frequency/Code</B> for shock collar:<BR>
@@ -112,7 +112,14 @@
. = ..()
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
ui = new(user, src, ui_key, "radio", name, 370, 220 + channels.len * 22, master_ui, state)
var/ui_width = 360
var/ui_height = 106
if(subspace_transmission)
if(channels.len > 0)
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.open()
/obj/item/radio/ui_data(mob/user)
+5 -7
View File
@@ -28,7 +28,7 @@ SLIME SCANNER
/obj/item/t_scanner/attack_self(mob/user)
on = !on
icon_state = copytext(icon_state, 1, length(icon_state))+"[on]"
icon_state = copytext_char(icon_state, 1, -1) + "[on]"
if(on)
START_PROCESSING(SSobj, src)
@@ -407,19 +407,17 @@ SLIME SCANNER
// Blood Level
if(M.has_dna())
var/mob/living/carbon/C = M
var/blood_id = C.get_blood_id()
if(blood_id)
var/blood_typepath = C.get_blood_id()
if(blood_typepath)
if(ishuman(C))
if(H.bleed_rate)
msg += "<span class='danger'>Subject is bleeding!</span>\n"
var/blood_percent = round((C.scan_blood_volume() / (BLOOD_VOLUME_NORMAL * C.blood_ratio))*100)
var/blood_type = C.dna.blood_type
if(blood_id != ("blood" || "jellyblood"))//special blood substance
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id]
if(!(blood_typepath in GLOB.blood_reagent_types))
var/datum/reagent/R = GLOB.chemical_reagents_list[blood_typepath]
if(R)
blood_type = R.name
else
blood_type = blood_id
if(C.scan_blood_volume() <= (BLOOD_VOLUME_SAFE*C.blood_ratio) && C.scan_blood_volume() > (BLOOD_VOLUME_OKAY*C.blood_ratio))
msg += "<span class='danger'>LOW blood level [blood_percent] %, [C.scan_blood_volume()] cl,</span> <span class='info'>type: [blood_type]</span>\n"
else if(C.scan_blood_volume() <= (BLOOD_VOLUME_OKAY*C.blood_ratio))
+66 -47
View File
@@ -54,7 +54,7 @@
to_chat(user, "<span class='warning'>[src] was shaken recently, it needs time to settle.</span>")
return
user.visible_message("<span class='notice'>[user] starts shaking [src].</span>", "<span class='notice'>You start shaking [src].</span>", "<span class='italics'>You hear shaking and sloshing.</span>")
user.visible_message("<span class='notice'>[user] starts shaking [src].</span>", "<span class='notice'>You start shaking [src].</span>", "<span class='hear'>You hear shaking and sloshing.</span>")
shaking = TRUE
@@ -95,16 +95,47 @@
// except it actually ASKS THE DEAD (wooooo)
/obj/item/toy/eightball/haunted
shake_time = 150
cooldown_time = 1800
shake_time = 30 SECONDS
cooldown_time = 3 MINUTES
flags_1 = HEAR_1
var/last_message
var/selected_message
var/list/votes
//these kind of store the same thing but one is easier to work with.
var/list/votes = list()
var/list/voted = list()
var/static/list/haunted_answers = list(
"yes" = list(
"It is certain",
"It is decidedly so",
"Without a doubt",
"Yes definitely",
"You may rely on it",
"As I see it, yes",
"Most likely",
"Outlook good",
"Yes",
"Signs point to yes"
),
"maybe" = list(
"Reply hazy try again",
"Ask again later",
"Better not tell you now",
"Cannot predict now",
"Concentrate and ask again"
),
"no" = list(
"Don't count on it",
"My reply is no",
"My sources say no",
"Outlook not so good",
"Very doubtful"
)
)
/obj/item/toy/eightball/haunted/Initialize(mapload)
. = ..()
votes = list()
for (var/answer in haunted_answers)
votes[answer] = 0
GLOB.poi_list |= src
/obj/item/toy/eightball/haunted/Destroy()
@@ -122,7 +153,7 @@
interact(user)
return ..()
/obj/item/toy/eightball/haunted/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode, atom/movable/source)
/obj/item/toy/eightball/haunted/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, spans, message_mode)
. = ..()
last_message = raw_message
@@ -137,38 +168,31 @@
if(isobserver(usr))
interact(usr)
/obj/item/toy/eightball/haunted/proc/get_vote_tallies()
var/list/answers = list()
for(var/ckey in votes)
var/selected = votes[ckey]
if(selected in answers)
answers[selected]++
else
answers[selected] = 1
return answers
/obj/item/toy/eightball/haunted/get_answer()
if(!votes.len)
return pick(possible_answers)
var/top_amount = 0
var/top_vote
var/list/tallied_votes = get_vote_tallies()
for(var/vote in votes)
var/amount_of_votes = length(votes[vote])
if(amount_of_votes > top_amount)
top_vote = vote
top_amount = amount_of_votes
//If one option actually has votes and there's a tie, pick between them 50/50
else if(top_amount && amount_of_votes == top_amount && prob(50))
top_vote = vote
top_amount = amount_of_votes
// I miss python sorting, then I wouldn't have to muck about with
// all this
var/most_popular_answer
var/most_amount = 0
// yes, if there is a tie, there is an arbitary decision
// but we never said the spirit world was fair
for(var/A in tallied_votes)
var/amount = tallied_votes[A]
if(amount > most_amount)
most_popular_answer = A
if(isnull(top_vote))
top_vote = pick(votes)
return most_popular_answer
for(var/vote in votes)
votes[vote] = 0
/obj/item/toy/eightball/haunted/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state = GLOB.observer_state)
voted.Cut()
return top_vote
/obj/item/toy/eightball/haunted/ui_interact(mob/user, ui_key="main", datum/tgui/ui=null, force_open=0, datum/tgui/master_ui=null, datum/ui_state/state = GLOB.always_state)
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
if(!ui)
@@ -179,21 +203,13 @@
var/list/data = list()
data["shaking"] = shaking
data["question"] = selected_message
var/list/tallied_votes = get_vote_tallies()
data["answers"] = list()
for(var/pa in possible_answers)
for(var/pa in haunted_answers)
var/list/L = list()
L["answer"] = pa
var/amount = 0
if(pa in tallied_votes)
amount = tallied_votes[pa]
L["amount"] = amount
var/selected = FALSE
if(votes[user.ckey] == pa)
selected = TRUE
L["selected"] = selected
L["amount"] = votes[pa]
L["selected"] = voted[user.ckey]
data["answers"] += list(L)
return data
@@ -206,8 +222,11 @@
switch(action)
if("vote")
var/selected_answer = params["answer"]
if(!(selected_answer in possible_answers))
if(!(selected_answer in haunted_answers))
return
if(user.ckey in voted)
return
else
votes[user.ckey] = selected_answer
. = TRUE
votes[selected_answer] += 1
voted[user.ckey] = selected_answer
. = TRUE
+3 -3
View File
@@ -34,12 +34,12 @@
/obj/item/grenade/proc/clown_check(mob/living/carbon/human/user)
var/clumsy = HAS_TRAIT(user, TRAIT_CLUMSY)
if(clumsy && (clumsy_check == GRENADE_CLUMSY_FUMBLE))
if(prob(50))
if(clumsy)
if(clumsy_check == GRENADE_CLUMSY_FUMBLE && prob(50))
to_chat(user, "<span class='warning'>Huh? How does this thing work?</span>")
preprime(user, 5, FALSE)
return FALSE
else if(!clumsy && (clumsy_check == GRENADE_NONCLUMSY_FUMBLE))
else if(clumsy_check == GRENADE_NONCLUMSY_FUMBLE && !(user.mind && HAS_TRAIT(user.mind, TRAIT_CLOWN_MENTALITY)))
to_chat(user, "<span class='warning'>You pull the pin on [src]. Attached to it is a pink ribbon that says, \"<span class='clown'>HONK</span>\"</span>")
preprime(user, 5, FALSE)
return FALSE
@@ -92,6 +92,14 @@
creation_time = 0
max_signs = 3
/obj/item/holosign_creator/combifan
name = "ATMOS holo-combifan projector"
desc = "A holographic projector that creates holographic combi-fans that prevent changes in atmosphere and temperature conditions. Somehow."
icon_state = "signmaker_atmos"
holosign_type = /obj/structure/holosign/barrier/combifan
creation_time = 0
max_signs = 3
/obj/item/holosign_creator/medical
name = "\improper PENLITE barrier projector"
desc = "A holographic projector that creates PENLITE holobarriers. Useful during quarantines since they halt those with malicious diseases."
+4 -3
View File
@@ -72,20 +72,21 @@
display_names += list(initial(A.name) = A)
var/choice = input(M,"What holy armor kit would you like to order?","Holy Armor Theme") as null|anything in display_names
if(QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || GLOB.holy_armor_type)
var/turf/T = get_turf(M)
if(!T || QDELETED(src) || !choice || M.stat || !in_range(M, src) || M.restrained() || !M.canmove || GLOB.holy_armor_type)
return
var/index = display_names.Find(choice)
var/A = holy_armor_list[index]
GLOB.holy_armor_type = A
var/holy_armor_box = new A
var/holy_armor_box = new A(T)
SSblackbox.record_feedback("tally", "chaplain_armor", 1, "[choice]")
if(holy_armor_box)
qdel(src)
M.put_in_active_hand(holy_armor_box)///YOU COMPILED
M.put_in_hands(holy_armor_box)
/obj/item/storage/box/holy
name = "Templar Kit"
@@ -77,7 +77,10 @@
return TRUE
if (user.get_active_held_item())
return
object.attack_ai(imp_in)
if (user.CanReach(object))
object.attack_robot(imp_in)
else
object.attack_ai(imp_in)
return TRUE
/obj/item/implant/hijack/proc/hijack_remotely(obj/machinery/power/apc/apc)
@@ -87,6 +90,9 @@
if (!do_after(imp_in, 4 SECONDS,target=apc))
to_chat(imp_in, "<span class='warning'>Aborting.</span>")
return TRUE
if (LAZYLEN(imp_in.siliconaccessareas) >= HIJACK_APC_MAX_AMOUNT)
to_chat(src,"<span class='warning'>You are connected to too many APCs! Too many more will fry your brain.</span>")
return TRUE
imp_in.light_power = 2
imp_in.light_range = 2
imp_in.light_color = COLOR_YELLOW
@@ -99,7 +105,7 @@
apc.set_hijacked_lighting()
imp_in.toggleSiliconAccessArea(apc.area)
apc.update_icon()
stealthcooldown = world.time + 3 MINUTES
stealthcooldown = world.time + 1 MINUTES + 30 SECONDS
toggle_eyes()
else
to_chat(imp_in, "<span class='warning'>Aborting.</span>")
@@ -154,6 +154,7 @@ GLOBAL_LIST_INIT(metal_recipes, list ( \
GLOBAL_LIST_INIT(plasteel_recipes, list ( \
new/datum/stack_recipe("AI core", /obj/structure/AIcore, 4, time = 50, one_per_turf = TRUE), \
new/datum/stack_recipe("bomb assembly", /obj/machinery/syndicatebomb/empty, 10, time = 50), \
new/datum/stack_recipe("crate", /obj/structure/closet/crate, 5, time = 90, one_per_turf = TRUE), \
null, \
new /datum/stack_recipe_list("airlock assemblies", list( \
new/datum/stack_recipe("high security airlock assembly", /obj/structure/door_assembly/door_assembly_highsecurity, 6, time = 50, one_per_turf = 1, on_floor = 1), \
+8 -5
View File
@@ -399,11 +399,14 @@
. = ..()
/obj/item/stack/proc/copy_evidences(obj/item/stack/from)
blood_DNA = from.blood_DNA
fingerprints = from.fingerprints
fingerprintshidden = from.fingerprintshidden
fingerprintslast = from.fingerprintslast
//TODO bloody overlay
if(from.blood_DNA)
blood_DNA = from.blood_DNA.Copy()
if(from.fingerprints)
fingerprints = from.fingerprints.Copy()
if(from.fingerprintshidden)
fingerprintshidden = from.fingerprintshidden.Copy()
if(from.fingerprintslast)
fingerprintslast = from.fingerprintslast
/obj/item/stack/microwave_act(obj/machinery/microwave/M)
if(istype(M) && M.dirty < 100)
+21 -1
View File
@@ -322,6 +322,26 @@
for(var/i in 1 to 5)
new /obj/item/grenade/empgrenade(src)
/obj/item/storage/box/minibombs
name = "box of syndicate minibombs"
desc = "A box containing 2 highly explosive syndicate minibombs."
icon_state = "syndiebox"
illustration = "frag"
/obj/item/storage/box/minibombs/PopulateContents()
new /obj/item/grenade/syndieminibomb(src)
new /obj/item/grenade/syndieminibomb(src)
/obj/item/storage/box/bombananas
name = "box of bombananas"
desc = "A box containing 2 highly explosive bombananas. Discard peel at enemy after consumption."
icon_state = "syndiebox"
illustration = "frag"
/obj/item/storage/box/bombananas/PopulateContents()
new /obj/item/reagent_containers/food/snacks/grown/banana/bombanana(src)
new /obj/item/reagent_containers/food/snacks/grown/banana/bombanana(src)
/obj/item/storage/box/trackimp
name = "boxed tracking implant kit"
desc = "Box full of scum-bag tracking utensils."
@@ -1267,4 +1287,4 @@
/obj/item/storage/box/marshmallow/PopulateContents()
for (var/i in 1 to 5)
new /obj/item/reagent_containers/food/snacks/marshmallow(src)
new /obj/item/reagent_containers/food/snacks/marshmallow(src)
+31
View File
@@ -12,6 +12,7 @@
* Cigarette Box
* Cigar Case
* Heart Shaped Box w/ Chocolates
* Ring Box
*/
/obj/item/storage/fancy
@@ -352,3 +353,33 @@
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 8
STR.can_hold = typecacheof(list(/obj/item/reagent_containers/food/snacks/tinychocolate))
/*
* Ring Box
*/
/obj/item/storage/fancy/ringbox
name = "ring box"
desc = "A tiny box covered in soft red felt made for holding rings."
icon = 'icons/obj/ring.dmi'
icon_state = "gold ringbox"
icon_type = "gold ring"
w_class = WEIGHT_CLASS_TINY
spawn_type = /obj/item/clothing/gloves/ring
/obj/item/storage/fancy/ringbox/ComponentInitialize()
. = ..()
var/datum/component/storage/STR = GetComponent(/datum/component/storage)
STR.max_items = 1
STR.can_hold = typecacheof(list(/obj/item/clothing/gloves/ring))
/obj/item/storage/fancy/ringbox/diamond
icon_state = "diamond ringbox"
icon_type = "diamond ring"
spawn_type = /obj/item/clothing/gloves/ring/diamond
/obj/item/storage/fancy/ringbox/silver
icon_state = "silver ringbox"
icon_type = "silver ring"
spawn_type = /obj/item/clothing/gloves/ring/silver
+2 -6
View File
@@ -35,7 +35,7 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
/obj/item/storage/toolbox/update_icon()
..()
cut_overlays()
if(blood_DNA && blood_DNA.len)
if(length(blood_DNA))
add_blood_overlay()
if(has_latches)
var/icon/I = icon('icons/obj/storage.dmi', latches)
@@ -251,16 +251,12 @@ GLOBAL_LIST_EMPTY(rubber_toolbox_icons)
new /obj/item/ammo_box/a762(src)
new /obj/item/ammo_box/a762(src)
/obj/item/storage/toolbox/gold_real
/obj/item/storage/toolbox/plastitanium/gold_real
name = "golden toolbox"
desc = "A larger then normal toolbox made of gold plated plastitanium."
icon_state = "gold"
item_state = "toolbox_gold"
has_latches = FALSE
force = 16 // Less then a spear
throwforce = 14
throw_speed = 5
throw_range = 10
/obj/item/storage/toolbox/gold_real/PopulateContents()
new /obj/item/screwdriver/nuke(src)
+1 -1
View File
@@ -156,7 +156,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, 420, 200, master_ui, state)
ui = new(user, src, ui_key, "tanks", name, 400, 120, master_ui, state)
ui.open()
/obj/item/tank/ui_data(mob/user)
+1 -1
View File
@@ -1244,7 +1244,7 @@
/obj/item/toy/clockwork_watch/examine(mob/user)
. = ..()
. += "<span class='info'>Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss")]"
. += "<span class='info'>Station Time: [STATION_TIME_TIMESTAMP("hh:mm:ss", world.time)]"
/*
* Toy Dagger
+2 -3
View File
@@ -38,9 +38,9 @@
wielded = 0
if(!isnull(force_unwielded))
force = force_unwielded
var/sf = findtext(name," (Wielded)")
var/sf = findtext(name, " (Wielded)", -10)//10 == length(" (Wielded)")
if(sf)
name = copytext(name,1,sf)
name = copytext(name, 1, sf)
else //something wrong
name = "[initial(name)]"
update_icon()
@@ -347,7 +347,6 @@
icon_state = "dualsaber[item_color][wielded]"
else
icon_state = "dualsaber0"
clean_blood()
/obj/item/twohanded/dualsaber/attack(mob/target, mob/living/carbon/human/user)
+2 -2
View File
@@ -60,8 +60,8 @@
var/flagslist = splittext(set_obj_flags,";")
var/list/string_to_objflag = GLOB.bitfields["obj_flags"]
for (var/flag in flagslist)
if (findtext(flag,"!",1,2))
flag = copytext(flag,1-(length(flag))) // Get all but the initial !
if(flag[1] == "!")
flag = copytext(flag, length(flag[1]) + 1) // Get all but the initial !
obj_flags &= ~string_to_objflag[flag]
else
obj_flags |= string_to_objflag[flag]
@@ -126,8 +126,10 @@
new /obj/item/clothing/mask/bandana/black(src)
if(prob(40))
new /obj/item/clothing/under/assistantformal(src)
new /obj/item/clothing/suit/hooded/wintercoat/aformal(src)
if(prob(40))
new /obj/item/clothing/under/assistantformal(src)
new /obj/item/clothing/suit/hooded/wintercoat/aformal(src)
if(prob(30))
new /obj/item/clothing/suit/hooded/wintercoat(src)
new /obj/item/clothing/shoes/winterboots(src)
@@ -169,4 +171,6 @@
if(prob(30))
new /obj/item/clothing/suit/hooded/wintercoat(src)
new /obj/item/clothing/shoes/winterboots(src)
if (prob(30))
new /obj/item/clothing/suit/hooded/wintercoat/polychromic(src)
return
@@ -13,6 +13,8 @@
climb_time = 10 //real fast, because let's be honest stepping into or onto a crate is easy
climb_stun = 0 //climbing onto crates isn't hard, guys
delivery_icon = "deliverycrate"
material_drop = /obj/item/stack/sheet/plasteel
material_drop_amount = 5
var/obj/item/paper/fluff/jobs/cargo/manifest/manifest
/obj/structure/closet/crate/New()
@@ -142,6 +144,9 @@
new /obj/item/reagent_containers/blood/OMinus(src)
new /obj/item/reagent_containers/blood/OPlus(src)
new /obj/item/reagent_containers/blood/lizard(src)
new /obj/item/reagent_containers/blood/jellyblood(src)
new /obj/item/reagent_containers/blood/insect(src)
new /obj/item/reagent_containers/blood/synthetics(src)
for(var/i in 1 to 3)
new /obj/item/reagent_containers/blood/random(src)
@@ -12,9 +12,11 @@
roundstart = FALSE
death = FALSE
mob_species = /datum/species/pod
flavour_text = "<span class='big bold'>You are a sentient ecosystem,</span><b> an example of the mastery over life that your creators possessed. Your masters, benevolent as they were, created uncounted \
seed vaults and spread them across the universe to every planet they could chart. You are in one such seed vault. Your goal is to cultivate and spread life wherever it will go while waiting \
for contact from your creators. Estimated time of last contact: Deployment, 5x10^3 millennia ago.</b>"
short_desc = "You are a sentient ecosystem, an example of the mastery over life that your creators possessed."
flavour_text = "Your masters, benevolent as they were, created uncounted seed vaults and spread them across \
the universe to every planet they could chart. You are in one such seed vault. \
Your goal is to cultivate and spread life wherever it will go while waiting for contact from your creators. \
Estimated time of last contact: Deployment, 5000 millennia ago."
assignedrole = "Lifebringer"
/obj/effect/mob_spawn/human/seed_vault/special(mob/living/new_spawn)
@@ -48,8 +50,10 @@
anchored = FALSE
move_resist = MOVE_FORCE_NORMAL
density = FALSE
flavour_text = "<span class='big bold'>You are an ash walker.</span><b> Your tribe worships <span class='danger'>the Necropolis</span>. The wastes are sacred ground, its monsters a blessed bounty. You would never leave its beautiful expanse. \
You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. Fresh sacrifices for your nest.</b>"
short_desc = "You are an ash walker. Your tribe worships the Necropolis."
flavour_text = "The wastes are sacred ground, its monsters a blessed bounty. You would never leave its sacred ground. \
You have seen lights in the distance... they foreshadow the arrival of outsiders that seek to tear apart the Necropolis and its domain. \
Fresh sacrifices for your nest."
assignedrole = "Ash Walker"
/obj/effect/mob_spawn/human/ash_walker/special(mob/living/new_spawn)
@@ -88,8 +92,9 @@
roundstart = FALSE
death = FALSE
mob_species = /datum/species/shadow
flavour_text = "<span class='big bold'>You are cursed.</span><b> Years ago, you sacrificed the lives of your trusted friends and the humanity of yourself to reach the Wish Granter. Though you \
did so, it has come at a cost: your very body rejects the light, dooming you to wander endlessly in this horrible wasteland.</b>"
short_desc = "You are cursed."
flavour_text = "Years ago, you sacrificed the lives of your trusted friends and the humanity of yourself to reach the Wish Granter. Though you \
did so, it has come at a cost: your very body rejects the light, dooming you to wander endlessly in this horrible wasteland."
assignedrole = "Exile"
/obj/effect/mob_spawn/human/exile/Destroy()
@@ -126,9 +131,10 @@
var/has_owner = FALSE
var/can_transfer = TRUE //if golems can switch bodies to this new shell
var/mob/living/owner = null //golem's owner if it has one
flavour_text = "<span class='big bold'>You are a Free Golem.</span><b> Your family worships <span class='danger'>The Liberator</span>. In his infinite and divine wisdom, he set your clan free to \
short_desc = "You are a Free Golem. Your family worships The Liberator."
flavour_text = "In his infinite and divine wisdom, he set your clan free to \
travel the stars with a single declaration: \"Yeah go do whatever.\" Though you are bound to the one who created you, it is customary in your society to repeat those same words to newborn \
golems, so that no golem may ever be forced to serve again.</b>"
golems, so that no golem may ever be forced to serve again."
/obj/effect/mob_spawn/human/golem/Initialize(mapload, datum/species/golem/species = null, mob/creator = null)
if(species) //spawners list uses object name to register so this goes before ..()
@@ -139,8 +145,9 @@
if(!mapload && A)
notify_ghosts("\A [initial(species.prefix)] golem shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_GOLEM, ignore_dnr_observers = TRUE)
if(has_owner && creator)
flavour_text = "<span class='big bold'>You are a Golem.</span><b> You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools. \
Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost.</b>"
short_desc = "You are a golem."
flavour_text = "You move slowly, but are highly resistant to heat and cold as well as blunt trauma. You are unable to wear clothes, but can still use most tools."
important_info = "Serve [creator], and assist [creator.p_them()] in completing [creator.p_their()] goals at any cost."
owner = creator
/obj/effect/mob_spawn/human/golem/special(mob/living/new_spawn, name)
@@ -213,8 +220,9 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You've been stranded in this godless prison of a planet for longer than you can remember.</span><b> Each day you barely scrape by, and between the terrible \
conditions of your makeshift shelter, the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \
short_desc = "You've been stranded in this godless prison of a planet for longer than you can remember."
flavour_text = "Each day you barely scrape by, and between the terrible conditions of your makeshift shelter, \
the hostile creatures, and the ash drakes swooping down from the cloudless skies, all you can wish for is the feel of soft grass between your toes and \
the fresh air of Earth. These thoughts are dispelled by yet another recollection of how you got here... "
assignedrole = "Hermit"
@@ -225,20 +233,20 @@
if(1)
flavour_text += "you were a [pick("arms dealer", "shipwright", "docking manager")]'s assistant on a small trading station several sectors from here. Raiders attacked, and there was \
only one pod left when you got to the escape bay. You took it and launched it alone, and the crowd of terrified faces crowding at the airlock door as your pod's engines burst to \
life and sent you to this hell are forever branded into your memory.</b>"
life and sent you to this hell are forever branded into your memory."
outfit.uniform = /obj/item/clothing/under/assistantformal
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
outfit.back = /obj/item/storage/backpack
if(2)
flavour_text += "you're an exile from the Tiger Cooperative. Their technological fanaticism drove you to question the power and beliefs of the Exolitics, and they saw you as a \
heretic and subjected you to hours of horrible torture. You were hours away from execution when a high-ranking friend of yours in the Cooperative managed to secure you a pod, \
scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since.</b>"
scrambled its destination's coordinates, and launched it. You awoke from stasis when you landed and have been surviving - barely - ever since."
outfit.uniform = /obj/item/clothing/under/rank/prisoner
outfit.shoes = /obj/item/clothing/shoes/sneakers/orange
outfit.back = /obj/item/storage/backpack
if(3)
flavour_text += "you were a doctor on one of Nanotrasen's space stations, but you left behind that damn corporation's tyranny and everything it stood for. From a metaphorical hell \
to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there.</b>"
to a literal one, you find yourself nonetheless missing the recycled air and warm floors of what you left behind... but you'd still rather be here than there."
outfit.uniform = /obj/item/clothing/under/rank/medical
outfit.suit = /obj/item/clothing/suit/toggle/labcoat
outfit.back = /obj/item/storage/backpack/medic
@@ -246,7 +254,7 @@
if(4)
flavour_text += "you were always joked about by your friends for \"not playing with a full deck\", as they so <i>kindly</i> put it. It seems that they were right when you, on a tour \
at one of Nanotrasen's state-of-the-art research facilities, were in one of the escape pods alone and saw the red button. It was big and shiny, and it caught your eye. You pressed \
it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now.</b>"
it, and after a terrifying and fast ride for days, you landed here. You've had time to wisen up since then, and you think that your old friends wouldn't be laughing now."
outfit.uniform = /obj/item/clothing/under/color/grey/glorf
outfit.shoes = /obj/item/clothing/shoes/sneakers/black
outfit.back = /obj/item/storage/backpack
@@ -264,9 +272,10 @@
desc = "A small sleeper typically used to instantly restore minor wounds. This one seems broken, and its occupant is comatose."
job_description = "Lavaland Veterinarian"
mob_name = "a translocated vet"
flavour_text = "<span class='big bold'>What...?</span><b> Where are you? Where are the others? This is still the animal hospital - you should know, you've been an intern here for weeks - but \
everyone's gone. One of the cats scratched you just a few minutes ago. That's why you were in the pod - to heal the scratch. The scabs are still fresh; you see them right now. So where is \
everyone? Where did they go? What happened to the hospital? And is that <i>smoke</i> you smell? You need to find someone else. Maybe they can tell you what happened.</b>"
short_desc = "You are a animal doctor who just woke up in lavaland"
flavour_text = "What...? Where are you? Where are the others? This is still the animal hospital - you should know, you've been an intern here for weeks - but \
you see them right now. So where is \
everyone? Where did they go? What happened to the hospital? And is that <i>smoke</i> you smell? You need to find someone else. Maybe they c everyone's gone. One of the cats scratched you just a few minutes ago. That's why you were in the pod - to heal the scratch. The scabs are still fresh; an tell you what happened."
assignedrole = "Translocated Vet"
/obj/effect/mob_spawn/human/doctor/alive/lavaland/Destroy()
@@ -285,8 +294,9 @@
outfit = /datum/outfit/lavalandprisoner
roundstart = FALSE
death = FALSE
flavour_text = "<b>Good. It seems as though your ship crashed. <span class='big bold'>You're a prisoner,</span> sentenced to hard work in one of Nanotrasen's labor camps, but it seems as \
though fate has other plans for you. You remember that you were convicted of "
short_desc = "You're a prisoner, sentenced to hard work in one of Nanotrasen's labor camps, but it seems as \
though fate has other plans for you."
flavour_text = "Good. It seems as though your ship crashed. You remember that you were convicted of "
assignedrole = "Escaped Prisoner"
/obj/effect/mob_spawn/human/prisoner_transport/special(mob/living/L)
@@ -298,7 +308,7 @@
var/list/crimes = list("murder", "larceny", "embezzlement", "unionization", "dereliction of duty", "kidnapping", "gross incompetence", "grand theft", "collaboration with the Syndicate", \
"worship of a forbidden deity", "interspecies relations", "mutiny")
flavour_text += "[pick(crimes)]. but regardless of that, it seems like your crime doesn't matter now. You don't know where you are, but you know that it's out to kill you, and you're not going \
to lose this opportunity. Find a way to get out of this mess and back to where you rightfully belong - your [pick("house", "apartment", "spaceship", "station")]</b>."
to lose this opportunity. Find a way to get out of this mess and back to where you rightfully belong - your [pick("house", "apartment", "spaceship", "station")]."
/datum/outfit/lavalandprisoner
name = "Lavaland Prisoner"
@@ -325,8 +335,9 @@
roundstart = FALSE
random = TRUE
outfit = /datum/outfit/hotelstaff
flavour_text = "<span class='big bold'>You are a staff member of a top-of-the-line space hotel!</span><b> Cater to guests and <font size=6><b>DON'T</b></font> leave the hotel, lest the manager fire you for\
dereliction of duty!</b>"
short_desc = "You are a staff member of a top-of-the-line space hotel!"
flavour_text = "You are a staff member of a top-of-the-line space hotel! Cater to guests and make sure the manager doesn't fire you."
important_info = "DON'T leave the hotel"
assignedrole = "Hotel Staff"
/datum/outfit/hotelstaff
@@ -343,8 +354,10 @@
mob_name = "hotel security member"
job_description = "Hotel Security"
outfit = /datum/outfit/hotelstaff/security
flavour_text = "<span class='big bold'>You are a peacekeeper</span><b> assigned to this hotel to protect the interests of the company while keeping the peace between \
guests and the staff. Do <font size=6>NOT</font> leave the hotel, as that is grounds for contract termination.</b>"
short_desc = "You are a peacekeeper."
flavour_text = "You have been assigned to this hotel to protect the interests of the company while keeping the peace between \
guests and the staff."
important_info = "Do NOT leave the hotel, as that is grounds for contract termination."
objectives = "Do not leave your assigned hotel. Try and keep the peace between staff and guests, non-lethal force heavily advised if possible."
/datum/outfit/hotelstaff/security
@@ -383,7 +396,8 @@
/obj/effect/mob_spawn/human/demonic_friend/Initialize(mapload, datum/mind/owner_mind, obj/effect/proc_holder/spell/targeted/summon_friend/summoning_spell)
. = ..()
owner = owner_mind
flavour_text = "<span class='big bold'>You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil.</span><b> Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell.</b>"
flavour_text = "You have been given a reprieve from your eternity of torment, to be [owner.name]'s friend for [owner.p_their()] short mortal coil."
important_info = "Be aware that if you do not live up to [owner.name]'s expectations, they can send you back to hell with a single thought. [owner.name]'s death will also return you to hell."
var/area/A = get_area(src)
if(!mapload && A)
notify_ghosts("\A friendship shell has been completed in \the [A.name].", source = src, action=NOTIFY_ATTACK, flashwindow = FALSE, ignore_dnr_observers = TRUE)
@@ -441,9 +455,9 @@
/obj/effect/mob_spawn/human/syndicate/battlecruiser
name = "Syndicate Battlecruiser Ship Operative"
flavour_text = "<span class='big bold'>You are a crewmember aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to follow your captain's orders, maintain the ship, and keep the engine running.</b></span> If you are not familiar with how the supermatter engine functions: <b>do not attempt to start it.</b><br>\
<br>\
<span class='danger'><b>The armory is not a candy store, and your role is not to assault the station directly, leave that work to the assault operatives.</b></span></font>"
short_desc = "You are a crewmember aboard the syndicate flagship: the SBC Starfury."
flavour_text = "Your job is to follow your captain's orders, maintain the ship, and keep the engine running. If you are not familiar with how the supermatter engine functions: do not attempt to start it."
important_info = "The armory is not a candy store, and your role is not to assault the station directly, leave that work to the assault operatives."
outfit = /datum/outfit/syndicate_empty/SBC
/datum/outfit/syndicate_empty/SBC
@@ -453,10 +467,9 @@
belt = /obj/item/storage/belt/military/assault
/obj/effect/mob_spawn/human/syndicate/battlecruiser/assault
name = "Syndicate Battlecruiser Assault Operative"
flavour_text = "<span class='big bold'>You are an assault operative aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to follow your captain's orders, keep intruders out of the ship, and assault Space Station 13.</b></span> There is an armory, multiple assault ships, and beam cannons to attack the station with.<br>\
<br>\
<span class='danger'><b>Work as a team with your fellow operatives and work out a plan of attack. If you are overwhelmed, escape back to your ship!</b></span></span>"
short_desc = "You are an assault operative aboard the syndicate flagship: the SBC Starfury."
flavour_text = "Your job is to follow your captain's orders, keep intruders out of the ship, and assault Space Station 13. There is an armory, multiple assault ships, and beam cannons to attack the station with."
important_info = "Work as a team with your fellow operatives and work out a plan of attack. If you are overwhelmed, escape back to your ship!"
outfit = /datum/outfit/syndicate_empty/SBC/assault
/datum/outfit/syndicate_empty/SBC/assault
@@ -472,9 +485,9 @@
/obj/effect/mob_spawn/human/syndicate/battlecruiser/captain
name = "Syndicate Battlecruiser Captain"
flavour_text = "<span class='big bold'>You are the captain aboard the syndicate flagship: the SBC Starfury.</span><span class='big'> <span class='danger'><b>Your job is to oversee your crew, defend the ship, and destroy Space Station 13.</b></span> The ship has an armory, multiple ships, beam cannons, and multiple crewmembers to accomplish this goal.<br>\
<br>\
<span class='danger'><b>As the captain, this whole operation falls on your shoulders.</b></span> You do not need to nuke the station, causing sufficient damage and preventing your ship from being destroyed will be enough.</span>"
short_desc = "You are the captain aboard the syndicate flagship: the SBC Starfury."
flavour_text = "Your job is to oversee your crew, defend the ship, and destroy Space Station 13. The ship has an armory, multiple ships, beam cannons, and multiple crewmembers to accomplish this goal."
important_info = "As the captain, this whole operation falls on your shoulders. You do not need to nuke the station, causing sufficient damage and preventing your ship from being destroyed will be enough."
outfit = /datum/outfit/syndicate_empty/SBC/assault/captain
id_access_list = list(150,151)
@@ -500,10 +513,11 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are a security officer working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
short_desc = "You are a security officer working for Nanotrasen, stationed onboard a state of the art research station."
flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. \
The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod."
important_info = "Work as a team with your fellow survivors and do not abandon them."
uniform = /obj/item/clothing/under/rank/security
shoes = /obj/item/clothing/shoes/jackboots
id = /obj/item/card/id/away/old/sec
@@ -527,10 +541,11 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are an engineer working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
short_desc = "You are an engineer working for Nanotrasen, stationed onboard a state of the art research station."
flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. The last thing \
you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod."
important_info = "Work as a team with your fellow survivors and do not abandon them."
uniform = /obj/item/clothing/under/rank/engineer
shoes = /obj/item/clothing/shoes/workboots
id = /obj/item/card/id/away/old/eng
@@ -552,10 +567,11 @@
death = FALSE
random = TRUE
mob_species = /datum/species/human
flavour_text = "<span class='big bold'>You are a scientist working for Nanotrasen,</span><b> stationed onboard a state of the art research station. You vaguely recall rushing into a \
cryogenics pod due to an oncoming radiation storm. The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod. \
Work as a team with your fellow survivors and do not abandon them.</b>"
short_desc = "You are a scientist working for Nanotrasen, stationed onboard a state of the art research station."
flavour_text = "You vaguely recall rushing into a cryogenics pod due to an oncoming radiation storm. \
The last thing you remember is the station's Artificial Program telling you that you would only be asleep for eight hours. As you open \
your eyes, everything seems rusted and broken, a dark feeling swells in your gut as you climb out of your pod."
important_info = "Work as a team with your fellow survivors and do not abandon them."
uniform = /obj/item/clothing/under/rank/scientist
shoes = /obj/item/clothing/shoes/laceup
id = /obj/item/card/id/away/old/sci
@@ -582,7 +598,8 @@
anchored = TRUE
density = FALSE
show_flavour = FALSE //Flavour only exists for spawners menu
flavour_text = "<span class='big bold'>You are a space pirate.</span><b> The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot.</b>"
short_desc = "You are a space pirate."
flavour_text = "The station refused to pay for your protection, protect the ship, siphon the credits from the station and raid it for even more loot."
assignedrole = "Space Pirate"
var/rank = "Mate"
@@ -617,7 +634,8 @@
density = FALSE
death = FALSE
assignedrole = "Ghost Cafe Visitor"
flavour_text = "Is this what life after death is like?"
short_desc = "You are a Ghost Cafe Visitor!"
flavour_text = "You know one thing for sure. You arent actually alive. Are you in a simulation?"
skip_reentry_check = TRUE
banType = ROLE_GHOSTCAFE
+18
View File
@@ -93,6 +93,24 @@
/obj/structure/holosign/barrier/firelock/blocksTemperature()
return TRUE
/obj/structure/holosign/barrier/combifan
name = "holo combifan"
desc = "A holographic barrier resembling a blue-accented tiny fan. Though it does not prevent solid objects from passing through, gas and temperature changes are kept out."
icon_state = "holo_combifan"
max_integrity = 30
density = FALSE
anchored = TRUE
alpha = 150
CanAtmosPass = ATMOS_PASS_NO
resistance_flags = FIRE_PROOF
/obj/structure/holosign/barrier/combolock/blocksTemperature()
return TRUE
/obj/structure/holosign/barrier/combolock/Initialize()
. = ..()
air_update_turf(TRUE)
/obj/structure/holosign/barrier/cyborg
name = "Energy Field"
desc = "A fragile energy field that blocks movement. Excels at blocking lethal projectiles."
+1 -1
View File
@@ -133,7 +133,7 @@
switch(choice)
if("name")
var/newname = copytext(sanitize(input(H, "Who are we again?", "Name change", H.name) as null|text),1,MAX_NAME_LEN)
var/newname = reject_bad_name(stripped_input(H, "Who are we again?", "Name change", H.name, MAX_NAME_LEN))
if(!newname)
return
+12 -11
View File
@@ -109,8 +109,10 @@
var/cur_note = text2ascii(note) - 96
if(cur_note < 1 || cur_note > 7)
continue
for(var/i=2 to length(note))
var/ni = copytext(note,i,i+1)
var/notelen = length(note)
var/ni = ""
for(var/i = length(note[1]) + 1, i <= notelen, i += length(ni))
ni = note[i]
if(!text2num(ni))
if(ni == "#" || ni == "b" || ni == "n")
cur_acc[cur_note] = ni
@@ -199,9 +201,10 @@
//split into lines
lines = splittext(text, "\n")
if(lines.len)
if(copytext(lines[1],1,6) == "BPM: ")
tempo = sanitize_tempo(600 / text2num(copytext(lines[1],6)))
lines.Cut(1,2)
var/bpm_string = "BPM: "
if(findtext(lines[1], bpm_string, 1, length(bpm_string) + 1))
tempo = sanitize_tempo(600 / text2num(copytext(lines[1], length(bpm_string) + 1)))
lines.Cut(1, 2)
else
tempo = sanitize_tempo(5) // default 120 BPM
if(lines.len > MUSIC_MAXLINES)
@@ -209,7 +212,7 @@
lines.Cut(MUSIC_MAXLINES + 1)
var/linenum = 1
for(var/l in lines)
if(length(l) > MUSIC_MAXLINECHARS)
if(length_char(l) > MUSIC_MAXLINECHARS)
to_chat(usr, "Line [linenum] too long!")
lines.Remove(l)
else
@@ -236,11 +239,11 @@
if(!in_range(instrumentObj, usr))
return
if(length(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
if(length_char(t) >= MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
var/cont = input(usr, "Your message is too long! Would you like to continue editing it?", "", "yes") in list("yes", "no")
if(cont == "no")
break
while(length(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
while(length_char(t) > MUSIC_MAXLINES * MUSIC_MAXLINECHARS)
ParseSong(t)
else if(href_list["help"])
@@ -284,11 +287,9 @@
else if(href_list["modifyline"])
var/num = round(text2num(href_list["modifyline"]),1)
var/content = html_encode(input("Enter your line: ", instrumentObj.name, lines[num]) as text|null)
var/content = stripped_input(usr, "Enter your line: ", instrumentObj.name, lines[num], MUSIC_MAXLINECHARS)
if(!content || !in_range(instrumentObj, usr))
return
if(length(content) > MUSIC_MAXLINECHARS)
content = copytext(content, 1, MUSIC_MAXLINECHARS)
if(num > lines.len || num < 1)
return
lines[num] = content
@@ -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, 100, master_ui, state)
ui = new(user, src, ui_key, "tank_dispenser", name, 275, 103, master_ui, state)
ui.open()
/obj/structure/tank_dispenser/ui_data(mob/user)
+6 -6
View File
@@ -75,8 +75,8 @@ GLOBAL_LIST_INIT(freqtospan, list(
return ""
/atom/movable/proc/say_mod(input, message_mode)
var/ending = copytext(input, length(input))
if(copytext(input, length(input) - 1) == "!!")
var/ending = copytext_char(input, -1)
if(copytext_char(input, -2) == "!!")
return verb_yell
else if(ending == "?")
return verb_ask
@@ -89,7 +89,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
if(!input)
input = "..."
if(copytext(input, length(input) - 1) == "!!")
if(copytext_char(input, -2) == "!!")
spans |= SPAN_YELL
var/spanned = attach_spans(input, spans)
@@ -124,12 +124,12 @@ GLOBAL_LIST_INIT(freqtospan, list(
var/returntext = GLOB.reverseradiochannels["[freq]"]
if(returntext)
return returntext
return "[copytext("[freq]", 1, 4)].[copytext("[freq]", 4, 5)]"
return "[copytext_char("[freq]", 1, 4)].[copytext_char("[freq]", 4, 5)]"
/atom/movable/proc/attach_spans(input, list/spans)
var/customsayverb = findtext(input, "*")
if(customsayverb)
input = capitalize(copytext(input, customsayverb+1))
input = capitalize(copytext(input, length(input[customsayverb]) + 1))
if(input)
return "[message_spans_start(spans)][input]</span>"
else
@@ -143,7 +143,7 @@ GLOBAL_LIST_INIT(freqtospan, list(
return output
/proc/say_test(text)
var/ending = copytext(text, length(text))
var/ending = copytext_char(text, -1)
if (ending == "?")
return "1"
else if (ending == "!")
+37 -38
View File
@@ -245,48 +245,47 @@
return TRUE
/turf/open/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube)
if(C.movement_type & FLYING)
return 0
if(has_gravity(src))
var/obj/buckled_obj
if(C.buckled)
buckled_obj = C.buckled
if(!(lube&GALOSHES_DONT_HELP)) //can't slip while buckled unless it's lube.
return 0
else
if(!(lube&SLIP_WHEN_CRAWLING) && (C.lying || !(C.status_flags & CANKNOCKDOWN))) // can't slip unbuckled mob if they're lying or can't fall.
return 0
if(lube & NO_SLIP_WHEN_WALKING)
if(C.m_intent == MOVE_INTENT_WALK)
return 0
if(ishuman(C) && !(lube & SLIP_WHEN_JOGGING))
var/mob/living/carbon/human/H = C
if(!H.sprinting && H.getStaminaLoss() <= 20)
return 0
if(!(lube&SLIDE_ICE))
to_chat(C, "<span class='notice'>You slipped[ O ? " on the [O.name]" : ""]!</span>")
playsound(C.loc, 'sound/misc/slip.ogg', 50, 1, -3)
if(!(lube & FLYING_DOESNT_HELP) && (C.movement_type & FLYING || !has_gravity(src)))
return FALSE
var/obj/buckled_obj
if(C.buckled)
buckled_obj = C.buckled
if(!(lube&GALOSHES_DONT_HELP)) //can't slip while buckled unless it's lube.
return FALSE
else
if(!(lube&SLIP_WHEN_CRAWLING) && (C.lying || !(C.status_flags & CANKNOCKDOWN))) // can't slip unbuckled mob if they're lying or can't fall.
return FALSE
if(lube & NO_SLIP_WHEN_WALKING)
if(C.m_intent == MOVE_INTENT_WALK)
return FALSE
if(ishuman(C) && !(lube & SLIP_WHEN_JOGGING))
var/mob/living/carbon/human/H = C
if(!H.sprinting && H.getStaminaLoss() <= 20)
return FALSE
if(!(lube&SLIDE_ICE))
to_chat(C, "<span class='notice'>You slipped[ O ? " on the [O.name]" : ""]!</span>")
playsound(C.loc, 'sound/misc/slip.ogg', 50, 1, -3)
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "slipped", /datum/mood_event/slipped)
for(var/obj/item/I in C.held_items)
C.accident(I)
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "slipped", /datum/mood_event/slipped)
for(var/obj/item/I in C.held_items)
C.accident(I)
var/olddir = C.dir
if(!(lube & SLIDE_ICE))
C.Knockdown(knockdown_amount)
C.stop_pulling()
else
C.Stun(20)
var/olddir = C.dir
if(!(lube & SLIDE_ICE))
C.Knockdown(knockdown_amount)
C.stop_pulling()
else
C.Stun(20)
if(buckled_obj)
buckled_obj.unbuckle_mob(C)
lube |= SLIDE_ICE
if(buckled_obj)
buckled_obj.unbuckle_mob(C)
lube |= SLIDE_ICE
if(lube&SLIDE)
new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 4), 1, FALSE, CALLBACK(C, /mob/living/carbon/.proc/spin, 1, 1))
else if(lube&SLIDE_ICE)
new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 1), 1, FALSE) //spinning would be bad for ice, fucks up the next dir
return 1
if(lube&SLIDE)
new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 4), 1, FALSE, CALLBACK(C, /mob/living/carbon/.proc/spin, 1, 1))
else if(lube&SLIDE_ICE)
new /datum/forced_movement(C, get_ranged_target_turf(C, olddir, 1), 1, FALSE) //spinning would be bad for ice, fucks up the next dir
return TRUE
/turf/open/proc/MakeSlippery(wet_setting = TURF_WET_WATER, min_wet_time = 0, wet_time_to_add = 0, max_wet_time = MAXIMUM_WET_TIME, permanent)
AddComponent(/datum/component/wet_floor, wet_setting, min_wet_time, wet_time_to_add, max_wet_time, permanent)
+3 -2
View File
@@ -88,8 +88,9 @@
/turf/open/space/proc/CanBuildHere()
return TRUE
/turf/open/space/handle_slip()
return
/turf/open/space/handle_slip(mob/living/carbon/C, knockdown_amount, obj/O, lube)
if(lube & FLYING_DOESNT_HELP)
return ..()
/turf/open/space/attackby(obj/item/C, mob/user, params)
..()
+3
View File
@@ -115,10 +115,12 @@ GLOBAL_LIST(topic_status_cache)
GLOB.world_runtime_log = "[GLOB.log_directory]/runtime.log"
GLOB.query_debug_log = "[GLOB.log_directory]/query_debug.log"
GLOB.world_job_debug_log = "[GLOB.log_directory]/job_debug.log"
GLOB.tgui_log = "[GLOB.log_directory]/tgui.log"
GLOB.subsystem_log = "[GLOB.log_directory]/subsystem.log"
GLOB.reagent_log = "[GLOB.log_directory]/reagents.log"
GLOB.world_crafting_log = "[GLOB.log_directory]/crafting.log"
#ifdef UNIT_TESTS
GLOB.test_log = file("[GLOB.log_directory]/tests.log")
start_log(GLOB.test_log)
@@ -132,6 +134,7 @@ GLOBAL_LIST(topic_status_cache)
start_log(GLOB.world_qdel_log)
start_log(GLOB.world_runtime_log)
start_log(GLOB.world_job_debug_log)
start_log(GLOB.tgui_log)
start_log(GLOB.subsystem_log)
start_log(GLOB.reagent_log)
start_log(GLOB.world_crafting_log)