This commit is contained in:
Ghommie
2019-08-08 04:46:54 +02:00
329 changed files with 6488 additions and 3837 deletions
+2 -2
View File
@@ -190,11 +190,11 @@
/obj/effect/anomaly/bluespace/anomalyEffect()
..()
for(var/mob/living/M in range(1,src))
do_teleport(M, locate(M.x, M.y, M.z), 4)
do_teleport(M, locate(M.x, M.y, M.z), 4, channel = TELEPORT_CHANNEL_BLUESPACE)
/obj/effect/anomaly/bluespace/Bumped(atom/movable/AM)
if(isliving(AM))
do_teleport(AM, locate(AM.x, AM.y, AM.z), 8)
do_teleport(AM, locate(AM.x, AM.y, AM.z), 8, channel = TELEPORT_CHANNEL_BLUESPACE)
/obj/effect/anomaly/bluespace/detonate()
var/turf/T = safepick(get_area_turfs(impact_area))
+9
View File
@@ -16,3 +16,12 @@
I.alpha = 64
I.appearance_flags = RESET_ALPHA
add_alt_appearance(/datum/atom_hud/alternate_appearance/basic/blessedAware, "blessing", I)
RegisterSignal(loc, COMSIG_ATOM_INTERCEPT_TELEPORT, .proc/block_cult_teleport)
/obj/effect/blessing/Destroy()
UnregisterSignal(loc, COMSIG_ATOM_INTERCEPT_TELEPORT)
return ..()
/obj/effect/blessing/proc/block_cult_teleport(datum/source, channel, turf/origin, turf/destination)
if(channel == TELEPORT_CHANNEL_CULT)
return COMPONENT_BLOCK_TELEPORT
@@ -26,7 +26,7 @@
/obj/effect/particle_effect/sparks/Initialize()
. = ..()
flick("sparks", src) // replay the animation
flick(icon_state, src) // replay the animation
playsound(src, "sparks", 100, TRUE)
var/turf/T = loc
if(isturf(T))
@@ -48,6 +48,8 @@
/datum/effect_system/spark_spread
effect_type = /obj/effect/particle_effect/sparks
/datum/effect_system/spark_spread/quantum
effect_type = /obj/effect/particle_effect/sparks/quantum
//electricity
@@ -55,5 +57,9 @@
name = "lightning"
icon_state = "electricity"
/obj/effect/particle_effect/sparks/quantum
name = "quantum sparks"
icon_state = "quantum_sparks"
/datum/effect_system/lightning_spread
effect_type = /obj/effect/particle_effect/sparks/electricity
+3 -1
View File
@@ -20,6 +20,7 @@
var/mech_sized = FALSE
var/obj/effect/portal/linked
var/hardlinked = TRUE //Requires a linked portal at all times. Destroy if there's no linked portal, if there is destroy it when this one is deleted.
var/teleport_channel = TELEPORT_CHANNEL_BLUESPACE
var/creator
var/turf/hard_target //For when a portal needs a hard target and isn't to be linked.
var/atmos_link = FALSE //Link source/destination atmos.
@@ -34,6 +35,7 @@
icon = 'icons/obj/objects.dmi'
icon_state = "anom"
mech_sized = TRUE
teleport_channel = TELEPORT_CHANNEL_WORMHOLE
/obj/effect/portal/Move(newloc)
for(var/T in newloc)
@@ -160,7 +162,7 @@
no_effect = TRUE
else
last_effect = world.time
if(do_teleport(M, real_target, innate_accuracy_penalty, no_effects = no_effect))
if(do_teleport(M, real_target, innate_accuracy_penalty, no_effects = no_effect, channel = teleport_channel))
if(istype(M, /obj/item/projectile))
var/obj/item/projectile/P = M
P.ignore_source_check = TRUE
+3
View File
@@ -579,6 +579,9 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
/obj/item/proc/get_belt_overlay() //Returns the icon used for overlaying the object on a belt
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', icon_state)
/obj/item/proc/get_worn_belt_overlay(icon_file)
return
/obj/item/proc/update_slot_icon()
if(!ismob(loc))
return
+9 -3
View File
@@ -616,7 +616,7 @@ RLD
name = "rapid-light-device (RLD)"
desc = "A device used to rapidly provide lighting sources to an area. Reload with metal, plasteel, glass or compressed matter cartridges."
icon = 'icons/obj/tools.dmi'
icon_state = "rld-5"
icon_state = "rld"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
matter = 500
@@ -625,6 +625,7 @@ RLD
var/mode = LIGHT_MODE
actions_types = list(/datum/action/item_action/pick_color)
ammo_sections = 5
has_ammobar = TRUE
var/wallcost = 10
var/floorcost = 15
@@ -638,6 +639,10 @@ RLD
var/color_choice = null
/obj/item/construction/rld/Initialize()
. = ..()
update_icon()
/obj/item/construction/rld/ui_action_click(mob/user, var/datum/action/A)
if(istype(A, /datum/action/item_action/pick_color))
color_choice = input(user,"","Choose Color",color_choice) as color
@@ -645,9 +650,10 @@ RLD
..()
/obj/item/construction/rld/update_icon()
icon_state = "rld-[round((matter/max_matter) * 5, 1)]"
..()
var/ratio = CEILING((matter / max_matter) * ammo_sections, 1)
cut_overlays() //To prevent infinite stacking of overlays
add_overlay("rld_light[ratio]")
/obj/item/construction/rld/attack_self(mob/user)
..()
+44 -17
View File
@@ -2,7 +2,7 @@
name = "rapid cable layer"
desc = "A device used to rapidly deploy cables. It has screws on the side which can be removed to slide off the cables. Do not use without insulation!"
icon = 'icons/obj/tools.dmi'
icon_state = "rcl-0"
icon_state = "rcl-empty"
item_state = "rcl-0"
var/obj/structure/cable/last
var/obj/item/stack/cable_coil/loaded
@@ -92,22 +92,32 @@
/obj/item/twohanded/rcl/update_icon()
if(!loaded)
icon_state = "rcl-0"
item_state = "rcl-0"
icon_state = "rcl-empty"
item_state = "rcl-empty"
return
cut_overlays()
var/cable_amount = 0
switch(loaded.amount)
if(61 to INFINITY)
icon_state = "rcl-30"
item_state = "rcl"
cable_amount = 3
if(31 to 60)
icon_state = "rcl-20"
item_state = "rcl"
cable_amount = 2
if(1 to 30)
icon_state = "rcl-10"
item_state = "rcl"
cable_amount = 1
else
icon_state = "rcl-0"
item_state = "rcl-0"
cable_amount = 0
var/mutable_appearance/cable_overlay = mutable_appearance(icon, "rcl-[cable_amount]")
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
if(cable_amount >= 1)
icon_state = "rcl"
item_state = "rcl"
add_overlay(cable_overlay)
else
icon_state = "rcl-empty"
item_state = "rcl-0"
add_overlay(cable_overlay)
/obj/item/twohanded/rcl/proc/is_empty(mob/user, loud = 1)
update_icon()
@@ -302,6 +312,7 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
to_chat(user, "Color changed to [cwname]!")
if(loaded)
loaded.item_color= colors[current_color_index]
update_icon()
if(wiring_gui_menu)
wiringGuiUpdate(user)
else if(istype(action, /datum/action/item_action/rcl_gui))
@@ -318,13 +329,29 @@ obj/item/twohanded/rcl/proc/getMobhook(mob/to_hook)
/obj/item/twohanded/rcl/ghetto/update_icon()
if(!loaded)
icon_state = "rclg-0"
icon_state = "rclg-empty"
item_state = "rclg-0"
return
cut_overlays()
var/cable_amount = 0
switch(loaded.amount)
if(1 to INFINITY)
icon_state = "rclg-1"
item_state = "rcl"
if(20 to INFINITY)
cable_amount = 3
if(10 to 19)
cable_amount = 2
if(1 to 9)
cable_amount = 1
else
icon_state = "rclg-1"
item_state = "rclg-1"
cable_amount = 0
var/mutable_appearance/cable_overlay = mutable_appearance(icon, "rcl-[cable_amount]")
cable_overlay.color = GLOB.cable_colors[colors[current_color_index]]
if(cable_amount >= 1)
icon_state = "rclg"
item_state = "rclg"
add_overlay(cable_overlay)
else
icon_state = "rclg-empty"
item_state = "rclg-0"
add_overlay(cable_overlay)
+2
View File
@@ -177,6 +177,8 @@ GLOBAL_LIST_INIT(transit_tube_recipes, list(
desc = "A device used to rapidly pipe things."
icon = 'icons/obj/tools.dmi'
icon_state = "rpd"
lefthand_file = 'icons/mob/inhands/equipment/tools_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/tools_righthand.dmi'
flags_1 = CONDUCT_1
force = 10
throwforce = 10
@@ -237,3 +237,10 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "multitool"
toolspeed = 0.1
/obj/item/multitool/advanced
name = "advanced multitool"
desc = "The reproduction of an abductor's multitool, this multitool is a classy silver."
icon = 'icons/obj/advancedtools.dmi'
icon_state = "multitool"
toolspeed = 0.2
@@ -0,0 +1,32 @@
/obj/item/quantum_keycard
name = "quantum keycard"
desc = "A keycard able to link to a quantum pad's particle signature, allowing other quantum pads to travel there instead of their linked pad."
icon = 'icons/obj/device.dmi'
icon_state = "quantum_keycard"
item_state = "card-id"
lefthand_file = 'icons/mob/inhands/equipment/idcards_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/idcards_righthand.dmi'
w_class = WEIGHT_CLASS_TINY
var/obj/machinery/quantumpad/qpad
/obj/item/quantum_keycard/examine(mob/user)
..()
if(qpad)
to_chat(user, "It's currently linked to a quantum pad.")
to_chat(user, "<span class='notice'>Alt-click to unlink the keycard.</span>")
else
to_chat(user, "<span class='notice'>Insert [src] into an active quantum pad to link it.</span>")
/obj/item/quantum_keycard/AltClick(mob/living/user)
if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user)))
return
to_chat(user, "<span class='notice'>You start pressing [src]'s unlink button...</span>")
if(do_after(user, 40, target = src))
to_chat(user, "<span class='notice'>The keycard beeps twice and disconnects the quantum link.</span>")
qpad = null
/obj/item/quantum_keycard/update_icon()
if(qpad)
icon_state = "quantum_keycard_on"
else
icon_state = initial(icon_state)
@@ -1,6 +1,6 @@
/obj/item/encryptionkey
name = "standard encryption key"
desc = "An encryption key for a radio headset. Has no special codes in it. WHY DOES IT EXIST? ASK NANOTRASEN."
desc = "An encryption key for a radio headset."
icon = 'icons/obj/radio.dmi'
icon_state = "cypherkey"
w_class = WEIGHT_CLASS_TINY
@@ -9,124 +9,119 @@
var/independent = FALSE
var/list/channels = list()
/obj/item/encryptionkey/Initialize()
. = ..()
if(!channels.len)
desc = "An encryption key for a radio headset. Has no special codes in it. You should probably tell a coder!"
/obj/item/encryptionkey/examine(mob/user)
. = ..()
if(LAZYLEN(channels))
var/list/examine_text_list = list()
for(var/i in channels)
examine_text_list += "[GLOB.channel_tokens[i]] - [lowertext(i)]"
to_chat(user, "<span class='notice'>It can access the following channels; [jointext(examine_text_list, ", ")].</span>")
/obj/item/encryptionkey/syndicate
name = "syndicate encryption key"
desc = "An encryption key for a radio headset. To access the syndicate channel, use :t."
icon_state = "syn_cypherkey"
channels = list("Syndicate" = 1)
syndie = 1//Signifies that it de-crypts Syndicate transmissions
channels = list(RADIO_CHANNEL_SYNDICATE = 1)
syndie = TRUE //Signifies that it de-crypts Syndicate transmissions
/obj/item/encryptionkey/binary
name = "binary translator key"
desc = "An encryption key for a radio headset. To access the binary channel, use :b."
icon_state = "bin_cypherkey"
translate_binary = TRUE
/obj/item/encryptionkey/headset_sec
name = "security radio encryption key"
desc = "An encryption key for a radio headset. To access the security channel, use :s."
icon_state = "sec_cypherkey"
channels = list("Security" = 1)
channels = list(RADIO_CHANNEL_SECURITY = 1)
/obj/item/encryptionkey/headset_eng
name = "engineering radio encryption key"
desc = "An encryption key for a radio headset. To access the engineering channel, use :e."
icon_state = "eng_cypherkey"
channels = list("Engineering" = 1)
channels = list(RADIO_CHANNEL_ENGINEERING = 1)
/obj/item/encryptionkey/headset_rob
name = "robotics radio encryption key"
desc = "An encryption key for a radio headset. To access the engineering channel, use :e. For research, use :n."
icon_state = "rob_cypherkey"
channels = list("Science" = 1, "Engineering" = 1)
channels = list(RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_ENGINEERING = 1)
/obj/item/encryptionkey/headset_med
name = "medical radio encryption key"
desc = "An encryption key for a radio headset. To access the medical channel, use :m."
icon_state = "med_cypherkey"
channels = list("Medical" = 1)
channels = list(RADIO_CHANNEL_MEDICAL = 1)
/obj/item/encryptionkey/headset_sci
name = "science radio encryption key"
desc = "An encryption key for a radio headset. To access the science channel, use :n."
icon_state = "sci_cypherkey"
channels = list("Science" = 1)
channels = list(RADIO_CHANNEL_SCIENCE = 1)
/obj/item/encryptionkey/headset_medsci
name = "medical research radio encryption key"
desc = "An encryption key for a radio headset. To access the medical channel, use :m. For science, use :n."
icon_state = "medsci_cypherkey"
channels = list("Science" = 1, "Medical" = 1)
channels = list(RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_MEDICAL = 1)
/obj/item/encryptionkey/headset_com
name = "command radio encryption key"
desc = "An encryption key for a radio headset. To access the command channel, use :c."
icon_state = "com_cypherkey"
channels = list("Command" = 1)
channels = list(RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/heads/captain
name = "\proper the captain's encryption key"
desc = "An encryption key for a radio headset. Channels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
icon_state = "cap_cypherkey"
channels = list("Command" = 1, "Security" = 1, "Engineering" = 0, "Science" = 0, "Medical" = 0, "Supply" = 0, "Service" = 0)
channels = list(RADIO_CHANNEL_COMMAND = 1, RADIO_CHANNEL_SECURITY = 1, RADIO_CHANNEL_ENGINEERING = 0, RADIO_CHANNEL_SCIENCE = 0, RADIO_CHANNEL_MEDICAL = 0, RADIO_CHANNEL_SUPPLY = 0, RADIO_CHANNEL_SERVICE = 0)
/obj/item/encryptionkey/heads/rd
name = "\proper the research director's encryption key"
desc = "An encryption key for a radio headset. To access the science channel, use :n. For command, use :c."
icon_state = "rd_cypherkey"
channels = list("Science" = 1, "Command" = 1)
channels = list(RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/heads/hos
name = "\proper the head of security's encryption key"
desc = "An encryption key for a radio headset. To access the security channel, use :s. For command, use :c."
icon_state = "hos_cypherkey"
channels = list("Security" = 1, "Command" = 1)
channels = list(RADIO_CHANNEL_SECURITY = 1, RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/heads/ce
name = "\proper the chief engineer's encryption key"
desc = "An encryption key for a radio headset. To access the engineering channel, use :e. For command, use :c."
icon_state = "ce_cypherkey"
channels = list("Engineering" = 1, "Command" = 1)
channels = list(RADIO_CHANNEL_ENGINEERING = 1, RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/heads/cmo
name = "\proper the chief medical officer's encryption key"
desc = "An encryption key for a radio headset. To access the medical channel, use :m. For command, use :c."
icon_state = "cmo_cypherkey"
channels = list("Medical" = 1, "Command" = 1)
channels = list(RADIO_CHANNEL_MEDICAL = 1, RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/heads/hop
name = "\proper the head of personnel's encryption key"
desc = "An encryption key for a radio headset. Channels are as follows: :u - supply, :v - service, :c - command."
icon_state = "hop_cypherkey"
channels = list("Supply" = 1, "Service" = 1, "Command" = 1)
channels = list(RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SERVICE = 1, RADIO_CHANNEL_COMMAND = 1)
/obj/item/encryptionkey/headset_cargo
name = "supply radio encryption key"
desc = "An encryption key for a radio headset. To access the supply channel, use :u."
icon_state = "cargo_cypherkey"
channels = list("Supply" = 1)
channels = list(RADIO_CHANNEL_SUPPLY = 1)
/obj/item/encryptionkey/headset_mining
name = "mining radio encryption key"
desc = "An encryption key for a radio headset. To access the supply channel, use :u. For science, use :n."
icon_state = "cargo_cypherkey"
channels = list("Supply" = 1, "Science" = 1)
channels = list(RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SCIENCE = 1)
/obj/item/encryptionkey/headset_service
name = "service radio encryption key"
desc = "An encryption key for a radio headset. To access the service channel, use :v."
icon_state = "srv_cypherkey"
channels = list("Service" = 1)
channels = list(RADIO_CHANNEL_SERVICE = 1)
/obj/item/encryptionkey/headset_cent
name = "\improper CentCom radio encryption key"
desc = "An encryption key for a radio headset. To access the CentCom channel, use :y."
icon_state = "cent_cypherkey"
independent = TRUE
channels = list("CentCom" = 1)
channels = list(RADIO_CHANNEL_CENTCOM = 1)
/obj/item/encryptionkey/ai //ported from NT, this goes 'inside' the AI.
channels = list("Command" = 1, "Security" = 1, "Engineering" = 1, "Science" = 1, "Medical" = 1, "Supply" = 1, "Service" = 1, "AI Private" = 1)
channels = list(RADIO_CHANNEL_COMMAND = 1, RADIO_CHANNEL_SECURITY = 1, RADIO_CHANNEL_ENGINEERING = 1, RADIO_CHANNEL_SCIENCE = 1, RADIO_CHANNEL_MEDICAL = 1, RADIO_CHANNEL_SUPPLY = 1, RADIO_CHANNEL_SERVICE = 1, RADIO_CHANNEL_AI_PRIVATE = 1)
/obj/item/encryptionkey/secbot
channels = list("AI Private"=1,"Security"=1)
channels = list(RADIO_CHANNEL_AI_PRIVATE = 1, RADIO_CHANNEL_SECURITY = 1)
@@ -1,3 +1,19 @@
// Used for translating channels to tokens on examination
GLOBAL_LIST_INIT(channel_tokens, list(
RADIO_CHANNEL_COMMON = RADIO_KEY_COMMON,
RADIO_CHANNEL_SCIENCE = RADIO_TOKEN_SCIENCE,
RADIO_CHANNEL_COMMAND = RADIO_TOKEN_COMMAND,
RADIO_CHANNEL_MEDICAL = RADIO_TOKEN_MEDICAL,
RADIO_CHANNEL_ENGINEERING = RADIO_TOKEN_ENGINEERING,
RADIO_CHANNEL_SECURITY = RADIO_TOKEN_SECURITY,
RADIO_CHANNEL_CENTCOM = RADIO_TOKEN_CENTCOM,
RADIO_CHANNEL_SYNDICATE = RADIO_TOKEN_SYNDICATE,
RADIO_CHANNEL_SUPPLY = RADIO_TOKEN_SUPPLY,
RADIO_CHANNEL_SERVICE = RADIO_TOKEN_SERVICE,
MODE_BINARY = MODE_TOKEN_BINARY,
RADIO_CHANNEL_AI_PRIVATE = RADIO_TOKEN_AI_PRIVATE
))
/obj/item/radio/headset
name = "radio headset"
desc = "An updated, modular intercom that fits over the head. Takes encryption keys."
@@ -17,9 +33,24 @@
/obj/item/radio/headset/examine(mob/user)
..()
to_chat(user, "<span class='notice'>To speak on the general radio frequency, use ; before speaking.</span>")
if (command)
to_chat(user, "<span class='notice'>Alt-click to toggle the high-volume mode.</span>")
if(item_flags & IN_INVENTORY && loc == user)
// construction of frequency description
var/list/avail_chans = list("Use [RADIO_KEY_COMMON] for the currently tuned frequency")
if(translate_binary)
avail_chans += "use [MODE_TOKEN_BINARY] for [MODE_BINARY]"
if(length(channels))
for(var/i in 1 to length(channels))
if(i == 1)
avail_chans += "use [MODE_TOKEN_DEPARTMENT] or [GLOB.channel_tokens[channels[i]]] for [lowertext(channels[i])]"
else
avail_chans += "use [GLOB.channel_tokens[channels[i]]] for [lowertext(channels[i])]"
to_chat(user, "<span class='notice'>A small screen on the headset displays the following available frequencies:\n[english_list(avail_chans)].")
if(command)
to_chat(user, "<span class='info'>Alt-click to toggle the high-volume mode.</span>")
else
to_chat(user, "<span class='notice'>A small screen on the headset flashes, it's too small to read without holding or wearing the headset.</span>")
/obj/item/radio/headset/Initialize()
. = ..()
@@ -47,7 +78,7 @@
/obj/item/radio/headset/syndicate/alt //undisguised bowman with flash protection
name = "syndicate headset"
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs. \nTo access the syndicate channel, use ; before speaking."
desc = "A syndicate headset that can be used to hear all radio frequencies. Protects ears from flashbangs."
icon_state = "syndie_headset"
item_state = "syndie_headset"
@@ -72,13 +103,13 @@
/obj/item/radio/headset/headset_sec
name = "security radio headset"
desc = "This is used by your elite security force.\nTo access the security channel, use :s."
desc = "This is used by your elite security force."
icon_state = "sec_headset"
keyslot = new /obj/item/encryptionkey/headset_sec
/obj/item/radio/headset/headset_sec/alt
name = "security bowman headset"
desc = "This is used by your elite security force. Protects ears from flashbangs.\nTo access the security channel, use :s."
desc = "This is used by your elite security force. Protects ears from flashbangs."
icon_state = "sec_headset_alt"
item_state = "sec_headset_alt"
@@ -88,31 +119,31 @@
/obj/item/radio/headset/headset_eng
name = "engineering radio headset"
desc = "When the engineers wish to chat like girls.\nTo access the engineering channel, use :e."
desc = "When the engineers wish to chat like girls."
icon_state = "eng_headset"
keyslot = new /obj/item/encryptionkey/headset_eng
/obj/item/radio/headset/headset_rob
name = "robotics radio headset"
desc = "Made specifically for the roboticists, who cannot decide between departments.\nTo access the engineering channel, use :e. For research, use :n."
desc = "Made specifically for the roboticists, who cannot decide between departments."
icon_state = "rob_headset"
keyslot = new /obj/item/encryptionkey/headset_rob
/obj/item/radio/headset/headset_med
name = "medical radio headset"
desc = "A headset for the trained staff of the medbay.\nTo access the medical channel, use :m."
desc = "A headset for the trained staff of the medbay."
icon_state = "med_headset"
keyslot = new /obj/item/encryptionkey/headset_med
/obj/item/radio/headset/headset_sci
name = "science radio headset"
desc = "A sciency headset. Like usual.\nTo access the science channel, use :n."
desc = "A sciency headset. Like usual."
icon_state = "sci_headset"
keyslot = new /obj/item/encryptionkey/headset_sci
/obj/item/radio/headset/headset_medsci
name = "medical research radio headset"
desc = "A headset that is a result of the mating between medical and science.\nTo access the medical channel, use :m. For science, use :n."
desc = "A headset that is a result of the mating between medical and science."
icon_state = "medsci_headset"
keyslot = new /obj/item/encryptionkey/headset_medsci
@@ -127,13 +158,13 @@
/obj/item/radio/headset/heads/captain
name = "\proper the captain's headset"
desc = "The headset of the king.\nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
desc = "The headset of the king."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/captain
/obj/item/radio/headset/heads/captain/alt
name = "\proper the captain's bowman headset"
desc = "The headset of the boss. Protects ears from flashbangs.\nChannels are as follows: :c - command, :s - security, :e - engineering, :u - supply, :v - service, :m - medical, :n - science."
desc = "The headset of the boss. Protects ears from flashbangs."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
@@ -143,19 +174,19 @@
/obj/item/radio/headset/heads/rd
name = "\proper the research director's headset"
desc = "Headset of the fellow who keeps society marching towards technological singularity.\nTo access the science channel, use :n. For command, use :c."
desc = "Headset of the fellow who keeps society marching towards technological singularity."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/rd
/obj/item/radio/headset/heads/hos
name = "\proper the head of security's headset"
desc = "The headset of the man in charge of keeping order and protecting the station.\nTo access the security channel, use :s. For command, use :c."
desc = "The headset of the man in charge of keeping order and protecting the station."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/hos
/obj/item/radio/headset/heads/hos/alt
name = "\proper the head of security's bowman headset"
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs.\nTo access the security channel, use :s. For command, use :c."
desc = "The headset of the man in charge of keeping order and protecting the station. Protects ears from flashbangs."
icon_state = "com_headset_alt"
item_state = "com_headset_alt"
@@ -165,43 +196,43 @@
/obj/item/radio/headset/heads/ce
name = "\proper the chief engineer's headset"
desc = "The headset of the guy in charge of keeping the station powered and undamaged.\nTo access the engineering channel, use :e. For command, use :c."
desc = "The headset of the guy in charge of keeping the station powered and undamaged."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/ce
/obj/item/radio/headset/heads/cmo
name = "\proper the chief medical officer's headset"
desc = "The headset of the highly trained medical chief.\nTo access the medical channel, use :m. For command, use :c."
desc = "The headset of the highly trained medical chief."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/cmo
/obj/item/radio/headset/heads/hop
name = "\proper the head of personnel's headset"
desc = "The headset of the guy who will one day be captain.\nChannels are as follows: :u - supply, :v - service, :c - command."
desc = "The headset of the guy who will one day be captain."
icon_state = "com_headset"
keyslot = new /obj/item/encryptionkey/heads/hop
/obj/item/radio/headset/headset_cargo
name = "supply radio headset"
desc = "A headset used by the QM and his slaves.\nTo access the supply channel, use :u."
desc = "A headset used by the QM and his slaves."
icon_state = "cargo_headset"
keyslot = new /obj/item/encryptionkey/headset_cargo
/obj/item/radio/headset/headset_cargo/mining
name = "mining radio headset"
desc = "Headset used by shaft miners.\nTo access the supply channel, use :u. For science, use :n."
desc = "Headset used by shaft miners."
icon_state = "mine_headset"
keyslot = new /obj/item/encryptionkey/headset_mining
/obj/item/radio/headset/headset_srv
name = "service radio headset"
desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean.\nTo access the service channel, use :v."
desc = "Headset used by the service staff, tasked with keeping the station full, happy and clean."
icon_state = "srv_headset"
keyslot = new /obj/item/encryptionkey/headset_service
/obj/item/radio/headset/headset_cent
name = "\improper CentCom headset"
desc = "A headset used by the upper echelons of Nanotrasen.\nTo access the CentCom channel, use :y."
desc = "A headset used by the upper echelons of Nanotrasen."
icon_state = "cent_headset"
keyslot = new /obj/item/encryptionkey/headset_com
keyslot2 = new /obj/item/encryptionkey/headset_cent
@@ -215,7 +246,7 @@
/obj/item/radio/headset/headset_cent/alt
name = "\improper CentCom bowman headset"
desc = "A headset especially for emergency response personnel. Protects ears from flashbangs.\nTo access the CentCom channel, use :y."
desc = "A headset especially for emergency response personnel. Protects ears from flashbangs."
icon_state = "cent_headset_alt"
item_state = "cent_headset_alt"
keyslot = null
@@ -221,7 +221,7 @@
// From the channel, determine the frequency and get a reference to it.
var/freq
if(channel && channels && channels.len > 0)
if(channel == "department")
if(channel == MODE_DEPARTMENT)
channel = channels[1]
freq = secure_radio_connections[channel]
if (!channels[channel]) // if the channel is turned off, don't broadcast
+122 -81
View File
@@ -1,4 +1,3 @@
///books that teach things (intrinsic actions like bar flinging, spells like fireball or smoke, or martial arts)///
/obj/item/book/granter
@@ -13,19 +12,50 @@
/obj/item/book/granter/proc/turn_page(mob/user)
playsound(user, pick('sound/effects/pageturn1.ogg','sound/effects/pageturn2.ogg','sound/effects/pageturn3.ogg'), 30, 1)
if(do_after(user,50, user))
to_chat(user, "<span class='notice'>[pick(remarks)]</span>")
if(remarks.len)
to_chat(user, "<span class='notice'>[pick(remarks)]</span>")
else
to_chat(user, "<span class='notice'>You keep reading...</span>")
return TRUE
return FALSE
/obj/item/book/granter/proc/recoil(mob/user) //nothing so some books can just return
/obj/item/book/granter/proc/already_known(mob/user)
return FALSE
/obj/item/book/granter/proc/on_reading_start(mob/user)
to_chat(user, "<span class='notice'>You start reading [name]...</span>")
/obj/item/book/granter/proc/on_reading_stopped(mob/user)
to_chat(user, "<span class='notice'>You stop reading...</span>")
/obj/item/book/granter/proc/on_reading_finished(mob/user)
to_chat(user, "<span class='notice'>You finish reading [name]!</span>")
/obj/item/book/granter/proc/onlearned(mob/user)
used = TRUE
/obj/item/book/granter/attack_self(mob/user)
if(reading == TRUE)
if(reading)
to_chat(user, "<span class='warning'>You're already reading this!</span>")
return FALSE
if(already_known(user))
return FALSE
if(used && oneuse)
recoil(user)
else
on_reading_start(user)
reading = TRUE
for(var/i=1, i<=pages_to_mastery, i++)
if(!turn_page(user))
on_reading_stopped()
reading = FALSE
return
if(do_after(user,50, user))
on_reading_finished(user)
reading = FALSE
return TRUE
///ACTION BUTTONS///
@@ -34,33 +64,23 @@
var/granted_action
var/actionname = "catching bugs" //might not seem needed but this makes it so you can safely name action buttons toggle this or that without it fucking up the granter, also caps
/obj/item/book/granter/action/attack_self(mob/user)
. = ..()
if(!.)
return
/obj/item/book/granter/action/already_known(mob/user)
if(!granted_action)
return
var/datum/action/G = new granted_action
return TRUE
for(var/datum/action/A in user.actions)
if(A.type == G.type)
if(A.type == granted_action)
to_chat(user, "<span class='notice'>You already know all about [actionname].</span>")
qdel(G)
return
if(used == TRUE && oneuse == TRUE)
recoil(user)
else
to_chat(user, "<span class='notice'>You start reading about [actionname]...</span>")
reading = TRUE
for(var/i=1, i<=pages_to_mastery, i++)
if(!turn_page(user))
to_chat(user, "<span class='notice'>You stop reading...</span>")
reading = FALSE
qdel(G)
return
if(do_after(user,50, user))
to_chat(user, "<span class='notice'>You feel like you've got a good handle on [actionname]!</span>")
G.Grant(user)
reading = FALSE
return TRUE
return FALSE
/obj/item/book/granter/action/on_reading_start(mob/user)
to_chat(user, "<span class='notice'>You start reading about [actionname]...</span>")
/obj/item/book/granter/action/on_reading_finished(mob/user)
to_chat(user, "<span class='notice'>You feel like you've got a good handle on [actionname]!</span>")
var/datum/action/G = new granted_action
G.Grant(user)
onlearned(user)
/obj/item/book/granter/action/drink_fling
granted_action = /datum/action/innate/drink_fling
@@ -120,38 +140,28 @@
var/spell
var/spellname = "conjure bugs"
/obj/item/book/granter/spell/attack_self(mob/user)
. = ..()
if(!.)
return
/obj/item/book/granter/spell/already_known(mob/user)
if(!spell)
return
var/obj/effect/proc_holder/spell/S = new spell
return TRUE
for(var/obj/effect/proc_holder/spell/knownspell in user.mind.spell_list)
if(knownspell.type == S.type)
if(knownspell.type == spell)
if(user.mind)
if(iswizard(user))
to_chat(user,"<span class='notice'>You're already far more versed in this spell than this flimsy howto book can provide.</span>")
to_chat(user,"<span class='notice'>You're already far more versed in this spell than this flimsy how-to book can provide.</span>")
else
to_chat(user,"<span class='notice'>You've already read this one.</span>")
return
if(used == TRUE && oneuse == TRUE)
recoil(user)
else
to_chat(user, "<span class='notice'>You start reading about casting [spellname]...</span>")
reading = TRUE
for(var/i=1, i<=pages_to_mastery, i++)
if(!turn_page(user))
to_chat(user, "<span class='notice'>You stop reading...</span>")
reading = FALSE
qdel(S)
return
if(do_after(user,50, user))
to_chat(user, "<span class='notice'>You feel like you've experienced enough to cast [spellname]!</span>")
user.mind.AddSpell(S)
user.log_message("learned the spell [spellname] ([S])", LOG_ATTACK, color="orange")
onlearned(user)
reading = FALSE
return TRUE
return FALSE
/obj/item/book/granter/spell/on_reading_start(mob/user)
to_chat(user, "<span class='notice'>You start reading about casting [spellname]...</span>")
/obj/item/book/granter/spell/on_reading_finished(mob/user)
to_chat(user, "<span class='notice'>You feel like you've experienced enough to cast [spellname]!</span>")
var/obj/effect/proc_holder/spell/S = new spell
user.mind.AddSpell(S)
user.log_message("learned the spell [spellname] ([S])", LOG_ATTACK, color="orange")
onlearned(user)
/obj/item/book/granter/spell/recoil(mob/user)
user.visible_message("<span class='warning'>[src] glows in a black light!</span>")
@@ -280,7 +290,8 @@
if(ishuman(user))
to_chat(user,"<font size='15' color='red'><b>HORSIE HAS RISEN</b></font>")
var/obj/item/clothing/magichead = new /obj/item/clothing/mask/horsehead/cursed(user.drop_location())
user.dropItemToGround(user.wear_mask, TRUE)
if(!user.dropItemToGround(user.wear_mask))
qdel(user.wear_mask)
user.equip_to_slot_if_possible(magichead, SLOT_WEAR_MASK, TRUE, TRUE)
qdel(src)
else
@@ -327,35 +338,24 @@
var/martialname = "bug jitsu"
var/greet = "You feel like you have mastered the art in breaking code. Nice work, jackass."
/obj/item/book/granter/martial/attack_self(mob/user)
. = ..()
if(!.)
return
/obj/item/book/granter/martial/already_known(mob/user)
if(!martial)
return
return TRUE
var/datum/martial_art/MA = martial
if(user.mind.has_martialart(initial(MA.id)))
to_chat(user,"<span class='warning'>You already know [martialname]!</span>")
return TRUE
return FALSE
/obj/item/book/granter/martial/on_reading_start(mob/user)
to_chat(user, "<span class='notice'>You start reading about [martialname]...</span>")
/obj/item/book/granter/martial/on_reading_finished(mob/user)
to_chat(user, "[greet]")
var/datum/martial_art/MA = new martial
if(user.mind.martial_art)
for(var/datum/martial_art/knownmartial in user.mind.martial_art)
if(knownmartial.type == MA.type)
to_chat(user,"<span class='warning'>You already know [martialname]!</span>")
return
if(used == TRUE && oneuse == TRUE)
recoil(user)
else
to_chat(user, "<span class='notice'>You start reading about [martialname]...</span>")
reading = TRUE
for(var/i=1, i<=pages_to_mastery, i++)
if(!turn_page(user))
to_chat(user, "<span class='notice'>You stop reading...</span>")
reading = FALSE
qdel(MA)
return
if(do_after(user,50, user))
to_chat(user, "[greet]")
MA.teach(user)
user.log_message("learned the martial art [martialname] ([MA])", LOG_ATTACK, color="orange")
onlearned(user)
reading = FALSE
MA.teach(user)
user.log_message("learned the martial art [martialname] ([MA])", LOG_ATTACK, color="orange")
onlearned(user)
/obj/item/book/granter/martial/cqc
martial = /datum/martial_art/cqc
@@ -416,3 +416,44 @@
icon_state = "blankscroll"
// I did not include mushpunch's grant, it is not a book and the item does it just fine.
//Crafting Recipe books
/obj/item/book/granter/crafting_recipe
var/list/crafting_recipe_types = list() //Use full /datum/crafting_recipe/what_you_craft
/obj/item/book/granter/crafting_recipe/on_reading_finished(mob/user)
. = ..()
if(!user.mind)
return
for(var/crafting_recipe_type in crafting_recipe_types)
var/datum/crafting_recipe/R = crafting_recipe_type
user.mind.teach_crafting_recipe(crafting_recipe_type)
to_chat(user,"<span class='notice'>You learned how to make [initial(R.name)].</span>")
/obj/item/book/granter/crafting_recipe/cooking_sweets_101 //We start at 101 for 103 and 105
name = "Cooking Desserts 101"
desc = "A cook book that teaches you some more of the newest desserts. AI approved, and a best seller on Honkplanet."
crafting_recipe_types = list(/datum/crafting_recipe/food/mimetart, /datum/crafting_recipe/food/berrytart, /datum/crafting_recipe/food/cocolavatart, /datum/crafting_recipe/food/clowncake, /datum/crafting_recipe/food/vanillacake)
icon_state = "cooking_learing_sweets"
oneuse = FALSE
remarks = list("So that is how icing is made!", "Placing fruit on top? How simple...", "Huh layering cake seems harder then this...", "This book smells like candy", "A clown must have made this page, or they forgot to spell check it before printing...", "Wait, a way to cook slime to be safe?")
//Later content when I have free time - Trilby Date:02-Aug-2019
/obj/item/book/granter/crafting_recipe/under_the_oven //Illegal cook book
name = "Under The Oven"
desc = "A cook book that teaches you many illegal and fun candys. MALF AI approved, and a best seller on the blackmarket."
crafting_recipe_types = list()
icon_state = "cooking_learing_illegal"
oneuse = FALSE
remarks = list()
/obj/item/book/granter/crafting_recipe/coldcooking //IceCream
name = "Cooking with Ice"
desc = "A cook book that teaches you many old icecream treats."
crafting_recipe_types = list()
icon_state = "cooking_learing_ice"
oneuse = FALSE
remarks = list()
+11 -3
View File
@@ -26,6 +26,7 @@
gender = PLURAL
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "handcuff"
item_state = "handcuff"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
flags_1 = CONDUCT_1
@@ -103,7 +104,6 @@
desc = "A pair of restraints fashioned from long strands of flesh."
icon = 'icons/obj/mining.dmi'
icon_state = "sinewcuff"
item_state = "sinewcuff"
breakouttime = 300 //Deciseconds = 30s
cuffsound = 'sound/weapons/cablecuff.ogg'
@@ -172,6 +172,13 @@
desc = "Fake handcuffs meant for gag purposes."
breakouttime = 10 //Deciseconds = 1s
/obj/item/restraints/handcuffs/fake/kinky
name = "kinky handcuffs"
desc = "Fake handcuffs meant for erotic roleplay."
icon = 'modular_citadel/icons/obj/items_and_weapons.dmi'
icon_state = "handcuffgag"
item_state = "kinkycuff"
/obj/item/restraints/handcuffs/cable/attackby(obj/item/I, mob/user, params)
..()
if(istype(I, /obj/item/stack/rods))
@@ -206,7 +213,8 @@
/obj/item/restraints/handcuffs/cable/zipties
name = "zipties"
desc = "Plastic, disposable zipties that can be used to restrain temporarily but are destroyed after use."
icon_state = "cuff"
icon_state = "zipties"
item_state = "zipties"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
materials = list()
@@ -217,7 +225,6 @@
/obj/item/restraints/handcuffs/cable/zipties/used
desc = "A pair of broken zipties."
icon_state = "cuff_used"
item_state = "cuff"
/obj/item/restraints/handcuffs/cable/zipties/used/attack()
return
@@ -230,6 +237,7 @@
gender = PLURAL
icon = 'icons/obj/items_and_weapons.dmi'
icon_state = "handcuff"
item_state = "legcuff"
lefthand_file = 'icons/mob/inhands/equipment/security_lefthand.dmi'
righthand_file = 'icons/mob/inhands/equipment/security_righthand.dmi'
flags_1 = CONDUCT_1
+5 -1
View File
@@ -174,6 +174,7 @@
/obj/item/his_grace/proc/consume(mob/living/meal) //Here's your dinner, Mr. Grace.
if(!meal)
return
var/victims = 0
meal.visible_message("<span class='warning'>[src] swings open and devours [meal]!</span>", "<span class='his_grace big bold'>[src] consumes you!</span>")
meal.adjustBruteLoss(200)
playsound(meal, 'sound/misc/desceration-02.ogg', 75, 1)
@@ -185,7 +186,10 @@
bloodthirst = max(LAZYLEN(contents), 1) //Never fully sated, and His hunger will only grow.
else
bloodthirst = HIS_GRACE_CONSUME_OWNER
if(LAZYLEN(contents) >= victims_needed)
for(var/mob/living/C in contents)
if(C.mind)
victims++
if(victims >= victims_needed)
ascend()
update_stats()
@@ -21,7 +21,7 @@
return
if(!H.mind)
return
if(istype(H.mind.martial_art, /datum/martial_art/krav_maga))
if(H.mind.has_martialart(MARTIALART_KRAVMAGA))
style.remove(H)
else
style.teach(H,1)
@@ -9,6 +9,7 @@
name = "inconspicious box"
desc = "It's so normal that you didn't notice it before."
icon_state = "agentbox"
max_integrity = 1
use_mob_movespeed = TRUE
/obj/structure/closet/cardboard/agent/proc/go_invisible()
+13 -1
View File
@@ -89,6 +89,12 @@
if(istype(B))
playsound(B, 'sound/items/sheath.ogg', 25, 1)
/obj/item/melee/sabre/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "sabre")
/obj/item/melee/sabre/get_worn_belt_overlay(icon_file)
return mutable_appearance(icon_file, "-sabre")
/obj/item/melee/sabre/suicide_act(mob/living/user)
user.visible_message("<span class='suicide'>[user] is trying to cut off all [user.p_their()] limbs with [src]! it looks like [user.p_theyre()] trying to commit suicide!</span>")
var/i = 0
@@ -147,13 +153,19 @@
flags_1 = CONDUCT_1
obj_flags = UNIQUE_RENAME
w_class = WEIGHT_CLASS_BULKY
sharpness = IS_SHARP_ACCURATE //It cant be sharpend cook -_-
sharpness = IS_SHARP_ACCURATE //It cant be sharpend cook -_-
attack_verb = list("slashed", "cut", "pierces", "pokes")
/obj/item/melee/rapier/Initialize()
. = ..()
AddComponent(/datum/component/butchering, 20, 65, 0)
/obj/item/melee/rapier/get_belt_overlay()
return mutable_appearance('icons/obj/clothing/belt_overlays.dmi', "rapier")
/obj/item/melee/rapier/get_worn_belt_overlay(icon_file)
return mutable_appearance(icon_file, "-rapier")
/obj/item/melee/classic_baton
name = "police baton"
desc = "A wooden truncheon for beating criminal scum."
+5 -4
View File
@@ -66,7 +66,8 @@
to_chat(user, "The spell matrix was unable to locate a suitable teleport destination for an unknown reason. Sorry.")
return
user.forceMove(pick(L))
smoke.start()
uses--
if(do_teleport(user, pick(L), forceMove = TRUE, channel = TELEPORT_CHANNEL_MAGIC, forced = TRUE))
smoke.start()
uses--
else
to_chat(user, "The spell matrix was disrupted by something near the destination.")
+1 -1
View File
@@ -33,7 +33,7 @@
use(1)
/obj/item/stack/ore/bluespace_crystal/proc/blink_mob(mob/living/L)
do_teleport(L, get_turf(L), blink_range, asoundin = 'sound/effects/phasein.ogg')
do_teleport(L, get_turf(L), blink_range, asoundin = 'sound/effects/phasein.ogg', channel = TELEPORT_CHANNEL_BLUESPACE)
/obj/item/stack/ore/bluespace_crystal/throw_impact(atom/hit_atom)
if(!..()) // not caught in mid-air
+1 -1
View File
@@ -18,7 +18,7 @@
/obj/item/stack/medical/attack(mob/living/M, mob/user)
if(M.stat == DEAD)
if(M.stat == DEAD && !stop_bleeding)
var/t_him = "it"
if(M.gender == MALE)
t_him = "him"
@@ -415,6 +415,8 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
new/datum/stack_recipe("brass window - directional", /obj/structure/window/reinforced/clockwork/unanchored, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass window - fulltile", /obj/structure/window/reinforced/clockwork/fulltile/unanchored, 2, time = 0, on_floor = TRUE, window_checks = TRUE), \
new/datum/stack_recipe("brass chair", /obj/structure/chair/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass bar stool", /obj/structure/chair/stool/bar/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass stool", /obj/structure/chair/stool/brass, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("brass table frame", /obj/structure/table_frame/brass, 1, time = 5, one_per_turf = TRUE, on_floor = TRUE), \
null,
new/datum/stack_recipe("sender - pressure sensor", /obj/structure/destructible/clockwork/trap/trigger/pressure_sensor, 2, time = 20, one_per_turf = TRUE, on_floor = TRUE), \
@@ -426,7 +428,7 @@ GLOBAL_LIST_INIT(brass_recipes, list ( \
new/datum/stack_recipe("receiver - steam vent", /obj/structure/destructible/clockwork/trap/steam_vent, 3, time = 30, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
new/datum/stack_recipe("receiver - power nullifier", /obj/structure/destructible/clockwork/trap/power_nullifier, 5, time = 20, one_per_turf = TRUE, on_floor = TRUE, placement_checks = STACK_CHECK_CARDINALS), \
null,
new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/holyoil/null), \
new/datum/stack_recipe("brass flask", /obj/item/reagent_containers/food/drinks/bottle/holyoil/empty), \
))
@@ -478,6 +480,8 @@ GLOBAL_LIST_INIT(bronze_recipes, list ( \
new/datum/stack_recipe("bronze boots", /obj/item/clothing/shoes/bronze), \
null,
new/datum/stack_recipe("bronze chair", /obj/structure/chair/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("bronze bar stool", /obj/structure/chair/stool/bar/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
new/datum/stack_recipe("bronze stool", /obj/structure/chair/stool/bronze, 1, time = 0, one_per_turf = TRUE, on_floor = TRUE), \
))
/obj/item/stack/tile/bronze
+32 -41
View File
@@ -10,6 +10,7 @@
attack_verb = list("whipped", "lashed", "disciplined")
max_integrity = 300
var/content_overlays = FALSE //If this is true, the belt will gain overlays based on what it's holding
var/worn_overlays = FALSE //worn counterpart of the above.
/obj/item/storage/belt/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] begins belting [user.p_them()]self with \the [src]! It looks like [user.p_theyre()] trying to commit suicide!</span>")
@@ -23,6 +24,12 @@
add_overlay(M)
..()
/obj/item/storage/belt/worn_overlays(isinhands, icon_file)
. = ..()
if(!isinhands && worn_overlays)
for(var/obj/item/I in contents)
. += I.get_worn_belt_overlay(icon_file)
/obj/item/storage/belt/Initialize()
. = ..()
update_icon()
@@ -653,6 +660,10 @@
icon_state = "sheath"
item_state = "sheath"
w_class = WEIGHT_CLASS_BULKY
content_overlays = TRUE
worn_overlays = TRUE
var/list/fitting_swords = list(/obj/item/melee/sabre, /obj/item/melee/baton/stunsword)
var/starting_sword = /obj/item/melee/sabre
/obj/item/storage/belt/sabre/ComponentInitialize()
. = ..()
@@ -660,35 +671,7 @@
STR.max_items = 1
STR.rustle_sound = FALSE
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.can_hold = typecacheof(list(
/obj/item/melee/sabre
))
/obj/item/storage/belt/sabre/rapier
name = "rapier sheath"
desc = "A black, thin sheath that looks to house only a long thin blade. Feels like its made of metal."
icon_state = "rsheath"
item_state = "rsheath"
force = 5
throwforce = 15
block_chance = 30
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("bashed", "slashes", "prods", "pokes")
/obj/item/storage/belt/sabre/rapier/ComponentInitialize()
. = ..()
GET_COMPONENT(STR, /datum/component/storage)
STR.max_items = 1
STR.rustle_sound = FALSE
STR.max_w_class = WEIGHT_CLASS_BULKY
STR.can_hold = typecacheof(list(
/obj/item/melee/rapier
))
/obj/item/storage/belt/sabre/rapier/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
final_block_chance = 0 //To thin to block bullets
return ..()
STR.can_hold = typecacheof(fitting_swords)
/obj/item/storage/belt/sabre/examine(mob/user)
..()
@@ -707,20 +690,28 @@
to_chat(user, "[src] is empty.")
/obj/item/storage/belt/sabre/update_icon()
icon_state = initial(icon_state)
item_state = initial(item_state)
if(contents.len)
icon_state += "-sabre"
item_state += "-sabre"
if(loc && isliving(loc))
. = ..()
if(isliving(loc))
var/mob/living/L = loc
L.regenerate_icons()
..()
/obj/item/storage/belt/sabre/PopulateContents()
new /obj/item/melee/sabre(src)
update_icon()
new starting_sword(src)
/obj/item/storage/belt/sabre/rapier/PopulateContents()
new /obj/item/melee/rapier(src)
update_icon()
/obj/item/storage/belt/sabre/rapier
name = "rapier sheath"
desc = "A black, thin sheath that looks to house only a long thin blade. Feels like its made of metal."
icon_state = "rsheath"
item_state = "rsheath"
force = 5
throwforce = 15
block_chance = 30
w_class = WEIGHT_CLASS_BULKY
attack_verb = list("bashed", "slashes", "prods", "pokes")
fitting_swords = list(/obj/item/melee/rapier)
starting_sword = /obj/item/melee/rapier
/obj/item/storage/belt/sabre/rapier/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == PROJECTILE_ATTACK)
final_block_chance = 0 //To thin to block bullets
return ..()
+21 -2
View File
@@ -1131,6 +1131,7 @@
name = "Nanotrasen MRE Ration Kit Menu 0"
desc = "A package containing food suspended in an outdated bluespace pocket which lasts for centuries. If you're lucky you may even be able to enjoy the meal without getting food poisoning."
icon_state = "mre"
illustration = null
var/can_expire = TRUE
var/spawner_chance = 2
var/expiration_date
@@ -1184,7 +1185,7 @@
/obj/item/storage/box/mre/menu3
name = "\improper Nanotrasen MRE Ration Kit Menu 3"
desc = "The holy grail of MREs. This item contains the fabled MRE pizza and a sample of coffee instant type 2. Any NT employee lucky enough to get their hands on one of these is truly blessed."
desc = "The holy grail of MREs. This item contains the fabled MRE pizza, spicy nachos and a sample of coffee instant type 2. Any NT employee lucky enough to get their hands on one of these is truly blessed."
icon_state = "menu3"
can_expire = FALSE //always fresh, never expired.
spawner_chance = 1
@@ -1192,11 +1193,29 @@
/obj/item/storage/box/mre/menu3/PopulateContents()
new /obj/item/reagent_containers/food/snacks/pizzaslice/pepperoni(src)
new /obj/item/reagent_containers/food/snacks/breadslice/plain(src)
new /obj/item/reagent_containers/food/snacks/cheesewedge(src)
new /obj/item/reagent_containers/food/snacks/cubannachos(src)
new /obj/item/reagent_containers/food/snacks/grown/chili(src)
new /obj/item/reagent_containers/food/drinks/coffee/type2(src)
new /obj/item/tank/internals/emergency_oxygen(src)
/obj/item/storage/box/mre/menu4
name = "\improper Nanotrasen MRE Ration Kit Menu 4"
/obj/item/storage/box/mre/menu4/safe
spawner_chance = 0
desc = "A package containing food suspended in a bluespace pocket capable of lasting till the end of time."
can_expire = FALSE
/obj/item/storage/box/mre/menu4/PopulateContents()
if(prob(66))
new /obj/item/reagent_containers/food/snacks/salad/boiledrice(src)
else
new /obj/item/reagent_containers/food/snacks/salad/ricebowl(src)
new /obj/item/reagent_containers/food/snacks/burger/tofu(src)
new /obj/item/reagent_containers/food/snacks/salad/fruit(src)
new /obj/item/reagent_containers/food/snacks/cracker(src)
new /obj/item/tank/internals/emergency_oxygen(src)
//Where do I put this?
/obj/item/secbat
name = "Secbat box"
+1 -1
View File
@@ -16,7 +16,7 @@
AddComponent(component_type)
/obj/item/storage/AllowDrop()
return TRUE
return FALSE
/obj/item/storage/contents_explosion(severity, target)
for(var/atom/A in contents)
+2 -2
View File
@@ -10,7 +10,7 @@
. = ..()
if(!. || !istype(M) || M.anchored)
return
do_teleport(M, get_turf(M), 15)
do_teleport(M, get_turf(M), 15, channel = TELEPORT_CHANNEL_BLUESPACE)
/obj/item/melee/baton/cattleprod/teleprod/clowning_around(mob/living/user)
user.visible_message("<span class='danger'>[user] accidentally hits [user.p_them()]self with [src]!</span>", \
@@ -18,7 +18,7 @@
SEND_SIGNAL(user, COMSIG_LIVING_MINOR_SHOCK)
user.Knockdown(stunforce*3)
playsound(loc, 'sound/weapons/egloves.ogg', 50, 1, -1)
if(do_teleport(user, get_turf(user), 50))
if(do_teleport(user, get_turf(user), 50, channel = TELEPORT_CHANNEL_BLUESPACE))
deductcharge(hitcost)
else
deductcharge(hitcost * 0.25)
+9 -1
View File
@@ -90,4 +90,12 @@
var/obj/item/wirecutters/power/cutjaws = new /obj/item/wirecutters/power(drop_location())
to_chat(user, "<span class='notice'>You attach the cutting jaws to [src].</span>")
qdel(src)
user.put_in_active_hand(cutjaws)
user.put_in_active_hand(cutjaws)
/obj/item/crowbar/advanced
name = "advanced crowbar"
desc = "A scientist's almost successful reproduction of an abductor's crowbar, it uses the same technology combined with a handle that can't quite hold it."
icon = 'icons/obj/advancedtools.dmi'
usesound = 'sound/weapons/sonic_jackhammer.ogg'
icon_state = "crowbar"
toolspeed = 0.2
+11 -1
View File
@@ -141,4 +141,14 @@
name = "powered screwdriver"
desc = "An electrical screwdriver, designed to be both precise and quick."
usesound = 'sound/items/drill_use.ogg'
toolspeed = 0.5
toolspeed = 0.5
/obj/item/screwdriver/advanced
name = "advanced screwdriver"
desc = "A classy silver screwdriver with an alien alloy tip, it works almost as well as the real thing."
icon = 'icons/obj/advancedtools.dmi'
icon_state = "screwdriver_a"
item_state = "screwdriver_nuke"
usesound = 'sound/items/pshoom.ogg'
toolspeed = 0.2
random_color = FALSE
@@ -377,4 +377,18 @@
nextrefueltick = world.time + 10
reagents.add_reagent("welding_fuel", 1)
/obj/item/weldingtool/advanced
name = "advanced welding tool"
desc = "A modern welding tool combined with an alien welding tool, it never runs out of fuel and works almost as fast."
icon = 'icons/obj/advancedtools.dmi'
icon_state = "welder"
toolspeed = 0.2
light_intensity = 0
change_icons = 0
/obj/item/weldingtool/advanced/process()
if(get_fuel() <= max_fuel)
reagents.add_reagent("welding_fuel", 1)
..()
#undef WELDER_FUEL_BURN_INTERVAL
+8 -1
View File
@@ -82,7 +82,6 @@
icon = 'icons/obj/abductor.dmi'
icon_state = "cutters"
toolspeed = 0.1
random_color = FALSE
/obj/item/wirecutters/cyborg
@@ -126,3 +125,11 @@
return
else
..()
/obj/item/wirecutters/advanced
name = "advanced wirecutters"
desc = "A set of reproduction alien wirecutters, they have a silver handle with an exceedingly sharp blade."
icon = 'icons/obj/advancedtools.dmi'
icon_state = "cutters"
toolspeed = 0.2
random_color = FALSE
+9 -1
View File
@@ -112,4 +112,12 @@
user.dust()
return OXYLOSS
return OXYLOSS
/obj/item/wrench/advanced
name = "advanced wrench"
desc = "A wrench that uses the same magnetic technology that abductor tools use, but slightly more ineffeciently."
icon = 'icons/obj/advancedtools.dmi'
icon_state = "wrench"
usesound = 'sound/effects/empulse.ogg'
toolspeed = 0.2
@@ -317,9 +317,6 @@
new stack_type(get_turf(loc))
qdel(src)
/obj/item/chair/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK)
if(attack_type == UNARMED_ATTACK && prob(hit_reaction_chance))
owner.visible_message("<span class='danger'>[owner] fends off [attack_text] with [src]!</span>")
@@ -338,7 +335,6 @@
C.Knockdown(20)
smash(user)
/obj/item/chair/stool
name = "stool"
icon_state = "stool_toppled"
@@ -352,6 +348,70 @@
item_state = "stool_bar"
origin_type = /obj/structure/chair/stool/bar
//////////////////////////
//Brass & Bronze stools!//
//////////////////////////
/obj/structure/chair/stool/bar/brass
name = "brass bar stool"
desc = "A brass bar stool with red silk for a pillow."
icon_state = "barbrass"
item_chair = /obj/item/chair/stool/bar/brass
buildstacktype = /obj/item/stack/tile/brass
buildstackamount = 1
/obj/structure/chair/stool/bar/bronze
name = "bronze bar stool"
desc = "A bronze bar stool with red silk for a pillow."
icon_state = "barbrass"
item_chair = /obj/item/chair/stool/bar/bronze
buildstacktype = /obj/item/stack/tile/bronze
buildstackamount = 1
/obj/structure/chair/stool/brass
name = "brass stool"
desc = "A brass stool with a silk top for comfort."
icon_state = "stoolbrass"
item_chair = /obj/item/chair/stool/brass
buildstacktype = /obj/item/stack/tile/brass
buildstackamount = 1
/obj/structure/chair/stool/bronze
name = "bronze stool"
desc = "A bronze stool with a silk top for comfort."
icon_state = "stoolbrass"
item_chair = /obj/item/chair/stool/bronze
buildstacktype = /obj/item/stack/tile/bronze
buildstackamount = 1
/obj/item/chair/stool/brass
name = "brass stool"
icon_state = "stoolbrass_toppled"
item_state = "stoolbrass"
origin_type = /obj/structure/chair/stool/brass
/obj/item/chair/stool/bar/brass
name = "brass bar stool"
icon_state = "barbrass_toppled"
item_state = "stoolbrass_bar"
origin_type = /obj/structure/chair/stool/bar/brass
/obj/item/chair/stool/bronze
name = "bronze stool"
icon_state = "stoolbrass_toppled"
item_state = "stoolbrass"
origin_type = /obj/structure/chair/stool/bronze
/obj/item/chair/stool/bar/bronze
name = "bronze bar stool"
icon_state = "barbrass_toppled"
item_state = "stoolbrass_bar"
origin_type = /obj/structure/chair/stool/bar/bronze
/////////////////////////////////
//End of Brass & Bronze stools!//
/////////////////////////////////
/obj/item/chair/stool/narsie_act()
return //sturdy enough to ignore a god
@@ -34,7 +34,8 @@
var/delivery_icon = "deliverycloset" //which icon to use when packagewrapped. null to be unwrappable.
var/anchorable = TRUE
var/icon_welded = "welded"
var/obj/item/electronics/airlock/lockerelectronics //Installed electronics
var/lock_in_use = FALSE //Someone is doing some stuff with the lock here, better not proceed further
/obj/structure/closet/Initialize(mapload)
. = ..()
@@ -42,47 +43,56 @@
PopulateContents()
if(mapload && !opened) // if closed, any item at the crate's loc is put in the contents
take_contents()
if(secure)
lockerelectronics = new(src)
lockerelectronics.accesses = req_access
//USE THIS TO FILL IT, NOT INITIALIZE OR NEW
/obj/structure/closet/proc/PopulateContents()
return
/obj/structure/closet/Destroy()
dump_contents()
dump_contents(override = FALSE)
return ..()
/obj/structure/closet/update_icon()
cut_overlays()
if(!opened)
if(opened & icon_door_override)
add_overlay("[icon_door]_open")
layer = OBJ_LAYER
if(icon_door)
add_overlay("[icon_door]_door")
else
add_overlay("[icon_state]_door")
if(welded)
add_overlay(icon_welded)
if(secure && !broken)
if(locked)
add_overlay("locked")
else
add_overlay("unlocked")
return
else if(opened)
add_overlay("[icon_state]_open")
return
if(icon_door)
add_overlay("[icon_door]_door")
else
layer = BELOW_OBJ_LAYER
if(icon_door_override)
add_overlay("[icon_door]_open")
else
add_overlay("[icon_state]_open")
add_overlay("[icon_state]_door")
if(welded)
add_overlay("welded")
if(!secure)
return
if(broken)
add_overlay("off")
add_overlay("sparking")
else if(locked)
add_overlay("locked")
else
add_overlay("unlocked")
/obj/structure/closet/examine(mob/user)
..()
if(welded)
to_chat(user, "<span class='notice'>It's welded shut.</span>")
to_chat(user, "<span class='notice'>It's <b>welded</b> shut.</span>")
if(anchored)
to_chat(user, "<span class='notice'>It is <b>bolted</b> to the ground.</span>")
if(opened)
to_chat(user, "<span class='notice'>The parts are <b>welded</b> together.</span>")
else if(secure && !opened)
else if(broken)
to_chat(user, "<span class='notice'>The lock is <b>screwed</b> in.</span>")
else if(secure)
to_chat(user, "<span class='notice'>Alt-click to [locked ? "unlock" : "lock"].</span>")
if(isliving(user))
var/mob/living/L = user
@@ -117,9 +127,37 @@
return FALSE
return TRUE
/obj/structure/closet/proc/dump_contents()
/obj/structure/closet/proc/can_lock(mob/living/user, var/check_access = TRUE) //set check_access to FALSE if you only need to check if a locker has a functional lock rather than access
if(!secure)
return FALSE
if(broken)
to_chat(user, "<span class='notice'>[src] is broken!</span>")
return FALSE
if(QDELETED(lockerelectronics) && !locked) //We want to be able to unlock it regardless of electronics, but only lockable with electronics
to_chat(user, "<span class='notice'>[src] is missing locker electronics!</span>")
return FALSE
if(!check_access)
return TRUE
if(allowed(user))
return TRUE
to_chat(user, "<span class='notice'>Access denied.</span>")
/obj/structure/closet/proc/togglelock(mob/living/user)
add_fingerprint(user)
if(opened)
return
if(!can_lock(user))
return
locked = !locked
user.visible_message("<span class='notice'>[user] [locked ? null : "un"]locks [src].</span>",
"<span class='notice'>You [locked ? null : "un"]lock [src].</span>")
update_icon()
/obj/structure/closet/proc/dump_contents(var/override = TRUE) //Override is for not revealing the locker electronics when you open the locker, for example
var/atom/L = drop_location()
for(var/atom/movable/AM in src)
if(AM == lockerelectronics && override)
continue
AM.forceMove(L)
if(throwing) // you keep some momentum when getting out of a thrown closet
step(AM, dir)
@@ -207,6 +245,73 @@
else
return open(user)
/obj/structure/closet/proc/bust_open()
welded = FALSE //applies to all lockers
locked = FALSE //applies to critter crates and secure lockers only
broken = TRUE //applies to secure lockers only
open()
/obj/structure/closet/proc/handle_lock_addition(mob/user, obj/item/electronics/airlock/E)
add_fingerprint(user)
if(lock_in_use)
to_chat(user, "<span class='notice'>Wait for work on [src] to be done first!</span>")
return
if(secure)
to_chat(user, "<span class='notice'>This locker already has a lock!</span>")
return
if(broken)
to_chat(user, "<span class='notice'><b>Unscrew</b> the broken lock first!</span>")
return
if(!istype(E))
return
user.visible_message("<span class='notice'>[user] begins installing a lock on [src]...</span>","<span class='notice'>You begin installing a lock on [src]...</span>")
lock_in_use = TRUE
playsound(loc, 'sound/items/screwdriver.ogg', 50, 1)
if(!do_after(user, 60, target = src))
lock_in_use = FALSE
return
lock_in_use = FALSE
to_chat(user, "<span class='notice'>You finish the lock on [src]!</span>")
E.forceMove(src)
lockerelectronics = E
req_access = E.accesses
secure = TRUE
update_icon()
return TRUE
/obj/structure/closet/proc/handle_lock_removal(mob/user, obj/item/screwdriver/S)
if(lock_in_use)
to_chat(user, "<span class='notice'>Wait for work on [src] to be done first!</span>")
return
if(locked)
to_chat(user, "<span class='notice'>Unlock it first!</span>")
return
if(!secure)
to_chat(user, "<span class='notice'>[src] doesn't have a lock that you can remove!</span>")
return
if(!istype(S))
return
var/brokenword = broken ? "broken " : null
user.visible_message("<span class='notice'>[user] begins removing the [brokenword]lock on [src]...</span>","<span class='notice'>You begin removing the [brokenword]lock on [src]...</span>")
playsound(loc, S.usesound, 50, 1)
lock_in_use = TRUE
if(!do_after(user, 100 * S.toolspeed, target = src))
lock_in_use = FALSE
return
to_chat(user, "<span class='notice'>You remove the [brokenword]lock from [src]!</span>")
if(!QDELETED(lockerelectronics))
lockerelectronics.add_fingerprint(user)
lockerelectronics.forceMove(user.loc)
lockerelectronics = null
req_access = null
secure = FALSE
broken = FALSE
locked = FALSE
lock_in_use = FALSE
update_icon()
return TRUE
/obj/structure/closet/deconstruct(disassembled = TRUE)
if(ispath(material_drop) && material_drop_amount && !(flags_1 & NODECONSTRUCT_1))
new material_drop(loc, material_drop_amount)
@@ -247,7 +352,11 @@
deconstruct(TRUE)
return
if(user.transferItemToLoc(W, drop_location())) // so we put in unlit welder too
return
return TRUE
else if(istype(W, /obj/item/electronics/airlock))
handle_lock_addition(user, W)
else if(istype(W, /obj/item/screwdriver))
handle_lock_removal(user, W)
else if(istype(W, /obj/item/weldingtool) && can_weld_shut)
if(!W.tool_start_check(user, amount=0))
return
@@ -258,7 +367,7 @@
return
welded = !welded
after_weld(welded)
user.visible_message("<span class='notice'>[user] [welded ? "welds shut" : "unwelded"] \the [src].</span>",
user.visible_message("<span class='notice'>[user] [welded ? "welds shut" : "unwelds"] \the [src].</span>",
"<span class='notice'>You [welded ? "weld" : "unwelded"] \the [src] with \the [W].</span>",
"<span class='italics'>You hear welding.</span>")
update_icon()
@@ -401,20 +510,12 @@
if(user.loc == src) //so we don't get the message if we resisted multiple times and succeeded.
to_chat(user, "<span class='warning'>You fail to break out of [src]!</span>")
/obj/structure/closet/proc/bust_open()
welded = FALSE //applies to all lockers
locked = FALSE //applies to critter crates and secure lockers only
broken = TRUE //applies to secure lockers only
open()
/obj/structure/closet/AltClick(mob/user)
..()
if(!user.canUseTopic(src, BE_CLOSE) || !isturf(loc))
if(!user.canUseTopic(src, be_close=TRUE) || !isturf(loc))
to_chat(user, "<span class='warning'>You can't do that right now!</span>")
return
if(opened || !secure)
return
else
togglelock(user)
togglelock(user)
/obj/structure/closet/CtrlShiftClick(mob/living/user)
if(!HAS_TRAIT(user, TRAIT_SKITTISH))
@@ -423,20 +524,6 @@
return
dive_into(user)
/obj/structure/closet/proc/togglelock(mob/living/user, silent)
if(secure && !broken)
if(allowed(user))
if(iscarbon(user))
add_fingerprint(user)
locked = !locked
user.visible_message("<span class='notice'>[user] [locked ? null : "un"]locks [src].</span>",
"<span class='notice'>You [locked ? null : "un"]lock [src].</span>")
update_icon()
else if(!silent)
to_chat(user, "<span class='notice'>Access Denied</span>")
else if(secure && broken)
to_chat(user, "<span class='warning'>\The [src] is broken!</span>")
/obj/structure/closet/emag_act(mob/user)
if(secure && !broken)
user.visible_message("<span class='warning'>Sparks fly from [src]!</span>",
@@ -445,6 +532,9 @@
playsound(src, "sparks", 50, 1)
broken = TRUE
locked = FALSE
if(!QDELETED(lockerelectronics))
qdel(lockerelectronics)
lockerelectronics = null
update_icon()
/obj/structure/closet/get_remote_view_fullscreens(mob/user)
@@ -458,16 +548,19 @@
if (!(. & EMP_PROTECT_CONTENTS))
for(var/obj/O in src)
O.emp_act(severity)
if(secure && !broken && !(. & EMP_PROTECT_SELF))
if(prob(50 / severity))
locked = !locked
update_icon()
if(prob(20 / severity) && !opened)
if(!locked)
open()
else
req_access = list()
req_access += pick(get_all_accesses())
if(!secure || broken)
return ..()
if(prob(50 / severity))
locked = !locked
update_icon()
if(prob(20 / severity) && !opened)
if(!locked)
open()
else
req_access = list()
req_access += pick(get_all_accesses())
if(!QDELETED(lockerelectronics))
lockerelectronics.accesses = req_access
/obj/structure/closet/contents_explosion(severity, target)
for(var/atom/A in contents)
@@ -49,6 +49,12 @@
return 1
return 0
/obj/structure/closet/body_bag/handle_lock_addition()
return
/obj/structure/closet/body_bag/handle_lock_removal()
return
/obj/structure/closet/body_bag/MouseDrop(over_object, src_location, over_location)
. = ..()
if(over_object == usr && Adjacent(usr) && (in_range(src, usr) || usr.contents.Find(src)))
@@ -57,6 +57,11 @@
I.alpha = 0
animate(I, pixel_z = 32, alpha = 255, time = 5, easing = ELASTIC_EASING)
/obj/structure/closet/cardboard/handle_lock_addition() //Whoever heard of a lockable cardboard box anyway
return
/obj/structure/closet/cardboard/handle_lock_removal()
return
/obj/structure/closet/cardboard/metal
name = "large metal box"
@@ -358,3 +358,8 @@
new /obj/item/clothing/shoes/workboots/mining(src)
new /obj/item/storage/backpack/satchel/explorer(src)
/obj/structure/closet/coffin/handle_lock_addition()
return
/obj/structure/closet/coffin/handle_lock_removal()
return
@@ -4,6 +4,18 @@
req_access = list(ACCESS_ALL_PERSONAL_LOCKERS)
var/registered_name = null
/obj/structure/closet/secure_closet/personal/examine(mob/user)
..()
if(registered_name)
to_chat(user, "<span class='notice'>The display reads, \"Owned by [registered_name]\".</span>")
/obj/structure/closet/secure_closet/personal/check_access(obj/item/card/id/I)
. = ..()
if(!I || !istype(I))
return
if(registered_name == I.registered_name)
return TRUE
/obj/structure/closet/secure_closet/personal/PopulateContents()
..()
if(prob(50))
@@ -33,21 +45,21 @@
/obj/structure/closet/secure_closet/personal/attackby(obj/item/W, mob/user, params)
var/obj/item/card/id/I = W.GetID()
if(istype(I))
if(broken)
to_chat(user, "<span class='danger'>It appears to be broken.</span>")
return
if(!I || !I.registered_name)
return
if(allowed(user) || !registered_name || (istype(I) && (registered_name == I.registered_name)))
//they can open all lockers, or nobody owns this, or they own this locker
locked = !locked
update_icon()
if(!registered_name)
registered_name = I.registered_name
desc = "Owned by [I.registered_name]."
else
to_chat(user, "<span class='danger'>Access Denied.</span>")
else
if(!I || !istype(I))
return ..()
if(!can_lock(user, FALSE)) //Can't do anything if there isn't a lock!
return
if(I.registered_name && !registered_name)
to_chat(user, "<span class='notice'>You claim [src].</span>")
registered_name = I.registered_name
else
..()
/obj/structure/closet/secure_closet/personal/handle_lock_addition() //If lock construction is successful we don't care what access the electronics had, so we override it
if(..())
req_access = list(ACCESS_ALL_PERSONAL_LOCKERS)
lockerelectronics.accesses = req_access
/obj/structure/closet/secure_closet/personal/handle_lock_removal()
if(..())
registered_name = null
@@ -54,6 +54,12 @@
manifest = null
update_icon()
/obj/structure/closet/crate/handle_lock_addition()
return
/obj/structure/closet/crate/handle_lock_removal()
return
/obj/structure/closet/crate/proc/tear_manifest(mob/user)
to_chat(user, "<span class='notice'>You tear the manifest off of [src].</span>")
playsound(src, 'sound/items/poster_ripped.ogg', 75, 1)
+1 -1
View File
@@ -79,4 +79,4 @@
var/n_color = input(H, "Choose your [garment_type]'\s color.", "Character Preference", default_color) as color|null
if(!n_color || !H.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return default_color
return n_color
return sanitize_hexcolor(n_color, include_crunch= TRUE)
@@ -0,0 +1,174 @@
#define BREAKER_ANIMATION_LENGTH 32
#define BREAKER_SLAT_RAISED 1
#define BREAKER_SLAT_MOVING 2
#define BREAKER_SLAT_DROPPED 3
#define BREAKER_ACTIVATE_DELAY 30
#define BREAKER_WRENCH_DELAY 10
#define BREAKER_ACTION_INUSE 5
#define BREAKER_ACTION_WRENCH 6
/obj/structure/femur_breaker
name = "femur breaker"
desc = "A large structure used to break the femurs of traitors and treasonists."
icon = 'icons/obj/femur_breaker.dmi'
icon_state = "breaker_raised"
can_buckle = TRUE
anchored = TRUE
density = TRUE
max_buckled_mobs = 1
buckle_lying = TRUE
buckle_prevents_pull = TRUE
layer = ABOVE_MOB_LAYER
var/slat_status = BREAKER_SLAT_RAISED
var/current_action = 0 // What's currently happening to the femur breaker
/obj/structure/femur_breaker/examine(mob/user)
..()
var/msg = ""
msg += "It is [anchored ? "secured to the floor." : "unsecured."]<br/>"
if (slat_status == BREAKER_SLAT_RAISED)
msg += "The breaker slat is in a neutral position."
else
msg += "The breaker slat is lowered, and must be raised."
if (LAZYLEN(buckled_mobs))
msg += "<br/>"
msg += "Someone appears to be strapped in. You can help them unbuckle, or activate the femur breaker."
to_chat(user, msg)
return msg
/obj/structure/femur_breaker/attack_hand(mob/user)
add_fingerprint(user)
// Currently being used
if (current_action)
return
switch (slat_status)
if (BREAKER_SLAT_MOVING)
return
if (BREAKER_SLAT_DROPPED)
slat_status = BREAKER_SLAT_MOVING
icon_state = "breaker_raise"
addtimer(CALLBACK(src, .proc/raise_slat), BREAKER_ANIMATION_LENGTH)
return
if (BREAKER_SLAT_RAISED)
if (LAZYLEN(buckled_mobs))
if (user.a_intent == INTENT_HARM)
user.visible_message("<span class='warning'>[user] begins to pull the lever!</span>",
"<span class='warning'>You begin to the pull the lever.</span>")
current_action = BREAKER_ACTION_INUSE
if (do_after(user, BREAKER_ACTIVATE_DELAY, target = src) && slat_status == BREAKER_SLAT_RAISED)
current_action = 0
slat_status = BREAKER_SLAT_MOVING
icon_state = "breaker_drop"
drop_slat(user)
else
current_action = 0
else
var/mob/living/carbon/human/H = buckled_mobs[1]
if (H)
H.regenerate_icons()
unbuckle_all_mobs()
else //HERE
slat_status = BREAKER_SLAT_DROPPED
icon_state = "breaker_drop"
/obj/structure/femur_breaker/proc/damage_leg(mob/living/carbon/human/H)
H.say("AAAAAAAAAAAAAAAAAAAAAAAAAAAHHHHHHHHHHHHHHHHHHH!!", forced = "femur broken")
H.apply_damage(150, BRUTE, pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG))
/obj/structure/femur_breaker/proc/raise_slat()
slat_status = BREAKER_SLAT_RAISED
icon_state = "breaker_raised"
/obj/structure/femur_breaker/proc/drop_slat(mob/user)
if (buckled_mobs.len)
var/mob/living/carbon/human/H = buckled_mobs[1]
if (!H)
return
playsound(src, 'sound/effects/femur_breaker.ogg', 100, FALSE)
H.Stun(BREAKER_ANIMATION_LENGTH)
addtimer(CALLBACK(src, .proc/damage_leg, H), BREAKER_ANIMATION_LENGTH, TIMER_UNIQUE)
log_combat(user, H, "femur broke", src)
slat_status = BREAKER_SLAT_DROPPED
icon_state = "breaker"
/obj/structure/femur_breaker/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
if (!anchored)
to_chat(usr, "<span class='warning'>The [src] needs to be wrenched to the floor!</span>")
return FALSE
if (!istype(M, /mob/living/carbon/human))
to_chat(usr, "<span class='warning'>It doesn't look like [M.p_they()] can fit into this properly!</span>")
return FALSE
if (slat_status != BREAKER_SLAT_RAISED)
to_chat(usr, "<span class='warning'>The femur breaker must be in its neutral position before buckling someone in!</span>")
return FALSE
return ..(M, force, FALSE)
/obj/structure/femur_breaker/post_buckle_mob(mob/living/M)
if (!istype(M, /mob/living/carbon/human))
return
var/mob/living/carbon/human/H = M
if (H.dna)
if (H.dna.species)
var/datum/species/S = H.dna.species
if (!istype(S))
unbuckle_all_mobs()
else
unbuckle_all_mobs()
else
unbuckle_all_mobs()
..()
/obj/structure/femur_breaker/can_be_unfasten_wrench(mob/user, silent)
if (LAZYLEN(buckled_mobs))
if (!silent)
to_chat(user, "<span class='warning'>Can't unfasten, someone's strapped in!</span>")
return FAILED_UNFASTEN
if (current_action)
return FAILED_UNFASTEN
return ..()
/obj/structure/femur_breaker/wrench_act(mob/living/user, obj/item/I)
if (current_action)
return
current_action = BREAKER_ACTION_WRENCH
if (do_after(user, BREAKER_WRENCH_DELAY, target = src))
current_action = 0
default_unfasten_wrench(user, I, 0)
setDir(SOUTH)
return TRUE
else
current_action = 0
#undef BREAKER_ANIMATION_LENGTH
#undef BREAKER_SLAT_RAISED
#undef BREAKER_SLAT_MOVING
#undef BREAKER_SLAT_DROPPED
#undef BREAKER_ACTIVATE_DELAY
#undef BREAKER_WRENCH_DELAY
#undef BREAKER_ACTION_INUSE
#undef BREAKER_ACTION_WRENCH