Merge branch 'master' into upstream-merge-30544
This commit is contained in:
+3
-2
@@ -304,6 +304,7 @@
|
||||
/atom/proc/ex_act(severity, target)
|
||||
set waitfor = FALSE
|
||||
contents_explosion(severity, target)
|
||||
SendSignal(COMSIG_ATOM_EX_ACT, severity, target)
|
||||
|
||||
/atom/proc/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
@@ -468,8 +469,8 @@ GLOBAL_LIST_EMPTY(blood_splatter_icons)
|
||||
/atom/proc/singularity_act()
|
||||
return
|
||||
|
||||
/atom/proc/singularity_pull()
|
||||
return
|
||||
/atom/proc/singularity_pull(obj/singularity/S, current_size)
|
||||
SendSignal(COMSIG_ATOM_SING_PULL, S, current_size)
|
||||
|
||||
/atom/proc/acid_act(acidpwr, acid_volume)
|
||||
return
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
to_chat(user, "<span class='inathneq'>An emergency shuttle has arrived and this prism is no longer useful; attempt to activate it to gain a partial refund of components used.</span>")
|
||||
else
|
||||
var/efficiency = get_efficiency_mod(TRUE)
|
||||
to_chat(user, "<span class='inathneq_small'>It requires at least <b>[get_delay_cost()]W</b> of power to attempt to delay the arrival of an emergency shuttle by <b>[2 * efficiency]</b> minutes.</span>")
|
||||
to_chat(user, "<span class='inathneq_small'>This cost increases by <b>[delay_cost_increase]W</b> for every previous activation.</span>")
|
||||
to_chat(user, "<span class='inathneq_small'>It requires at least <b>[DisplayPower(get_delay_cost())]</b> of power to attempt to delay the arrival of an emergency shuttle by <b>[2 * efficiency]</b> minutes.</span>")
|
||||
to_chat(user, "<span class='inathneq_small'>This cost increases by <b>[DisplayPower(delay_cost_increase)]</b> for every previous activation.</span>")
|
||||
|
||||
/obj/structure/destructible/clockwork/powered/prolonging_prism/forced_disable(bad_effects)
|
||||
if(active)
|
||||
@@ -126,7 +126,7 @@
|
||||
if(!hex_combo)
|
||||
hex_combo = mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)
|
||||
else
|
||||
hex_combo.overlays += mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER)
|
||||
hex_combo.add_overlay(mutable_appearance('icons/effects/64x64.dmi', n, RIPPLE_LAYER))
|
||||
if(hex_combo) //YOU BUILT A HEXAGON
|
||||
hex_combo.pixel_x = -16
|
||||
hex_combo.pixel_y = -16
|
||||
|
||||
@@ -309,8 +309,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
owner_AI.nuking = TRUE
|
||||
owner_AI.doomsday_device = DOOM
|
||||
owner_AI.doomsday_device.start()
|
||||
for(var/pinpointer in GLOB.pinpointer_list)
|
||||
var/obj/item/pinpointer/P = pinpointer
|
||||
for(var/obj/item/pinpointer/nuke/P in GLOB.pinpointer_list)
|
||||
P.switch_mode_to(TRACK_MALF_AI) //Pinpointers start tracking the AI wherever it goes
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
diff a/code/game/gamemodes/malfunction/Malf_Modules.dm b/code/game/gamemodes/malfunction/Malf_Modules.dm (rejected hunks)
|
||||
@@ -309,8 +309,7 @@ GLOBAL_LIST_INIT(blacklisted_malf_machines, typecacheof(list(
|
||||
owner_AI.nuking = TRUE
|
||||
owner_AI.doomsday_device = DOOM
|
||||
owner_AI.doomsday_device.start()
|
||||
- for(var/pinpointer in GLOB.pinpointer_list)
|
||||
- var/obj/item/weapon/pinpointer/P = pinpointer
|
||||
+ for(var/obj/item/weapon/pinpointer/nuke/P in GLOB.pinpointer_list)
|
||||
P.switch_mode_to(TRACK_MALF_AI) //Pinpointers start tracking the AI wherever it goes
|
||||
qdel(src)
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
var/list/abductee_minds
|
||||
var/flash = " - || - "
|
||||
var/obj/machinery/abductor/console/console
|
||||
var/message_cooldown = 0
|
||||
var/breakout_time = 0.75
|
||||
|
||||
/obj/machinery/abductor/experiment/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !target.Adjacent(user) || !ishuman(target))
|
||||
@@ -40,25 +42,23 @@
|
||||
/obj/machinery/abductor/experiment/relaymove(mob/user)
|
||||
if(user.stat != CONSCIOUS)
|
||||
return
|
||||
container_resist(user)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
|
||||
/obj/machinery/abductor/experiment/container_resist(mob/living/user)
|
||||
var/breakout_time = 600
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about a minute.)</span>")
|
||||
user.visible_message("<span class='italics'>You hear a metallic creaking from [src]!</span>")
|
||||
|
||||
if(do_after(user,(breakout_time), target = src))
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
|
||||
return
|
||||
|
||||
visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>")
|
||||
to_chat(user, "<span class='notice'>You successfully break out of [src]!</span>")
|
||||
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
|
||||
/obj/machinery/abductor/experiment/proc/dissection_icon(mob/living/carbon/human/H)
|
||||
var/icon/photo = null
|
||||
var/g = (H.gender == FEMALE) ? "f" : "m"
|
||||
|
||||
@@ -325,7 +325,7 @@
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
back = /obj/item/storage/backpack
|
||||
ears = /obj/item/device/radio/headset/syndicate/alt
|
||||
l_pocket = /obj/item/pinpointer/syndicate
|
||||
l_pocket = /obj/item/pinpointer/nuke/syndicate
|
||||
id = /obj/item/card/id/syndicate
|
||||
belt = /obj/item/gun/ballistic/automatic/pistol
|
||||
backpack_contents = list(/obj/item/storage/box/syndie=1)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
diff a/code/game/gamemodes/nuclear/nuclear.dm b/code/game/gamemodes/nuclear/nuclear.dm (rejected hunks)
|
||||
@@ -325,7 +325,7 @@
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
back = /obj/item/weapon/storage/backpack
|
||||
ears = /obj/item/device/radio/headset/syndicate/alt
|
||||
- l_pocket = /obj/item/weapon/pinpointer/syndicate
|
||||
+ l_pocket = /obj/item/weapon/pinpointer/nuke/syndicate
|
||||
id = /obj/item/weapon/card/id/syndicate
|
||||
belt = /obj/item/weapon/gun/ballistic/automatic/pistol
|
||||
backpack_contents = list(/obj/item/weapon/storage/box/syndie=1)
|
||||
@@ -362,9 +362,9 @@
|
||||
if(safety)
|
||||
if(timing)
|
||||
set_security_level(previous_level)
|
||||
for(var/obj/item/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(initial(S.mode))
|
||||
S.nuke_warning = FALSE
|
||||
S.alert = FALSE
|
||||
timing = FALSE
|
||||
bomb_set = TRUE
|
||||
detonation_timer = null
|
||||
@@ -381,16 +381,16 @@
|
||||
bomb_set = TRUE
|
||||
set_security_level("delta")
|
||||
detonation_timer = world.time + (timer_set * 10)
|
||||
for(var/obj/item/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(TRACK_INFILTRATOR)
|
||||
countdown.start()
|
||||
else
|
||||
bomb_set = FALSE
|
||||
detonation_timer = null
|
||||
set_security_level(previous_level)
|
||||
for(var/obj/item/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(initial(S.mode))
|
||||
S.nuke_warning = FALSE
|
||||
S.alert = FALSE
|
||||
countdown.stop()
|
||||
update_icon()
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
diff a/code/game/gamemodes/nuclear/nuclearbomb.dm b/code/game/gamemodes/nuclear/nuclearbomb.dm (rejected hunks)
|
||||
@@ -362,9 +362,9 @@
|
||||
if(safety)
|
||||
if(timing)
|
||||
set_security_level(previous_level)
|
||||
- for(var/obj/item/weapon/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
+ for(var/obj/item/weapon/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(initial(S.mode))
|
||||
- S.nuke_warning = FALSE
|
||||
+ S.alert = FALSE
|
||||
timing = FALSE
|
||||
bomb_set = TRUE
|
||||
detonation_timer = null
|
||||
@@ -381,16 +381,16 @@
|
||||
bomb_set = TRUE
|
||||
set_security_level("delta")
|
||||
detonation_timer = world.time + (timer_set * 10)
|
||||
- for(var/obj/item/weapon/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
+ for(var/obj/item/weapon/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(TRACK_INFILTRATOR)
|
||||
countdown.start()
|
||||
else
|
||||
bomb_set = FALSE
|
||||
detonation_timer = null
|
||||
set_security_level(previous_level)
|
||||
- for(var/obj/item/weapon/pinpointer/syndicate/S in GLOB.pinpointer_list)
|
||||
+ for(var/obj/item/weapon/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list)
|
||||
S.switch_mode_to(initial(S.mode))
|
||||
- S.nuke_warning = FALSE
|
||||
+ S.alert = FALSE
|
||||
countdown.stop()
|
||||
update_icon()
|
||||
|
||||
@@ -1,56 +1,7 @@
|
||||
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
|
||||
/obj/item/pinpointer
|
||||
name = "pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "pinoff"
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/active = FALSE
|
||||
var/atom/movable/target = null //The thing we're searching for
|
||||
var/atom/movable/constant_target = null //The thing we're always focused on, if we're in the right mode
|
||||
var/target_x = 0 //The target coordinates if we're tracking those
|
||||
var/target_y = 0
|
||||
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
|
||||
var/nuke_warning = FALSE // If we've set off a miniature alarm about an armed nuke
|
||||
var/mode = TRACK_NUKE_DISK //What are we looking for?
|
||||
/obj/item/pinpointer/nuke
|
||||
var/mode = TRACK_NUKE_DISK
|
||||
|
||||
/obj/item/pinpointer/New()
|
||||
..()
|
||||
GLOB.pinpointer_list += src
|
||||
|
||||
/obj/item/pinpointer/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.pinpointer_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/pinpointer/attack_self(mob/living/user)
|
||||
active = !active
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
icon_state = "pin[active ? "onnull" : "off"]"
|
||||
if(active)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
target = null //Restarting the pinpointer forces a target reset
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
|
||||
/obj/item/pinpointer/attackby(obj/item/I, mob/living/user, params)
|
||||
if(mode != TRACK_ATOM)
|
||||
return ..()
|
||||
user.visible_message("<span class='notice'>[user] tunes [src] to [I].</span>", "<span class='notice'>You fine-tune [src]'s tracking to track [I].</span>")
|
||||
playsound(src, 'sound/machines/click.ogg', 50, 1)
|
||||
constant_target = I
|
||||
|
||||
/obj/item/pinpointer/examine(mob/user)
|
||||
/obj/item/pinpointer/nuke/examine(mob/user)
|
||||
..()
|
||||
var/msg = "Its tracking indicator reads "
|
||||
switch(mode)
|
||||
@@ -60,12 +11,6 @@
|
||||
msg += "\"01000001 01001001\"."
|
||||
if(TRACK_INFILTRATOR)
|
||||
msg += "\"vasvygengbefuvc\"."
|
||||
if(TRACK_OPERATIVES)
|
||||
msg += "\"[target ? "Operative [target]" : "friends"]\"."
|
||||
if(TRACK_ATOM)
|
||||
msg += "\"[initial(constant_target.name)]\"."
|
||||
if(TRACK_COORDINATES)
|
||||
msg += "\"([target_x], [target_y])\"."
|
||||
else
|
||||
msg = "Its tracking indicator is blank."
|
||||
to_chat(user, msg)
|
||||
@@ -73,22 +18,20 @@
|
||||
if(bomb.timing)
|
||||
to_chat(user, "Extreme danger. Arming signal detected. Time remaining: [bomb.get_time_left()]")
|
||||
|
||||
/obj/item/pinpointer/process()
|
||||
if(!active)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return
|
||||
scan_for_target()
|
||||
point_to_target()
|
||||
my_god_jc_a_bomb()
|
||||
addtimer(CALLBACK(src, .proc/refresh_target), 50, TIMER_UNIQUE)
|
||||
/obj/item/pinpointer/nuke/process()
|
||||
..()
|
||||
if(active) // If shit's going down
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.nuke_list)
|
||||
if(bomb.timing)
|
||||
if(!alert)
|
||||
alert = TRUE
|
||||
playsound(src, 'sound/items/nuke_toy_lowpower.ogg', 50, 0)
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
to_chat(L, "<span class='userdanger'>Your [name] vibrates and lets out a tinny alarm. Uh oh.</span>")
|
||||
|
||||
/obj/item/pinpointer/proc/scan_for_target() //Looks for whatever it's tracking
|
||||
if(target)
|
||||
if(isliving(target))
|
||||
var/mob/living/L = target
|
||||
if(L.stat == DEAD)
|
||||
target = null
|
||||
return
|
||||
/obj/item/pinpointer/nuke/scan_for_target()
|
||||
target = null
|
||||
switch(mode)
|
||||
if(TRACK_NUKE_DISK)
|
||||
var/obj/item/disk/nuclear/N = locate() in GLOB.poi_list
|
||||
@@ -104,76 +47,36 @@
|
||||
target = A
|
||||
if(TRACK_INFILTRATOR)
|
||||
target = SSshuttle.getShuttle("syndicate")
|
||||
if(TRACK_OPERATIVES)
|
||||
var/list/possible_targets = list()
|
||||
var/turf/here = get_turf(src)
|
||||
for(var/V in SSticker.mode.syndicates)
|
||||
var/datum/mind/M = V
|
||||
if(M.current && M.current.stat != DEAD)
|
||||
possible_targets |= M.current
|
||||
var/mob/living/closest_operative = get_closest_atom(/mob/living/carbon/human, possible_targets, here)
|
||||
if(closest_operative)
|
||||
target = closest_operative
|
||||
if(TRACK_ATOM)
|
||||
if(constant_target)
|
||||
target = constant_target
|
||||
if(TRACK_COORDINATES)
|
||||
var/turf/T = get_turf(src)
|
||||
target = locate(target_x, target_y, T.z)
|
||||
..()
|
||||
|
||||
/obj/item/pinpointer/proc/point_to_target() //If we found what we're looking for, show the distance and direction
|
||||
if(!active)
|
||||
return
|
||||
if(!target || (mode == TRACK_ATOM && !constant_target))
|
||||
icon_state = "pinon[nuke_warning ? "alert" : ""]null"
|
||||
return
|
||||
var/turf/here = get_turf(src)
|
||||
var/turf/there = get_turf(target)
|
||||
if(here.z != there.z)
|
||||
icon_state = "pinon[nuke_warning ? "alert" : ""]null"
|
||||
return
|
||||
if(get_dist_euclidian(here,there)<=minimum_range)
|
||||
icon_state = "pinon[nuke_warning ? "alert" : ""]direct"
|
||||
else
|
||||
setDir(get_dir(here, there))
|
||||
switch(get_dist(here, there))
|
||||
if(1 to 8)
|
||||
icon_state = "pinon[nuke_warning ? "alert" : "close"]"
|
||||
if(9 to 16)
|
||||
icon_state = "pinon[nuke_warning ? "alert" : "medium"]"
|
||||
if(16 to INFINITY)
|
||||
icon_state = "pinon[nuke_warning ? "alert" : "far"]"
|
||||
|
||||
/obj/item/pinpointer/proc/my_god_jc_a_bomb() //If we should get the hell back to the ship
|
||||
for(var/obj/machinery/nuclearbomb/bomb in GLOB.nuke_list)
|
||||
if(bomb.timing)
|
||||
if(!nuke_warning)
|
||||
nuke_warning = TRUE
|
||||
playsound(src, 'sound/items/nuke_toy_lowpower.ogg', 50, 0)
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
to_chat(L, "<span class='userdanger'>Your [name] vibrates and lets out a tinny alarm. Uh oh.</span>")
|
||||
|
||||
/obj/item/pinpointer/proc/switch_mode_to(new_mode) //If we shouldn't be tracking what we are
|
||||
/obj/item/pinpointer/nuke/proc/switch_mode_to(new_mode)
|
||||
if(isliving(loc))
|
||||
var/mob/living/L = loc
|
||||
to_chat(L, "<span class='userdanger'>Your [name] beeps as it reconfigures its tracking algorithms.</span>")
|
||||
playsound(L, 'sound/machines/triple_beep.ogg', 50, 1)
|
||||
mode = new_mode
|
||||
target = null //Switch modes so we can find the new target
|
||||
scan_for_target()
|
||||
|
||||
/obj/item/pinpointer/proc/refresh_target() //Periodically removes the target to allow the pinpointer to update (i.e. malf AI shunts, an operative dies)
|
||||
target = null
|
||||
|
||||
/obj/item/pinpointer/syndicate //Syndicate pinpointers automatically point towards the infiltrator once the nuke is active.
|
||||
/obj/item/pinpointer/nuke/syndicate // Syndicate pinpointers automatically point towards the infiltrator once the nuke is active.
|
||||
name = "syndicate pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals. It's configured to switch tracking modes once it detects the activation signal of a nuclear device."
|
||||
icon_state = "pinpointer_syndicate"
|
||||
|
||||
/obj/item/pinpointer/syndicate/cyborg //Cyborg pinpointers just look for a random operative.
|
||||
/obj/item/pinpointer/syndicate_cyborg // Cyborg pinpointers just look for a random operative.
|
||||
name = "cyborg syndicate pinpointer"
|
||||
desc = "An integrated tracking device, jury-rigged to search for living Syndicate operatives."
|
||||
mode = TRACK_OPERATIVES
|
||||
flags_1 = NODROP_1
|
||||
|
||||
|
||||
/obj/item/pinpointer/syndicate_cyborg/scan_for_target()
|
||||
target = null
|
||||
var/list/possible_targets = list()
|
||||
var/turf/here = get_turf(src)
|
||||
for(var/V in SSticker.mode.syndicates)
|
||||
var/datum/mind/M = V
|
||||
if(M.current && M.current.stat != DEAD)
|
||||
possible_targets |= M.current
|
||||
var/mob/living/closest_operative = get_closest_atom(/mob/living/carbon/human, possible_targets, here)
|
||||
if(closest_operative)
|
||||
target = closest_operative
|
||||
..()
|
||||
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
diff a/code/game/gamemodes/nuclear/pinpointer.dm b/code/game/gamemodes/nuclear/pinpointer.dm (rejected hunks)
|
||||
@@ -30,7 +30,6 @@
|
||||
var/mob/living/L = loc
|
||||
to_chat(L, "<span class='userdanger'>Your [name] vibrates and lets out a tinny alarm. Uh oh.</span>")
|
||||
|
||||
-
|
||||
/obj/item/pinpointer/nuke/scan_for_target()
|
||||
target = null
|
||||
switch(mode)
|
||||
@@ -58,10 +57,10 @@
|
||||
mode = new_mode
|
||||
scan_for_target()
|
||||
|
||||
-
|
||||
/obj/item/pinpointer/nuke/syndicate // Syndicate pinpointers automatically point towards the infiltrator once the nuke is active.
|
||||
name = "syndicate pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals. It's configured to switch tracking modes once it detects the activation signal of a nuclear device."
|
||||
+ icon_state = "pinpointer_syndicate"
|
||||
|
||||
/obj/item/pinpointer/syndicate_cyborg // Cyborg pinpointers just look for a random operative.
|
||||
name = "cyborg syndicate pinpointer"
|
||||
@@ -186,7 +186,7 @@
|
||||
return ..()
|
||||
|
||||
//Old ninja objectives.
|
||||
/datum/objective_item/special/pinpointer
|
||||
/datum/objective_item/special/pinpointer/nuke
|
||||
name = "the captain's pinpointer."
|
||||
targetitem = /obj/item/pinpointer
|
||||
difficulty = 10
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
diff a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm (rejected hunks)
|
||||
@@ -158,7 +158,7 @@
|
||||
difficulty = 10
|
||||
|
||||
//Old ninja objectives.
|
||||
-/datum/objective_item/special/pinpointer
|
||||
+/datum/objective_item/special/pinpointer/nuke
|
||||
name = "the captain's pinpointer."
|
||||
targetitem = /obj/item/pinpointer
|
||||
difficulty = 10
|
||||
@@ -392,6 +392,9 @@
|
||||
QDEL_IN(mob_occupant, 40)
|
||||
|
||||
/obj/machinery/clonepod/relaymove(mob/user)
|
||||
container_resist()
|
||||
|
||||
/obj/machinery/clonepod/container_resist(mob/living/user)
|
||||
if(user.stat == CONSCIOUS)
|
||||
go_out()
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
var/damage_coeff
|
||||
var/scan_level
|
||||
var/precision_coeff
|
||||
var/message_cooldown
|
||||
var/breakout_time = 2
|
||||
|
||||
/obj/machinery/dna_scannernew/RefreshParts()
|
||||
scan_level = 0
|
||||
@@ -65,23 +67,20 @@
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/dna_scannernew/container_resist(mob/living/user)
|
||||
var/breakout_time = 2
|
||||
if(state_open || !locked) //Open and unlocked, no need to escape
|
||||
state_open = TRUE
|
||||
if(!locked)
|
||||
open_machine()
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [breakout_time] minutes.)</span>")
|
||||
user.visible_message("<span class='italics'>You hear a metallic creaking from [src]!</span>")
|
||||
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open || !locked)
|
||||
return
|
||||
|
||||
locked = FALSE
|
||||
visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>")
|
||||
to_chat(user, "<span class='notice'>You successfully break out of [src]!</span>")
|
||||
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/dna_scannernew/proc/locate_computer(type_)
|
||||
@@ -122,10 +121,11 @@
|
||||
|
||||
/obj/machinery/dna_scannernew/relaymove(mob/user as mob)
|
||||
if(user.stat || locked)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
|
||||
open_machine()
|
||||
return
|
||||
|
||||
/obj/machinery/dna_scannernew/attackby(obj/item/I, mob/user, params)
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ The console is located at computer/gulag_teleporter.dm
|
||||
active_power_usage = 5000
|
||||
circuit = /obj/item/circuitboard/machine/gulag_teleporter
|
||||
var/locked = FALSE
|
||||
var/message_cooldown
|
||||
var/breakout_time = 1
|
||||
var/jumpsuit_type = /obj/item/clothing/under/rank/prisoner
|
||||
var/shoes_type = /obj/item/clothing/shoes/sneakers/orange
|
||||
var/obj/machinery/gulag_item_reclaimer/linked_reclaimer
|
||||
@@ -46,7 +48,7 @@ The console is located at computer/gulag_teleporter.dm
|
||||
|
||||
/obj/machinery/gulag_teleporter/interact(mob/user)
|
||||
if(locked)
|
||||
to_chat(user, "[src] is locked.")
|
||||
to_chat(user, "<span class='warning'>[src] is locked!</span>")
|
||||
return
|
||||
toggle_open()
|
||||
|
||||
@@ -89,28 +91,27 @@ The console is located at computer/gulag_teleporter.dm
|
||||
if(user.stat != CONSCIOUS)
|
||||
return
|
||||
if(locked)
|
||||
to_chat(user, "[src] is locked!")
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/gulag_teleporter/container_resist(mob/living/user)
|
||||
var/breakout_time = 600
|
||||
if(!locked)
|
||||
open_machine()
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about a minute.)</span>")
|
||||
user.visible_message("<span class='italics'>You hear a metallic creaking from [src]!</span>")
|
||||
|
||||
if(do_after(user,(breakout_time), target = src))
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open || !locked)
|
||||
return
|
||||
|
||||
locked = FALSE
|
||||
visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>")
|
||||
to_chat(user, "<span class='notice'>You successfully break out of [src]!</span>")
|
||||
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/gulag_teleporter/proc/locate_reclaimer()
|
||||
|
||||
@@ -1,379 +1,406 @@
|
||||
// SUIT STORAGE UNIT /////////////////
|
||||
/obj/machinery/suit_storage_unit
|
||||
name = "suit storage unit"
|
||||
desc = "An industrial unit made to hold space suits. It comes with a built-in UV cauterization mechanism. A small warning label advises that organic matter should not be placed into the unit."
|
||||
icon = 'icons/obj/suitstorage.dmi'
|
||||
icon_state = "close"
|
||||
// SUIT STORAGE UNIT /////////////////
|
||||
/obj/machinery/suit_storage_unit
|
||||
name = "suit storage unit"
|
||||
desc = "An industrial unit made to hold space suits. It comes with a built-in UV cauterization mechanism. A small warning label advises that organic matter should not be placed into the unit."
|
||||
icon = 'icons/obj/suitstorage.dmi'
|
||||
icon_state = "close"
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
max_integrity = 250
|
||||
|
||||
var/obj/item/clothing/suit/space/suit = null
|
||||
var/obj/item/clothing/head/helmet/space/helmet = null
|
||||
var/obj/item/clothing/mask/mask = null
|
||||
var/obj/item/storage = null
|
||||
|
||||
var/suit_type = null
|
||||
var/helmet_type = null
|
||||
var/mask_type = null
|
||||
var/storage_type = null
|
||||
|
||||
state_open = FALSE
|
||||
var/locked = FALSE
|
||||
panel_open = FALSE
|
||||
var/safeties = TRUE
|
||||
|
||||
var/uv = FALSE
|
||||
var/uv_super = FALSE
|
||||
var/uv_cycles = 6
|
||||
|
||||
/obj/machinery/suit_storage_unit/standard_unit
|
||||
suit_type = /obj/item/clothing/suit/space/eva
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/eva
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/captain
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/captain
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
storage_type = /obj/item/tank/jetpack/oxygen/captain
|
||||
|
||||
/obj/machinery/suit_storage_unit/engine
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/ce
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type= /obj/item/clothing/shoes/magboots/advance
|
||||
|
||||
/obj/machinery/suit_storage_unit/security
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/security
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
|
||||
/obj/machinery/suit_storage_unit/hos
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
storage_type = /obj/item/tank/internals/oxygen
|
||||
|
||||
/obj/machinery/suit_storage_unit/atmos
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos
|
||||
mask_type = /obj/item/clothing/mask/gas
|
||||
storage_type = /obj/item/watertank/atmos
|
||||
|
||||
/obj/machinery/suit_storage_unit/mining
|
||||
suit_type = /obj/item/clothing/suit/hooded/explorer
|
||||
mask_type = /obj/item/clothing/mask/gas/explorer
|
||||
|
||||
/obj/machinery/suit_storage_unit/mining/eva
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/mining
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/cmo
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/medical
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/rd
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/rd
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/syndicate
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
mask_type = /obj/item/clothing/mask/gas/syndicate
|
||||
storage_type = /obj/item/tank/jetpack/oxygen/harness
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/command
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/security
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/sec
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/engineer
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/engi
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/medical
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/med
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
max_integrity = 250
|
||||
|
||||
var/obj/item/clothing/suit/space/suit = null
|
||||
var/obj/item/clothing/head/helmet/space/helmet = null
|
||||
var/obj/item/clothing/mask/mask = null
|
||||
var/obj/item/storage = null
|
||||
|
||||
var/suit_type = null
|
||||
var/helmet_type = null
|
||||
var/mask_type = null
|
||||
var/storage_type = null
|
||||
|
||||
state_open = FALSE
|
||||
var/locked = FALSE
|
||||
panel_open = FALSE
|
||||
var/safeties = TRUE
|
||||
|
||||
var/uv = FALSE
|
||||
var/uv_super = FALSE
|
||||
var/uv_cycles = 6
|
||||
var/message_cooldown
|
||||
var/breakout_time = 0.5
|
||||
|
||||
/obj/machinery/suit_storage_unit/standard_unit
|
||||
suit_type = /obj/item/clothing/suit/space/eva
|
||||
helmet_type = /obj/item/clothing/head/helmet/space/eva
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/captain
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/captain
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
storage_type = /obj/item/tank/jetpack/oxygen/captain
|
||||
|
||||
/obj/machinery/suit_storage_unit/engine
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/ce
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/elite
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type= /obj/item/clothing/shoes/magboots/advance
|
||||
|
||||
/obj/machinery/suit_storage_unit/security
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/security
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
|
||||
/obj/machinery/suit_storage_unit/hos
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/security/hos
|
||||
mask_type = /obj/item/clothing/mask/gas/sechailer
|
||||
storage_type = /obj/item/tank/internals/oxygen
|
||||
|
||||
/obj/machinery/suit_storage_unit/atmos
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/engine/atmos
|
||||
mask_type = /obj/item/clothing/mask/gas
|
||||
storage_type = /obj/item/watertank/atmos
|
||||
|
||||
/obj/machinery/suit_storage_unit/mining
|
||||
suit_type = /obj/item/clothing/suit/hooded/explorer
|
||||
mask_type = /obj/item/clothing/mask/gas/explorer
|
||||
|
||||
/obj/machinery/suit_storage_unit/mining/eva
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/mining
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/cmo
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/medical
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/rd
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/rd
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
|
||||
/obj/machinery/suit_storage_unit/syndicate
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/syndi
|
||||
mask_type = /obj/item/clothing/mask/gas/syndicate
|
||||
storage_type = /obj/item/tank/jetpack/oxygen/harness
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/command
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/security
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/sec
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/engineer
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/engi
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/ert/medical
|
||||
suit_type = /obj/item/clothing/suit/space/hardsuit/ert/med
|
||||
mask_type = /obj/item/clothing/mask/breath
|
||||
storage_type = /obj/item/tank/internals/emergency_oxygen/double
|
||||
|
||||
/obj/machinery/suit_storage_unit/Initialize()
|
||||
. = ..()
|
||||
wires = new /datum/wires/suit_storage_unit(src)
|
||||
if(suit_type)
|
||||
suit = new suit_type(src)
|
||||
if(helmet_type)
|
||||
helmet = new helmet_type(src)
|
||||
if(mask_type)
|
||||
mask = new mask_type(src)
|
||||
if(storage_type)
|
||||
storage = new storage_type(src)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/suit_storage_unit/Destroy()
|
||||
wires = new /datum/wires/suit_storage_unit(src)
|
||||
if(suit_type)
|
||||
suit = new suit_type(src)
|
||||
if(helmet_type)
|
||||
helmet = new helmet_type(src)
|
||||
if(mask_type)
|
||||
mask = new mask_type(src)
|
||||
if(storage_type)
|
||||
storage = new storage_type(src)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/suit_storage_unit/Destroy()
|
||||
QDEL_NULL(suit)
|
||||
QDEL_NULL(helmet)
|
||||
QDEL_NULL(mask)
|
||||
QDEL_NULL(storage)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/suit_storage_unit/update_icon()
|
||||
cut_overlays()
|
||||
|
||||
if(uv)
|
||||
if(uv_super)
|
||||
add_overlay("super")
|
||||
else if(occupant)
|
||||
add_overlay("uvhuman")
|
||||
else
|
||||
add_overlay("uv")
|
||||
else if(state_open)
|
||||
if(stat & BROKEN)
|
||||
add_overlay("broken")
|
||||
else
|
||||
add_overlay("open")
|
||||
if(suit)
|
||||
add_overlay("suit")
|
||||
if(helmet)
|
||||
add_overlay("helm")
|
||||
if(storage)
|
||||
add_overlay("storage")
|
||||
else if(occupant)
|
||||
add_overlay("human")
|
||||
|
||||
/obj/machinery/suit_storage_unit/power_change()
|
||||
..()
|
||||
if(!is_operational() && state_open)
|
||||
open_machine()
|
||||
dump_contents()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/dump_contents()
|
||||
dropContents()
|
||||
helmet = null
|
||||
suit = null
|
||||
mask = null
|
||||
storage = null
|
||||
occupant = null
|
||||
|
||||
/obj/machinery/suit_storage_unit/deconstruct(disassembled = TRUE)
|
||||
return ..()
|
||||
|
||||
/obj/machinery/suit_storage_unit/update_icon()
|
||||
cut_overlays()
|
||||
|
||||
if(uv)
|
||||
if(uv_super)
|
||||
add_overlay("super")
|
||||
else if(occupant)
|
||||
add_overlay("uvhuman")
|
||||
else
|
||||
add_overlay("uv")
|
||||
else if(state_open)
|
||||
if(stat & BROKEN)
|
||||
add_overlay("broken")
|
||||
else
|
||||
add_overlay("open")
|
||||
if(suit)
|
||||
add_overlay("suit")
|
||||
if(helmet)
|
||||
add_overlay("helm")
|
||||
if(storage)
|
||||
add_overlay("storage")
|
||||
else if(occupant)
|
||||
add_overlay("human")
|
||||
|
||||
/obj/machinery/suit_storage_unit/power_change()
|
||||
..()
|
||||
if(!is_operational() && state_open)
|
||||
open_machine()
|
||||
dump_contents()
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/dump_contents()
|
||||
dropContents()
|
||||
helmet = null
|
||||
suit = null
|
||||
mask = null
|
||||
storage = null
|
||||
occupant = null
|
||||
|
||||
/obj/machinery/suit_storage_unit/deconstruct(disassembled = TRUE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
open_machine()
|
||||
dump_contents()
|
||||
new /obj/item/stack/sheet/metal (loc, 2)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !Adjacent(A) || !isliving(A))
|
||||
return
|
||||
var/mob/living/target = A
|
||||
if(!state_open)
|
||||
to_chat(user, "<span class='warning'>The unit's doors are shut!</span>")
|
||||
return
|
||||
if(!is_operational())
|
||||
to_chat(user, "<span class='warning'>The unit is not operational!</span>")
|
||||
return
|
||||
if(occupant || helmet || suit || storage)
|
||||
to_chat(user, "<span class='warning'>It's too cluttered inside to fit in!</span>")
|
||||
return
|
||||
|
||||
if(target == user)
|
||||
user.visible_message("<span class='warning'>[user] starts squeezing into [src]!</span>", "<span class='notice'>You start working your way into [src]...</span>")
|
||||
else
|
||||
target.visible_message("<span class='warning'>[user] starts shoving [target] into [src]!</span>", "<span class='userdanger'>[user] starts shoving you into [src]!</span>")
|
||||
|
||||
if(do_mob(user, target, 30))
|
||||
if(occupant || helmet || suit || storage)
|
||||
return
|
||||
if(target == user)
|
||||
user.visible_message("<span class='warning'>[user] slips into [src] and closes the door behind them!</span>", "<span class=notice'>You slip into [src]'s cramped space and shut its door.</span>")
|
||||
else
|
||||
target.visible_message("<span class='warning'>[user] pushes [target] into [src] and shuts its door!<span>", "<span class='userdanger'>[user] shoves you into [src] and shuts the door!</span>")
|
||||
close_machine(target)
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/cook()
|
||||
if(uv_cycles)
|
||||
uv_cycles--
|
||||
uv = TRUE
|
||||
locked = TRUE
|
||||
update_icon()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(uv_super)
|
||||
mob_occupant.adjustFireLoss(rand(20, 36))
|
||||
else
|
||||
mob_occupant.adjustFireLoss(rand(10, 16))
|
||||
mob_occupant.emote("scream")
|
||||
addtimer(CALLBACK(src, .proc/cook), 50)
|
||||
else
|
||||
uv_cycles = initial(uv_cycles)
|
||||
uv = FALSE
|
||||
locked = FALSE
|
||||
if(uv_super)
|
||||
visible_message("<span class='warning'>[src]'s door creaks open with a loud whining noise. A cloud of foul black smoke escapes from its chamber.</span>")
|
||||
playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50, 1)
|
||||
helmet = null
|
||||
qdel(helmet)
|
||||
suit = null
|
||||
qdel(suit) // Delete everything but the occupant.
|
||||
mask = null
|
||||
qdel(mask)
|
||||
storage = null
|
||||
qdel(storage)
|
||||
// The wires get damaged too.
|
||||
wires.cut_all()
|
||||
else
|
||||
if(!occupant)
|
||||
visible_message("<span class='notice'>[src]'s door slides open. The glowing yellow lights dim to a gentle green.</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[src]'s door slides open, barraging you with the nauseating smell of charred flesh.</span>")
|
||||
playsound(src, 'sound/machines/airlockclose.ogg', 25, 1)
|
||||
for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
|
||||
I.clean_blood()
|
||||
I.fingerprints = list()
|
||||
open_machine(FALSE)
|
||||
if(occupant)
|
||||
dump_contents()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/shock(mob/user, prb)
|
||||
if(!prob(prb))
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
if(electrocute_mob(user, src, src, 1, TRUE))
|
||||
return 1
|
||||
|
||||
/obj/machinery/suit_storage_unit/relaymove(mob/user)
|
||||
container_resist(user)
|
||||
|
||||
/obj/machinery/suit_storage_unit/container_resist(mob/living/user)
|
||||
add_fingerprint(user)
|
||||
if(locked)
|
||||
visible_message("<span class='notice'>You see [user] kicking against the doors of [src]!</span>", "<span class='notice'>You start kicking against the doors...</span>")
|
||||
addtimer(CALLBACK(src, .proc/resist_open, user), 300)
|
||||
else
|
||||
open_machine()
|
||||
dump_contents()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/resist_open(mob/user)
|
||||
if(!state_open && occupant && (user in src) && user.stat == 0) // Check they're still here.
|
||||
visible_message("<span class='notice'>You see [user] bursts out of [src]!</span>", "<span class='notice'>You escape the cramped confines of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/suit_storage_unit/attackby(obj/item/I, mob/user, params)
|
||||
if(state_open && is_operational())
|
||||
if(istype(I, /obj/item/clothing/suit/space))
|
||||
if(suit)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a suit!.</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
suit = I
|
||||
else if(istype(I, /obj/item/clothing/head/helmet))
|
||||
if(helmet)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a helmet!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
helmet = I
|
||||
else if(istype(I, /obj/item/clothing/mask))
|
||||
if(mask)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a mask!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
mask = I
|
||||
else
|
||||
if(storage)
|
||||
to_chat(user, "<span class='warning'>The auxiliary storage compartment is full!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
storage = I
|
||||
|
||||
I.loc = src
|
||||
visible_message("<span class='notice'>[user] inserts [I] into [src]</span>", "<span class='notice'>You load [I] into [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(panel_open && is_wire_tool(I))
|
||||
wires.interact(user)
|
||||
if(!state_open)
|
||||
if(default_deconstruction_screwdriver(user, "panel", "close", I))
|
||||
return
|
||||
if(default_pry_open(I))
|
||||
dump_contents()
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
open_machine()
|
||||
dump_contents()
|
||||
new /obj/item/stack/sheet/metal (loc, 2)
|
||||
qdel(src)
|
||||
|
||||
/obj/machinery/suit_storage_unit/MouseDrop_T(atom/A, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !Adjacent(A) || !isliving(A))
|
||||
return
|
||||
var/mob/living/target = A
|
||||
if(!state_open)
|
||||
to_chat(user, "<span class='warning'>The unit's doors are shut!</span>")
|
||||
return
|
||||
if(!is_operational())
|
||||
to_chat(user, "<span class='warning'>The unit is not operational!</span>")
|
||||
return
|
||||
if(occupant || helmet || suit || storage)
|
||||
to_chat(user, "<span class='warning'>It's too cluttered inside to fit in!</span>")
|
||||
return
|
||||
|
||||
if(target == user)
|
||||
user.visible_message("<span class='warning'>[user] starts squeezing into [src]!</span>", "<span class='notice'>You start working your way into [src]...</span>")
|
||||
else
|
||||
target.visible_message("<span class='warning'>[user] starts shoving [target] into [src]!</span>", "<span class='userdanger'>[user] starts shoving you into [src]!</span>")
|
||||
|
||||
if(do_mob(user, target, 30))
|
||||
if(occupant || helmet || suit || storage)
|
||||
return
|
||||
if(target == user)
|
||||
user.visible_message("<span class='warning'>[user] slips into [src] and closes the door behind them!</span>", "<span class=notice'>You slip into [src]'s cramped space and shut its door.</span>")
|
||||
else
|
||||
target.visible_message("<span class='warning'>[user] pushes [target] into [src] and shuts its door!<span>", "<span class='userdanger'>[user] shoves you into [src] and shuts the door!</span>")
|
||||
close_machine(target)
|
||||
add_fingerprint(user)
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/cook()
|
||||
if(uv_cycles)
|
||||
uv_cycles--
|
||||
uv = TRUE
|
||||
locked = TRUE
|
||||
update_icon()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
if(uv_super)
|
||||
mob_occupant.adjustFireLoss(rand(20, 36))
|
||||
else
|
||||
mob_occupant.adjustFireLoss(rand(10, 16))
|
||||
mob_occupant.emote("scream")
|
||||
addtimer(CALLBACK(src, .proc/cook), 50)
|
||||
else
|
||||
uv_cycles = initial(uv_cycles)
|
||||
uv = FALSE
|
||||
locked = FALSE
|
||||
if(uv_super)
|
||||
visible_message("<span class='warning'>[src]'s door creaks open with a loud whining noise. A cloud of foul black smoke escapes from its chamber.</span>")
|
||||
playsound(src, 'sound/machines/airlock_alien_prying.ogg', 50, 1)
|
||||
helmet = null
|
||||
qdel(helmet)
|
||||
suit = null
|
||||
qdel(suit) // Delete everything but the occupant.
|
||||
mask = null
|
||||
qdel(mask)
|
||||
storage = null
|
||||
qdel(storage)
|
||||
// The wires get damaged too.
|
||||
wires.cut_all()
|
||||
else
|
||||
if(!occupant)
|
||||
visible_message("<span class='notice'>[src]'s door slides open. The glowing yellow lights dim to a gentle green.</span>")
|
||||
else
|
||||
visible_message("<span class='warning'>[src]'s door slides open, barraging you with the nauseating smell of charred flesh.</span>")
|
||||
playsound(src, 'sound/machines/airlockclose.ogg', 25, 1)
|
||||
for(var/obj/item/I in src) //Scorches away blood and forensic evidence, although the SSU itself is unaffected
|
||||
I.clean_blood()
|
||||
I.fingerprints = list()
|
||||
open_machine(FALSE)
|
||||
if(occupant)
|
||||
dump_contents()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/shock(mob/user, prb)
|
||||
if(!prob(prb))
|
||||
var/datum/effect_system/spark_spread/s = new /datum/effect_system/spark_spread
|
||||
s.set_up(5, 1, src)
|
||||
s.start()
|
||||
if(electrocute_mob(user, src, src, 1, TRUE))
|
||||
return 1
|
||||
|
||||
/obj/machinery/suit_storage_unit/relaymove(mob/user)
|
||||
if(locked)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
open_machine()
|
||||
dump_contents()
|
||||
|
||||
/obj/machinery/suit_storage_unit/container_resist(mob/living/user)
|
||||
if(!locked)
|
||||
open_machine()
|
||||
dump_contents()
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the doors of [src]!</span>", \
|
||||
"<span class='notice'>You start kicking against the doors... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a thump from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src )
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
dump_contents()
|
||||
|
||||
add_fingerprint(user)
|
||||
if(locked)
|
||||
visible_message("<span class='notice'>You see [user] kicking against the doors of [src]!</span>", \
|
||||
"<span class='notice'>You start kicking against the doors...</span>")
|
||||
addtimer(CALLBACK(src, .proc/resist_open, user), 300)
|
||||
else
|
||||
open_machine()
|
||||
dump_contents()
|
||||
|
||||
/obj/machinery/suit_storage_unit/proc/resist_open(mob/user)
|
||||
if(!state_open && occupant && (user in src) && user.stat == 0) // Check they're still here.
|
||||
visible_message("<span class='notice'>You see [user] bursts out of [src]!</span>", \
|
||||
"<span class='notice'>You escape the cramped confines of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/suit_storage_unit/attackby(obj/item/I, mob/user, params)
|
||||
if(state_open && is_operational())
|
||||
if(istype(I, /obj/item/clothing/suit/space))
|
||||
if(suit)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a suit!.</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
suit = I
|
||||
else if(istype(I, /obj/item/clothing/head/helmet))
|
||||
if(helmet)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a helmet!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
helmet = I
|
||||
else if(istype(I, /obj/item/clothing/mask))
|
||||
if(mask)
|
||||
to_chat(user, "<span class='warning'>The unit already contains a mask!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
mask = I
|
||||
else
|
||||
if(storage)
|
||||
to_chat(user, "<span class='warning'>The auxiliary storage compartment is full!</span>")
|
||||
return
|
||||
if(!user.drop_item())
|
||||
return
|
||||
storage = I
|
||||
|
||||
I.loc = src
|
||||
visible_message("<span class='notice'>[user] inserts [I] into [src]</span>", "<span class='notice'>You load [I] into [src].</span>")
|
||||
update_icon()
|
||||
return
|
||||
|
||||
if(panel_open && is_wire_tool(I))
|
||||
wires.interact(user)
|
||||
if(!state_open)
|
||||
if(default_deconstruction_screwdriver(user, "panel", "close", I))
|
||||
return
|
||||
if(default_pry_open(I))
|
||||
dump_contents()
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
/obj/machinery/suit_storage_unit/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, \
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "suit_storage_unit", name, 400, 305, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/suit_storage_unit/ui_data()
|
||||
var/list/data = list()
|
||||
data["locked"] = locked
|
||||
data["open"] = state_open
|
||||
data["safeties"] = safeties
|
||||
data["uv_active"] = uv
|
||||
data["uv_super"] = uv_super
|
||||
if(helmet)
|
||||
data["helmet"] = helmet.name
|
||||
if(suit)
|
||||
data["suit"] = suit.name
|
||||
if(mask)
|
||||
data["mask"] = mask.name
|
||||
if(storage)
|
||||
data["storage"] = storage.name
|
||||
if(occupant)
|
||||
data["occupied"] = 1
|
||||
return data
|
||||
|
||||
/obj/machinery/suit_storage_unit/ui_act(action, params)
|
||||
if(..() || uv)
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine(0)
|
||||
if(occupant)
|
||||
dump_contents() // Dump out contents if someone is in there.
|
||||
. = TRUE
|
||||
if("lock")
|
||||
locked = !locked
|
||||
. = TRUE
|
||||
if("uv")
|
||||
if(occupant && safeties)
|
||||
return
|
||||
else if(!helmet && !mask && !suit && !storage && !occupant)
|
||||
return
|
||||
else
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
to_chat(mob_occupant, "<span class='userdanger'>[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!</span>")
|
||||
cook()
|
||||
. = TRUE
|
||||
if("dispense")
|
||||
if(!state_open)
|
||||
return
|
||||
|
||||
var/static/list/valid_items = list("helmet", "suit", "mask", "storage")
|
||||
var/item_name = params["item"]
|
||||
if(item_name in valid_items)
|
||||
var/obj/item/I = vars[item_name]
|
||||
vars[item_name] = null
|
||||
if(I)
|
||||
I.forceMove(loc)
|
||||
. = TRUE
|
||||
update_icon()
|
||||
datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "suit_storage_unit", name, 400, 305, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
/obj/machinery/suit_storage_unit/ui_data()
|
||||
var/list/data = list()
|
||||
data["locked"] = locked
|
||||
data["open"] = state_open
|
||||
data["safeties"] = safeties
|
||||
data["uv_active"] = uv
|
||||
data["uv_super"] = uv_super
|
||||
if(helmet)
|
||||
data["helmet"] = helmet.name
|
||||
if(suit)
|
||||
data["suit"] = suit.name
|
||||
if(mask)
|
||||
data["mask"] = mask.name
|
||||
if(storage)
|
||||
data["storage"] = storage.name
|
||||
if(occupant)
|
||||
data["occupied"] = 1
|
||||
return data
|
||||
|
||||
/obj/machinery/suit_storage_unit/ui_act(action, params)
|
||||
if(..() || uv)
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine(0)
|
||||
if(occupant)
|
||||
dump_contents() // Dump out contents if someone is in there.
|
||||
. = TRUE
|
||||
if("lock")
|
||||
locked = !locked
|
||||
. = TRUE
|
||||
if("uv")
|
||||
if(occupant && safeties)
|
||||
return
|
||||
else if(!helmet && !mask && !suit && !storage && !occupant)
|
||||
return
|
||||
else
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
to_chat(mob_occupant, "<span class='userdanger'>[src]'s confines grow warm, then hot, then scorching. You're being burned [!mob_occupant.stat ? "alive" : "away"]!</span>")
|
||||
cook()
|
||||
. = TRUE
|
||||
if("dispense")
|
||||
if(!state_open)
|
||||
return
|
||||
|
||||
var/static/list/valid_items = list("helmet", "suit", "mask", "storage")
|
||||
var/item_name = params["item"]
|
||||
if(item_name in valid_items)
|
||||
var/obj/item/I = vars[item_name]
|
||||
vars[item_name] = null
|
||||
if(I)
|
||||
I.forceMove(loc)
|
||||
. = TRUE
|
||||
update_icon()
|
||||
|
||||
@@ -869,7 +869,7 @@ IF YOU MODIFY THE PRODUCTS LIST OF A MACHINE, MAKE SURE TO UPDATE ITS RESUPPLY C
|
||||
products = list(/obj/item/reagent_containers/syringe = 12, /obj/item/reagent_containers/dropper = 3, /obj/item/stack/medical/gauze = 8, /obj/item/reagent_containers/pill/patch/styptic = 5, /obj/item/reagent_containers/pill/insulin = 10,
|
||||
/obj/item/reagent_containers/pill/patch/silver_sulf = 5, /obj/item/reagent_containers/glass/bottle/charcoal = 4, /obj/item/reagent_containers/spray/medical/sterilizer = 1,
|
||||
/obj/item/reagent_containers/glass/bottle/epinephrine = 4, /obj/item/reagent_containers/glass/bottle/morphine = 4, /obj/item/reagent_containers/glass/bottle/salglu_solution = 3,
|
||||
/obj/item/reagent_containers/glass/bottle/toxin = 3, /obj/item/reagent_containers/syringe/antiviral = 6, /obj/item/reagent_containers/pill/salbutamol = 2, /obj/item/device/healthanalyzer = 4, /obj/item/device/sensor_device = 2)
|
||||
/obj/item/reagent_containers/glass/bottle/toxin = 3, /obj/item/reagent_containers/syringe/antiviral = 6, /obj/item/reagent_containers/pill/salbutamol = 2, /obj/item/device/healthanalyzer = 4, /obj/item/device/sensor_device = 2, /obj/item/pinpointer/crew = 2)
|
||||
contraband = list(/obj/item/reagent_containers/pill/tox = 3, /obj/item/reagent_containers/pill/morphine = 4, /obj/item/reagent_containers/pill/charcoal = 6)
|
||||
premium = list(/obj/item/storage/box/hug/medical = 1, /obj/item/reagent_containers/hypospray/medipen = 3, /obj/item/storage/belt/medical = 3, /obj/item/wrench/medical = 1)
|
||||
armor = list(melee = 100, bullet = 100, laser = 100, energy = 100, bomb = 0, bio = 0, rad = 0, fire = 100, acid = 50)
|
||||
|
||||
@@ -58,7 +58,9 @@
|
||||
/turf/open/floor/plating/asteroid/drill_act(obj/item/mecha_parts/mecha_equipment/drill/drill)
|
||||
for(var/turf/open/floor/plating/asteroid/M in range(1, drill.chassis))
|
||||
if(get_dir(drill.chassis,M)&drill.chassis.dir)
|
||||
M.gets_dug()
|
||||
for(var/I in GetComponents(/datum/component/archaeology))
|
||||
var/datum/component/archaeology/archy = I
|
||||
archy.gets_dug()
|
||||
drill.log_message("Drilled through [src]")
|
||||
drill.move_ores()
|
||||
|
||||
|
||||
@@ -549,9 +549,10 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE)
|
||||
transfer_blood = 0
|
||||
|
||||
/obj/item/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FOUR)
|
||||
throw_at(S,14,3, spin=0)
|
||||
else ..()
|
||||
else return
|
||||
|
||||
/obj/item/throw_impact(atom/A)
|
||||
if(A && !QDELETED(A))
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
return
|
||||
if(!isnull(target) && !target.toff)
|
||||
charges--
|
||||
var/lock_code = "[rand(100,999)] [pick("Alpha","Bravo","Charlie","Delta","Echo","Foxtrot","Golf","Hotel","India","Juliet","Kilo","Lima","Mike","November","Oscar","Papa","Quebec","Romeo","Sierra","Tango","Uniform","Victor","Whiskey","X-ray","Yankee","Zulu")]"
|
||||
var/lock_code = "[rand(100,999)] [pick(GLOB.phonetic_alphabet)]"
|
||||
to_chat(U, "<span class='notice'>Virus Sent! The unlock code to the target is: [lock_code]</span>")
|
||||
if(!target.hidden_uplink)
|
||||
var/obj/item/device/uplink/uplink = new(target)
|
||||
|
||||
@@ -428,7 +428,7 @@
|
||||
|
||||
/obj/item/device/flashlight/glowstick/update_icon()
|
||||
item_state = "glowstick"
|
||||
overlays.Cut()
|
||||
cut_overlays()
|
||||
if(!fuel)
|
||||
icon_state = "glowstick-empty"
|
||||
cut_overlays()
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
|
||||
/obj/item/weapon/pinpointer
|
||||
name = "pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "pinpointer"
|
||||
flags = CONDUCT
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/active = FALSE
|
||||
var/atom/movable/target = null //The thing we're searching for
|
||||
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
|
||||
var/alert = FALSE // TRUE to display things more seriously
|
||||
|
||||
/obj/item/weapon/pinpointer/New()
|
||||
..()
|
||||
GLOB.pinpointer_list += src
|
||||
|
||||
/obj/item/weapon/pinpointer/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.pinpointer_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/weapon/pinpointer/attack_self(mob/living/user)
|
||||
active = !active
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
if(active)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
target = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_pointer_overlay()
|
||||
|
||||
/obj/item/weapon/pinpointer/process()
|
||||
if(!active)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return
|
||||
scan_for_target()
|
||||
update_pointer_overlay()
|
||||
|
||||
/obj/item/weapon/pinpointer/proc/scan_for_target()
|
||||
return
|
||||
|
||||
/obj/item/weapon/pinpointer/proc/update_pointer_overlay()
|
||||
cut_overlays()
|
||||
if(!active)
|
||||
return
|
||||
if(!target)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
var/turf/here = get_turf(src)
|
||||
var/turf/there = get_turf(target)
|
||||
if(here.z != there.z)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
return
|
||||
if(get_dist_euclidian(here,there) <= minimum_range)
|
||||
add_overlay("pinon[alert ? "alert" : ""]direct")
|
||||
else
|
||||
setDir(get_dir(here, there))
|
||||
switch(get_dist(here, there))
|
||||
if(1 to 8)
|
||||
add_overlay("pinon[alert ? "alert" : "close"]")
|
||||
if(9 to 16)
|
||||
add_overlay("pinon[alert ? "alert" : "medium"]")
|
||||
if(16 to INFINITY)
|
||||
add_overlay("pinon[alert ? "alert" : "far"]")
|
||||
|
||||
/obj/item/weapon/pinpointer/crew // A replacement for the old crew monitoring consoles
|
||||
name = "crew pinpointer"
|
||||
desc = "A handheld tracking device that points to crew suit sensors."
|
||||
icon_state = "pinpointer_crew"
|
||||
|
||||
/obj/item/weapon/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
|
||||
var/turf/here = get_turf(src)
|
||||
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = H.w_uniform
|
||||
|
||||
// Suit sensors must be on maximum.
|
||||
if(!U.has_sensor || U.sensor_mode < SENSOR_COORDS)
|
||||
return FALSE
|
||||
|
||||
var/turf/there = get_turf(H)
|
||||
return (H.z != 0 || (there && there.z == H.z))
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/item/weapon/pinpointer/crew/attack_self(mob/living/user)
|
||||
if(active)
|
||||
active = FALSE
|
||||
user.visible_message("<span class='notice'>[user] deactivates their pinpointer.</span>", "<span class='notice'>You deactivate your pinpointer.</span>")
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
target = null //Restarting the pinpointer forces a target reset
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_pointer_overlay()
|
||||
return
|
||||
|
||||
var/list/name_counts = list()
|
||||
var/list/names = list()
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
if(!trackable(H))
|
||||
continue
|
||||
|
||||
var/name = "Unknown"
|
||||
if(H.wear_id)
|
||||
var/obj/item/weapon/card/id/I = H.wear_id.GetID()
|
||||
name = I.registered_name
|
||||
|
||||
while(name in name_counts)
|
||||
name_counts[name]++
|
||||
name = text("[] ([])", name, name_counts[name])
|
||||
names[name] = H
|
||||
name_counts[name] = 1
|
||||
|
||||
if(!names.len)
|
||||
user.visible_message("<span class='notice'>[user]'s pinpointer fails to detect a signal.</span>", "<span class='notice'>Your pinpointer fails to detect a signal.</span>")
|
||||
return
|
||||
|
||||
var/A = input(user, "Person to track", "Pinpoint") in names
|
||||
if(!src || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !A)
|
||||
return
|
||||
|
||||
target = names[A]
|
||||
active = TRUE
|
||||
user.visible_message("<span class='notice'>[user] activates their pinpointer.</span>", "<span class='notice'>You activate your pinpointer.</span>")
|
||||
playsound(user, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
update_pointer_overlay()
|
||||
|
||||
/obj/item/weapon/pinpointer/crew/scan_for_target()
|
||||
if(target)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!trackable(H))
|
||||
target = null
|
||||
if(!target)
|
||||
active = FALSE
|
||||
|
||||
/obj/item/weapon/pinpointer/process()
|
||||
if(!active)
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
return
|
||||
scan_for_target()
|
||||
update_pointer_overlay()
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
icon_state = null
|
||||
active = TRUE
|
||||
if(tile_overlay)
|
||||
loc.overlays += tile_overlay
|
||||
loc.add_overlay(tile_overlay)
|
||||
else
|
||||
if(crossed)
|
||||
trigger() //no cheesing.
|
||||
|
||||
@@ -1,187 +1,188 @@
|
||||
/obj/machinery/implantchair
|
||||
name = "mindshield implanter"
|
||||
desc = "Used to implant occupants with mindshield implants."
|
||||
icon = 'icons/obj/machines/implantchair.dmi'
|
||||
icon_state = "implantchair"
|
||||
density = TRUE
|
||||
opacity = 0
|
||||
anchored = TRUE
|
||||
|
||||
var/ready = TRUE
|
||||
var/replenishing = FALSE
|
||||
|
||||
var/ready_implants = 5
|
||||
var/max_implants = 5
|
||||
var/injection_cooldown = 600
|
||||
var/replenish_cooldown = 6000
|
||||
var/implant_type = /obj/item/implant/mindshield
|
||||
var/auto_inject = FALSE
|
||||
var/auto_replenish = TRUE
|
||||
var/special = FALSE
|
||||
var/special_name = "special function"
|
||||
|
||||
/obj/machinery/implantchair/Initialize()
|
||||
. = ..()
|
||||
open_machine()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_data()
|
||||
var/list/data = list()
|
||||
data["occupied"] = occupant ? 1 : 0
|
||||
data["open"] = state_open
|
||||
|
||||
data["occupant"] = list()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
data["occupant"]["stat"] = mob_occupant.stat
|
||||
|
||||
data["special_name"] = special ? special_name : null
|
||||
data["ready_implants"] = ready_implants
|
||||
data["ready"] = ready
|
||||
data["replenishing"] = replenishing
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/implantchair/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine()
|
||||
. = TRUE
|
||||
if("implant")
|
||||
implant(occupant,usr)
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user)
|
||||
if (!istype(M))
|
||||
return
|
||||
if(!ready_implants || !ready)
|
||||
return
|
||||
if(implant_action(M,user))
|
||||
ready_implants--
|
||||
if(!replenishing && auto_replenish)
|
||||
replenishing = TRUE
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
if(injection_cooldown > 0)
|
||||
ready = FALSE
|
||||
addtimer(CALLBACK(src,"set_ready"),injection_cooldown)
|
||||
else
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/proc/implant_action(mob/living/M)
|
||||
var/obj/item/implant/I = new implant_type
|
||||
if(I.implant(M))
|
||||
visible_message("<span class='warning'>[M] has been implanted by the [name].</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/implantchair/update_icon()
|
||||
icon_state = initial(icon_state)
|
||||
if(state_open)
|
||||
icon_state += "_open"
|
||||
if(occupant)
|
||||
icon_state += "_occupied"
|
||||
if(ready)
|
||||
add_overlay("ready")
|
||||
else
|
||||
cut_overlays()
|
||||
|
||||
/obj/machinery/implantchair/proc/replenish()
|
||||
if(ready_implants < max_implants)
|
||||
ready_implants++
|
||||
if(ready_implants < max_implants)
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
else
|
||||
replenishing = FALSE
|
||||
|
||||
/obj/machinery/implantchair/proc/set_ready()
|
||||
ready = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/container_resist(mob/living/user)
|
||||
if(state_open)
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about about a minute.)</span>")
|
||||
audible_message("<span class='italics'>You hear a metallic creaking from [src]!</span>",hearing_distance = 2)
|
||||
|
||||
if(do_after(user, 600, target = src))
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
|
||||
return
|
||||
visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>")
|
||||
to_chat(user, "<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/implantchair/relaymove(mob/user)
|
||||
container_resist(user)
|
||||
|
||||
/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser())
|
||||
return
|
||||
close_machine(target)
|
||||
|
||||
/obj/machinery/implantchair/close_machine(mob/living/user)
|
||||
if((isnull(user) || istype(user)) && state_open)
|
||||
..(user)
|
||||
if(auto_inject && ready && ready_implants > 0)
|
||||
implant(user,null)
|
||||
|
||||
/obj/machinery/implantchair/genepurge
|
||||
name = "Genetic purifier"
|
||||
desc = "Used to purge human genome of foreign influences"
|
||||
special = TRUE
|
||||
special_name = "Purge genome"
|
||||
injection_cooldown = 0
|
||||
replenish_cooldown = 300
|
||||
|
||||
/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user)
|
||||
if(!istype(H))
|
||||
return 0
|
||||
H.set_species(/datum/species/human, 1)//lizards go home
|
||||
purrbation_remove(H)//remove cats
|
||||
H.dna.remove_all_mutations()//hulks out
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/implantchair/brainwash
|
||||
name = "Neural Imprinter"
|
||||
desc = "Used to <s>indoctrinate</s> rehabilitate hardened recidivists."
|
||||
special_name = "Imprint"
|
||||
injection_cooldown = 3000
|
||||
auto_inject = FALSE
|
||||
auto_replenish = FALSE
|
||||
special = TRUE
|
||||
var/objective = "Obey the law. Praise Nanotrasen."
|
||||
var/custom = FALSE
|
||||
|
||||
/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user)
|
||||
if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway.
|
||||
return 0
|
||||
if(custom)
|
||||
if(!user || !user.Adjacent(src))
|
||||
return 0
|
||||
objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120)
|
||||
message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
var/datum/objective/custom_objective = new/datum/objective(objective)
|
||||
custom_objective.owner = C.mind
|
||||
C.mind.objectives += custom_objective
|
||||
C.mind.announce_objectives()
|
||||
message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
return 1
|
||||
|
||||
/obj/machinery/implantchair
|
||||
name = "mindshield implanter"
|
||||
desc = "Used to implant occupants with mindshield implants."
|
||||
icon = 'icons/obj/machines/implantchair.dmi'
|
||||
icon_state = "implantchair"
|
||||
density = TRUE
|
||||
opacity = 0
|
||||
anchored = TRUE
|
||||
|
||||
var/ready = TRUE
|
||||
var/replenishing = FALSE
|
||||
|
||||
var/ready_implants = 5
|
||||
var/max_implants = 5
|
||||
var/injection_cooldown = 600
|
||||
var/replenish_cooldown = 6000
|
||||
var/implant_type = /obj/item/implant/mindshield
|
||||
var/auto_inject = FALSE
|
||||
var/auto_replenish = TRUE
|
||||
var/special = FALSE
|
||||
var/special_name = "special function"
|
||||
var/message_cooldown
|
||||
var/breakout_time = 1
|
||||
|
||||
/obj/machinery/implantchair/Initialize()
|
||||
. = ..()
|
||||
open_machine()
|
||||
update_icon()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_interact(mob/user, ui_key = "main", datum/tgui/ui = null, force_open = FALSE, datum/tgui/master_ui = null, datum/ui_state/state = GLOB.notcontained_state)
|
||||
ui = SStgui.try_update_ui(user, src, ui_key, ui, force_open)
|
||||
if(!ui)
|
||||
ui = new(user, src, ui_key, "implantchair", name, 375, 280, master_ui, state)
|
||||
ui.open()
|
||||
|
||||
|
||||
/obj/machinery/implantchair/ui_data()
|
||||
var/list/data = list()
|
||||
data["occupied"] = occupant ? 1 : 0
|
||||
data["open"] = state_open
|
||||
|
||||
data["occupant"] = list()
|
||||
if(occupant)
|
||||
var/mob/living/mob_occupant = occupant
|
||||
data["occupant"]["name"] = mob_occupant.name
|
||||
data["occupant"]["stat"] = mob_occupant.stat
|
||||
|
||||
data["special_name"] = special ? special_name : null
|
||||
data["ready_implants"] = ready_implants
|
||||
data["ready"] = ready
|
||||
data["replenishing"] = replenishing
|
||||
|
||||
return data
|
||||
|
||||
/obj/machinery/implantchair/ui_act(action, params)
|
||||
if(..())
|
||||
return
|
||||
switch(action)
|
||||
if("door")
|
||||
if(state_open)
|
||||
close_machine()
|
||||
else
|
||||
open_machine()
|
||||
. = TRUE
|
||||
if("implant")
|
||||
implant(occupant,usr)
|
||||
. = TRUE
|
||||
|
||||
/obj/machinery/implantchair/proc/implant(mob/living/M,mob/user)
|
||||
if (!istype(M))
|
||||
return
|
||||
if(!ready_implants || !ready)
|
||||
return
|
||||
if(implant_action(M,user))
|
||||
ready_implants--
|
||||
if(!replenishing && auto_replenish)
|
||||
replenishing = TRUE
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
if(injection_cooldown > 0)
|
||||
ready = FALSE
|
||||
addtimer(CALLBACK(src,"set_ready"),injection_cooldown)
|
||||
else
|
||||
playsound(get_turf(src), 'sound/machines/buzz-sigh.ogg', 25, 1)
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/proc/implant_action(mob/living/M)
|
||||
var/obj/item/implant/I = new implant_type
|
||||
if(I.implant(M))
|
||||
visible_message("<span class='warning'>[M] has been implanted by the [name].</span>")
|
||||
return 1
|
||||
|
||||
/obj/machinery/implantchair/update_icon()
|
||||
icon_state = initial(icon_state)
|
||||
if(state_open)
|
||||
icon_state += "_open"
|
||||
if(occupant)
|
||||
icon_state += "_occupied"
|
||||
if(ready)
|
||||
add_overlay("ready")
|
||||
else
|
||||
cut_overlays()
|
||||
|
||||
/obj/machinery/implantchair/proc/replenish()
|
||||
if(ready_implants < max_implants)
|
||||
ready_implants++
|
||||
if(ready_implants < max_implants)
|
||||
addtimer(CALLBACK(src,"replenish"),replenish_cooldown)
|
||||
else
|
||||
replenishing = FALSE
|
||||
|
||||
/obj/machinery/implantchair/proc/set_ready()
|
||||
ready = TRUE
|
||||
update_icon()
|
||||
|
||||
/obj/machinery/implantchair/container_resist(mob/living/user)
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message("<span class='notice'>You see [user] kicking against the door of [src]!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || state_open)
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open_machine()
|
||||
|
||||
/obj/machinery/implantchair/relaymove(mob/user)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
|
||||
/obj/machinery/implantchair/MouseDrop_T(mob/target, mob/user)
|
||||
if(user.stat || user.lying || !Adjacent(user) || !user.Adjacent(target) || !isliving(target) || !user.IsAdvancedToolUser())
|
||||
return
|
||||
close_machine(target)
|
||||
|
||||
/obj/machinery/implantchair/close_machine(mob/living/user)
|
||||
if((isnull(user) || istype(user)) && state_open)
|
||||
..(user)
|
||||
if(auto_inject && ready && ready_implants > 0)
|
||||
implant(user,null)
|
||||
|
||||
/obj/machinery/implantchair/genepurge
|
||||
name = "Genetic purifier"
|
||||
desc = "Used to purge human genome of foreign influences"
|
||||
special = TRUE
|
||||
special_name = "Purge genome"
|
||||
injection_cooldown = 0
|
||||
replenish_cooldown = 300
|
||||
|
||||
/obj/machinery/implantchair/genepurge/implant_action(mob/living/carbon/human/H,mob/user)
|
||||
if(!istype(H))
|
||||
return 0
|
||||
H.set_species(/datum/species/human, 1)//lizards go home
|
||||
purrbation_remove(H)//remove cats
|
||||
H.dna.remove_all_mutations()//hulks out
|
||||
return 1
|
||||
|
||||
|
||||
/obj/machinery/implantchair/brainwash
|
||||
name = "Neural Imprinter"
|
||||
desc = "Used to <s>indoctrinate</s> rehabilitate hardened recidivists."
|
||||
special_name = "Imprint"
|
||||
injection_cooldown = 3000
|
||||
auto_inject = FALSE
|
||||
auto_replenish = FALSE
|
||||
special = TRUE
|
||||
var/objective = "Obey the law. Praise Nanotrasen."
|
||||
var/custom = FALSE
|
||||
|
||||
/obj/machinery/implantchair/brainwash/implant_action(mob/living/C,mob/user)
|
||||
if(!istype(C) || !C.mind) // I don't know how this makes any sense for silicons but laws trump objectives anyway.
|
||||
return 0
|
||||
if(custom)
|
||||
if(!user || !user.Adjacent(src))
|
||||
return 0
|
||||
objective = stripped_input(usr,"What order do you want to imprint on [C]?","Enter the order","",120)
|
||||
message_admins("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
log_game("[key_name_admin(user)] set brainwash machine objective to '[objective]'.")
|
||||
var/datum/objective/custom_objective = new/datum/objective(objective)
|
||||
custom_objective.owner = C.mind
|
||||
C.mind.objectives += custom_objective
|
||||
C.mind.announce_objectives()
|
||||
message_admins("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
log_game("[key_name_admin(user)] brainwashed [key_name_admin(C)] with objective '[objective]'.")
|
||||
return 1
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
//Pinpointers are used to track atoms from a distance as long as they're on the same z-level. The captain and nuke ops have ones that track the nuclear authentication disk.
|
||||
/obj/item/pinpointer
|
||||
name = "pinpointer"
|
||||
desc = "A handheld tracking device that locks onto certain signals."
|
||||
icon = 'icons/obj/device.dmi'
|
||||
icon_state = "pinpointer"
|
||||
flags_1 = CONDUCT_1
|
||||
slot_flags = SLOT_BELT
|
||||
w_class = WEIGHT_CLASS_SMALL
|
||||
item_state = "electronic"
|
||||
lefthand_file = 'icons/mob/inhands/misc/devices_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
throw_speed = 3
|
||||
throw_range = 7
|
||||
materials = list(MAT_METAL = 500, MAT_GLASS = 250)
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | ACID_PROOF
|
||||
var/active = FALSE
|
||||
var/atom/movable/target //The thing we're searching for
|
||||
var/minimum_range = 0 //at what range the pinpointer declares you to be at your destination
|
||||
var/alert = FALSE // TRUE to display things more seriously
|
||||
|
||||
/obj/item/pinpointer/Initialize()
|
||||
. = ..()
|
||||
GLOB.pinpointer_list += src
|
||||
|
||||
/obj/item/pinpointer/Destroy()
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
GLOB.pinpointer_list -= src
|
||||
return ..()
|
||||
|
||||
/obj/item/pinpointer/attack_self(mob/living/user)
|
||||
active = !active
|
||||
user.visible_message("<span class='notice'>[user] [active ? "" : "de"]activates their pinpointer.</span>", "<span class='notice'>You [active ? "" : "de"]activate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
if(active)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
else
|
||||
target = null
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/pinpointer/process()
|
||||
if(!active)
|
||||
return PROCESS_KILL
|
||||
scan_for_target()
|
||||
update_icon()
|
||||
|
||||
/obj/item/pinpointer/proc/scan_for_target()
|
||||
return
|
||||
|
||||
/obj/item/pinpointer/update_icon()
|
||||
cut_overlays()
|
||||
if(!active)
|
||||
return
|
||||
if(!target)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
var/turf/here = get_turf(src)
|
||||
var/turf/there = get_turf(target)
|
||||
if(here.z != there.z)
|
||||
add_overlay("pinon[alert ? "alert" : ""]null")
|
||||
return
|
||||
if(get_dist_euclidian(here,there) <= minimum_range)
|
||||
add_overlay("pinon[alert ? "alert" : ""]direct")
|
||||
else
|
||||
setDir(get_dir(here, there))
|
||||
switch(get_dist(here, there))
|
||||
if(1 to 8)
|
||||
add_overlay("pinon[alert ? "alert" : "close"]")
|
||||
if(9 to 16)
|
||||
add_overlay("pinon[alert ? "alert" : "medium"]")
|
||||
if(16 to INFINITY)
|
||||
add_overlay("pinon[alert ? "alert" : "far"]")
|
||||
|
||||
/obj/item/pinpointer/crew // A replacement for the old crew monitoring consoles
|
||||
name = "crew pinpointer"
|
||||
desc = "A handheld tracking device that points to crew suit sensors."
|
||||
icon_state = "pinpointer_crew"
|
||||
|
||||
/obj/item/pinpointer/crew/proc/trackable(mob/living/carbon/human/H)
|
||||
var/turf/here = get_turf(src)
|
||||
if((H.z == 0 || H.z == here.z) && istype(H.w_uniform, /obj/item/clothing/under))
|
||||
var/obj/item/clothing/under/U = H.w_uniform
|
||||
|
||||
// Suit sensors must be on maximum.
|
||||
if(!U.has_sensor || U.sensor_mode < SENSOR_COORDS)
|
||||
return FALSE
|
||||
|
||||
var/turf/there = get_turf(H)
|
||||
return (H.z != 0 || (there && there.z == H.z))
|
||||
|
||||
return FALSE
|
||||
|
||||
/obj/item/pinpointer/crew/attack_self(mob/living/user)
|
||||
if(active)
|
||||
active = FALSE
|
||||
user.visible_message("<span class='notice'>[user] deactivates their pinpointer.</span>", "<span class='notice'>You deactivate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
target = null //Restarting the pinpointer forces a target reset
|
||||
STOP_PROCESSING(SSfastprocess, src)
|
||||
update_icon()
|
||||
return
|
||||
|
||||
var/list/name_counts = list()
|
||||
var/list/names = list()
|
||||
|
||||
for(var/mob/living/carbon/human/H in GLOB.mob_list)
|
||||
if(!trackable(H))
|
||||
continue
|
||||
|
||||
var/crewmember_name = "Unknown"
|
||||
if(H.wear_id)
|
||||
var/obj/item/card/id/I = H.wear_id.GetID()
|
||||
crewmember_name = I.registered_name
|
||||
|
||||
while(crewmember_name in name_counts)
|
||||
name_counts[crewmember_name]++
|
||||
crewmember_name = text("[] ([])", crewmember_name, name_counts[crewmember_name])
|
||||
names[crewmember_name] = H
|
||||
name_counts[crewmember_name] = 1
|
||||
|
||||
if(!names.len)
|
||||
user.visible_message("<span class='notice'>[user]'s pinpointer fails to detect a signal.</span>", "<span class='notice'>Your pinpointer fails to detect a signal.</span>")
|
||||
return
|
||||
|
||||
var/A = input(user, "Person to track", "Pinpoint") in names
|
||||
if(!A || QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated())
|
||||
return
|
||||
|
||||
target = names[A]
|
||||
active = TRUE
|
||||
user.visible_message("<span class='notice'>[user] activates their pinpointer.</span>", "<span class='notice'>You activate your pinpointer.</span>")
|
||||
playsound(src, 'sound/items/screwdriver2.ogg', 50, 1)
|
||||
START_PROCESSING(SSfastprocess, src)
|
||||
update_icon()
|
||||
|
||||
/obj/item/pinpointer/crew/scan_for_target()
|
||||
if(target)
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(!trackable(H))
|
||||
target = null
|
||||
if(!target) //target can be set to null from above code, or elsewhere
|
||||
active = FALSE
|
||||
|
||||
/obj/item/pinpointer/process()
|
||||
if(!active)
|
||||
return PROCESS_KILL
|
||||
scan_for_target()
|
||||
update_icon()
|
||||
|
||||
@@ -1,27 +1,201 @@
|
||||
/obj/item/banner
|
||||
name = "banner"
|
||||
desc = "A banner with Nanotrasen's logo on it."
|
||||
icon = 'icons/obj/items_and_weapons.dmi'
|
||||
icon_state = "banner"
|
||||
item_state = "banner"
|
||||
force = 8
|
||||
attack_verb = list("forcefully inspired", "violently encouraged", "relentlessly galvanized")
|
||||
lefthand_file = 'icons/mob/inhands/equipment/banners_lefthand.dmi'
|
||||
righthand_file = 'icons/mob/inhands/equipment/banners_righthand.dmi'
|
||||
desc = "A banner with Nanotrasen's logo on it."
|
||||
var/moralecooldown = 0
|
||||
var/moralewait = 600
|
||||
var/inspiration_available = TRUE //If this banner can be used to inspire crew
|
||||
var/morale_time = 0
|
||||
var/morale_cooldown = 600 //How many deciseconds between uses
|
||||
var/list/job_loyalties //Mobs with any of these assigned roles will be inspired
|
||||
var/list/role_loyalties //Mobs with any of these special roles will be inspired
|
||||
var/warcry
|
||||
|
||||
/obj/item/banner/examine(mob/user)
|
||||
..()
|
||||
if(inspiration_available)
|
||||
to_chat(user, "<span class='notice'>Activate it in your hand to inspire nearby allies of this banner's allegiance!</span>")
|
||||
|
||||
/obj/item/banner/attack_self(mob/living/carbon/human/user)
|
||||
if(moralecooldown + moralewait > world.time)
|
||||
if(!inspiration_available)
|
||||
return
|
||||
to_chat(user, "<span class='notice'>You increase the morale of your fellows!</span>")
|
||||
moralecooldown = world.time
|
||||
if(morale_time > world.time)
|
||||
to_chat(user, "<span class='warning'>You aren't feeling inspired enough to flourish [src] again yet.</span>")
|
||||
return
|
||||
user.visible_message("<span class='big notice'>[user] flourishes [src]!</span>", \
|
||||
"<span class='notice'>You raise [src] skywards, inspiring your allies!</span>")
|
||||
playsound(src, "rustle", 100, FALSE)
|
||||
if(warcry)
|
||||
user.say("[warcry]")
|
||||
var/old_transform = user.transform
|
||||
user.transform *= 1.2
|
||||
animate(user, transform = old_transform, time = 10)
|
||||
morale_time = world.time + morale_cooldown
|
||||
|
||||
for(var/mob/living/carbon/human/H in range(4,get_turf(src)))
|
||||
to_chat(H, "<span class='notice'>Your morale is increased by [user]'s banner!</span>")
|
||||
H.adjustBruteLoss(-15)
|
||||
H.adjustFireLoss(-15)
|
||||
H.AdjustStun(-40)
|
||||
H.AdjustKnockdown(-40)
|
||||
H.AdjustUnconscious(-40)
|
||||
var/list/inspired = list()
|
||||
var/has_job_loyalties = LAZYLEN(job_loyalties)
|
||||
var/has_role_loyalties = LAZYLEN(role_loyalties)
|
||||
inspired += user //The user is always inspired, regardless of loyalties
|
||||
for(var/mob/living/carbon/human/H in range(4, get_turf(src)))
|
||||
if(H.stat == DEAD || H == user)
|
||||
continue
|
||||
if(H.mind && (has_job_loyalties || has_role_loyalties))
|
||||
if(has_job_loyalties && H.mind.assigned_role in job_loyalties)
|
||||
inspired += H
|
||||
else if(has_role_loyalties && H.mind.special_role in role_loyalties)
|
||||
inspired += H
|
||||
else if(check_inspiration(H))
|
||||
inspired += H
|
||||
|
||||
for(var/V in inspired)
|
||||
var/mob/living/carbon/human/H = V
|
||||
if(H != user)
|
||||
to_chat(H, "<span class='notice'>Your confidence surges as [user] flourishes [user.p_their()] [name]!</span>")
|
||||
inspiration(H)
|
||||
special_inspiration(H)
|
||||
|
||||
/obj/item/banner/proc/check_inspiration(mob/living/carbon/human/H) //Banner-specific conditions for being eligible
|
||||
return
|
||||
|
||||
/obj/item/banner/proc/inspiration(mob/living/carbon/human/H)
|
||||
H.adjustBruteLoss(-15)
|
||||
H.adjustFireLoss(-15)
|
||||
H.AdjustStun(-40)
|
||||
H.AdjustKnockdown(-40)
|
||||
H.AdjustUnconscious(-40)
|
||||
playsound(H, 'sound/magic/staff_healing.ogg', 25, FALSE)
|
||||
|
||||
/obj/item/banner/proc/special_inspiration(mob/living/carbon/human/H) //Any banner-specific inspiration effects go here
|
||||
return
|
||||
|
||||
/obj/item/banner/security
|
||||
name = "securistan banner"
|
||||
desc = "The banner of Securistan, ruling the station with an iron fist."
|
||||
icon_state = "banner_security"
|
||||
job_loyalties = list("Security Officer", "Warden", "Detective", "Head of Security")
|
||||
warcry = "EVERYONE DOWN ON THE GROUND!!"
|
||||
|
||||
/obj/item/banner/security/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/datum/crafting_recipe/security_banner
|
||||
name = "Securistan Banner"
|
||||
result = /obj/item/banner/security/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/security = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/medical
|
||||
name = "meditopia banner"
|
||||
desc = "The banner of Meditopia, generous benefactors that cure wounds and shelter the weak."
|
||||
icon_state = "banner_medical"
|
||||
job_loyalties = list("Medical Doctor", "Chemist", "Geneticist", "Virologist", "Chief Medical Officer")
|
||||
warcry = "No wounds cannot be healed!"
|
||||
|
||||
/obj/item/banner/medical/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/medical/check_inspiration(mob/living/carbon/human/H)
|
||||
return H.stat //Meditopia is moved to help those in need
|
||||
|
||||
/datum/crafting_recipe/medical_banner
|
||||
name = "Meditopia Banner"
|
||||
result = /obj/item/banner/medical/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/medical = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/medical/special_inspiration(mob/living/carbon/human/H)
|
||||
H.adjustToxLoss(-15)
|
||||
H.setOxyLoss(0)
|
||||
H.reagents.add_reagent("inaprovaline", 5)
|
||||
|
||||
/obj/item/banner/science
|
||||
name = "sciencia banner"
|
||||
desc = "The banner of Sciencia, bold and daring thaumaturges and researchers that take the path less traveled."
|
||||
icon_state = "banner_science"
|
||||
job_loyalties = list("Scientist", "Roboticist", "Research Director")
|
||||
warcry = "For Cuban Pete!"
|
||||
|
||||
/obj/item/banner/science/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/science/check_inspiration(mob/living/carbon/human/H)
|
||||
return H.on_fire //Sciencia is pleased by dedication to the art of Toxins
|
||||
|
||||
/datum/crafting_recipe/science_banner
|
||||
name = "Sciencia Banner"
|
||||
result = /obj/item/banner/science/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/scientist = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/cargo
|
||||
name = "cargonia banner"
|
||||
desc = "The banner of the eternal Cargonia, with the mystical power of conjuring any object into existence."
|
||||
icon_state = "banner_cargo"
|
||||
job_loyalties = list("Cargo Technician", "Shaft Miner", "Quartermaster")
|
||||
warcry = "Hail Cargonia!"
|
||||
|
||||
/obj/item/banner/cargo/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/datum/crafting_recipe/cargo_banner
|
||||
name = "Cargonia Banner"
|
||||
result = /obj/item/banner/cargo/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/cargotech = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/engineering
|
||||
name = "engitopia banner"
|
||||
desc = "The banner of Engitopia, wielders of limitless power."
|
||||
icon_state = "banner_engineering"
|
||||
job_loyalties = list("Station Engineer", "Atmospheric Technician", "Chief Engineer")
|
||||
warcry = "All hail lord Singuloth!!"
|
||||
|
||||
/obj/item/banner/engineering/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/engineering/special_inspiration(mob/living/carbon/human/H)
|
||||
H.radiation = 0
|
||||
|
||||
/datum/crafting_recipe/engineering_banner
|
||||
name = "Engitopia Banner"
|
||||
result = /obj/item/banner/engineering/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/rank/engineer = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/command
|
||||
name = "command banner"
|
||||
desc = "The banner of Command, a staunch and ancient line of bueraucratic kings and queens."
|
||||
//No icon state here since the default one is the NT banner
|
||||
job_loyalties = list("Captain", "Head of Personnel", "Chief Engineer", "Head of Security", "Research Director", "Chief Medical Officer")
|
||||
warcry = "Hail Nanotrasen!"
|
||||
|
||||
/obj/item/banner/command/mundane
|
||||
inspiration_available = FALSE
|
||||
|
||||
/obj/item/banner/command/check_inspiration(mob/living/carbon/human/H)
|
||||
return H.isloyal() //Command is stalwart but rewards their allies.
|
||||
|
||||
/datum/crafting_recipe/command_banner
|
||||
name = "Command Banner"
|
||||
result = /obj/item/banner/command/mundane
|
||||
time = 40
|
||||
reqs = list(/obj/item/stack/rods = 2,
|
||||
/obj/item/clothing/under/captainparade = 1)
|
||||
category = CAT_MISC
|
||||
|
||||
/obj/item/banner/red
|
||||
name = "red banner"
|
||||
|
||||
+790
-790
File diff suppressed because it is too large
Load Diff
@@ -487,7 +487,7 @@
|
||||
righthand_file = 'icons/mob/inhands/weapons/chainsaw_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
force = 13
|
||||
var/force_on = 21
|
||||
var/force_on = 24
|
||||
w_class = WEIGHT_CLASS_HUGE
|
||||
throwforce = 13
|
||||
throw_speed = 2
|
||||
|
||||
+586
-586
File diff suppressed because it is too large
Load Diff
@@ -169,6 +169,7 @@
|
||||
return
|
||||
|
||||
/obj/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(!anchored || current_size >= STAGE_FIVE)
|
||||
step_towards(src,S)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
integrity_failure = 50
|
||||
armor = list(melee = 20, bullet = 10, laser = 10, energy = 0, bomb = 10, bio = 0, rad = 0, fire = 70, acid = 60)
|
||||
var/breakout_time = 2
|
||||
var/lastbang
|
||||
var/message_cooldown
|
||||
var/can_weld_shut = TRUE
|
||||
var/horizontal = FALSE
|
||||
var/allow_objects = FALSE
|
||||
@@ -300,14 +300,12 @@
|
||||
/obj/structure/closet/relaymove(mob/user)
|
||||
if(user.stat || !isturf(loc) || !isliving(user))
|
||||
return
|
||||
var/mob/living/L = user
|
||||
if(!open())
|
||||
if(L.last_special <= world.time)
|
||||
container_resist(L)
|
||||
if(world.time > lastbang+5)
|
||||
lastbang = world.time
|
||||
for(var/mob/M in get_hearers_in_view(src, null))
|
||||
M.show_message("<FONT size=[max(0, 5 - get_dist(src, M))]>BANG, bang!</FONT>", 2)
|
||||
if(locked)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
container_resist()
|
||||
|
||||
/obj/structure/closet/attack_hand(mob/user)
|
||||
..()
|
||||
@@ -367,9 +365,10 @@
|
||||
//okay, so the closet is either welded or locked... resist!!!
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
to_chat(user, "<span class='notice'>You lean on the back of [src] and start pushing the door open.</span>")
|
||||
visible_message("<span class='warning'>[src] begins to shake violently!</span>")
|
||||
if(do_after(user,(breakout_time * 60 * 10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
user.visible_message("<span class='warning'>[src] begins to shake violently!</span>", \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the door open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear banging from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src || opened || (!locked && !welded) )
|
||||
return
|
||||
//we check after a while whether there is a point of resisting anymore and whether the user is capable of resisting
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
new /obj/item/storage/belt/security/full(src)
|
||||
new /obj/item/gun/energy/e_gun/hos(src)
|
||||
new /obj/item/device/flashlight/seclite(src)
|
||||
new /obj/item/pinpointer(src)
|
||||
new /obj/item/pinpointer/nuke(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/warden
|
||||
name = "\proper warden's locker"
|
||||
@@ -108,6 +108,7 @@
|
||||
new /obj/item/clothing/gloves/krav_maga/sec(src)
|
||||
new /obj/item/door_remote/head_of_security(src)
|
||||
new /obj/item/gun/ballistic/shotgun/automatic/combat/compact(src)
|
||||
new /obj/item/pinpointer/crew(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/security
|
||||
name = "security officer's locker"
|
||||
@@ -183,6 +184,7 @@
|
||||
new /obj/item/reagent_containers/spray/pepper(src)
|
||||
new /obj/item/clothing/suit/armor/vest/det_suit(src)
|
||||
new /obj/item/storage/belt/holster/full(src)
|
||||
new /obj/item/pinpointer/crew(src)
|
||||
new /obj/item/device/mass_spectrometer(src)
|
||||
|
||||
/obj/structure/closet/secure_closet/injection
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/lattice/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FOUR)
|
||||
deconstruct()
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
var/obj/structure/tray/connected = null
|
||||
var/locked = FALSE
|
||||
var/opendir = SOUTH
|
||||
var/message_cooldown
|
||||
var/breakout_time = 1
|
||||
|
||||
/obj/structure/bodycontainer/Destroy()
|
||||
open()
|
||||
@@ -41,6 +43,11 @@
|
||||
/obj/structure/bodycontainer/relaymove(mob/user)
|
||||
if(user.stat || !isturf(loc))
|
||||
return
|
||||
if(locked)
|
||||
if(message_cooldown <= world.time)
|
||||
message_cooldown = world.time + 50
|
||||
to_chat(user, "<span class='warning'>[src]'s door won't budge!</span>")
|
||||
return
|
||||
open()
|
||||
|
||||
/obj/structure/bodycontainer/attack_paw(mob/user)
|
||||
@@ -84,11 +91,20 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/bodycontainer/container_resist(mob/living/user)
|
||||
open()
|
||||
|
||||
/obj/structure/bodycontainer/relay_container_resist(mob/living/user, obj/O)
|
||||
to_chat(user, "<span class='notice'>You slam yourself into the side of [O].</span>")
|
||||
container_resist(user)
|
||||
if(!locked)
|
||||
open()
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
user.visible_message(null, \
|
||||
"<span class='notice'>You lean on the back of [src] and start pushing the tray open... (this will take about [(breakout_time<1) ? "[breakout_time*60] seconds" : "[breakout_time] minute\s"].)</span>", \
|
||||
"<span class='italics'>You hear a metallic creaking from [src].</span>")
|
||||
if(do_after(user,(breakout_time*60*10), target = src)) //minutes * 60seconds * 10deciseconds
|
||||
if(!user || user.stat != CONSCIOUS || user.loc != src )
|
||||
return
|
||||
user.visible_message("<span class='warning'>[user] successfully broke out of [src]!</span>", \
|
||||
"<span class='notice'>You successfully break out of [src]!</span>")
|
||||
open()
|
||||
|
||||
/obj/structure/bodycontainer/proc/open()
|
||||
playsound(src.loc, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
return ..()
|
||||
|
||||
/obj/structure/transit_tube/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct(FALSE)
|
||||
|
||||
|
||||
@@ -62,10 +62,14 @@
|
||||
AM.ex_act(severity, target)
|
||||
|
||||
/obj/structure/transit_tube_pod/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct(FALSE)
|
||||
|
||||
/obj/structure/transit_tube_pod/container_resist(mob/living/user)
|
||||
if(!user.incapacitated())
|
||||
empty_pod()
|
||||
return
|
||||
if(!moving)
|
||||
user.changeNext_move(CLICK_CD_BREAKOUT)
|
||||
user.last_special = world.time + CLICK_CD_BREAKOUT
|
||||
|
||||
@@ -105,6 +105,7 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/structure/window/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
deconstruct(FALSE)
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
var/wet = 0
|
||||
var/wet_time = 0 // Time in seconds that this floor will be wet for.
|
||||
var/mutable_appearance/wet_overlay
|
||||
var/postdig_icon_change = FALSE
|
||||
var/postdig_icon
|
||||
var/list/archdrops
|
||||
|
||||
/turf/open/indestructible
|
||||
name = "floor"
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
return make_plating()
|
||||
|
||||
/turf/open/floor/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size == STAGE_THREE)
|
||||
if(prob(30))
|
||||
if(floor_tile)
|
||||
|
||||
@@ -269,6 +269,7 @@
|
||||
narsie_act(force, ignore_mobs, probability)
|
||||
|
||||
/turf/open/floor/vines/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
if(prob(50))
|
||||
ChangeTurf(src.baseturf)
|
||||
|
||||
@@ -9,11 +9,11 @@
|
||||
icon = 'icons/turf/floors.dmi'
|
||||
icon_state = "asteroid"
|
||||
icon_plating = "asteroid"
|
||||
postdig_icon_change = TRUE
|
||||
var/environment_type = "asteroid"
|
||||
var/turf_type = /turf/open/floor/plating/asteroid //Because caves do whacky shit to revert to normal
|
||||
var/dug = 0 //0 = has not yet been dug, 1 = has already been dug
|
||||
var/sand_type = /obj/item/ore/glass
|
||||
var/floor_variance = 20 //probability floor has a different icon state
|
||||
archdrops = list(/obj/item/ore/glass = 5)
|
||||
|
||||
/turf/open/floor/plating/asteroid/Initialize()
|
||||
var/proper_name = name
|
||||
@@ -22,6 +22,9 @@
|
||||
if(prob(floor_variance))
|
||||
icon_state = "[environment_type][rand(0,12)]"
|
||||
|
||||
if(LAZYLEN(archdrops))
|
||||
AddComponent(/datum/component/archaeology, 100, archdrops)
|
||||
|
||||
/turf/open/floor/plating/asteroid/burn_tile()
|
||||
return
|
||||
|
||||
@@ -31,46 +34,7 @@
|
||||
/turf/open/floor/plating/asteroid/MakeDry(wet_setting = TURF_WET_WATER)
|
||||
return
|
||||
|
||||
/turf/open/floor/plating/asteroid/ex_act(severity, target)
|
||||
contents_explosion(severity, target)
|
||||
switch(severity)
|
||||
if(3)
|
||||
return
|
||||
if(2)
|
||||
if(prob(20))
|
||||
src.gets_dug()
|
||||
if(1)
|
||||
src.gets_dug()
|
||||
|
||||
/turf/open/floor/plating/asteroid/attackby(obj/item/W, mob/user, params)
|
||||
//note that this proc does not call ..()
|
||||
if(!W || !user)
|
||||
return 0
|
||||
var/digging_speed = 0
|
||||
if (istype(W, /obj/item/shovel))
|
||||
var/obj/item/shovel/S = W
|
||||
digging_speed = S.digspeed
|
||||
else if (istype(W, /obj/item/pickaxe))
|
||||
var/obj/item/pickaxe/P = W
|
||||
digging_speed = P.digspeed
|
||||
if (digging_speed)
|
||||
var/turf/T = user.loc
|
||||
if(!isturf(T))
|
||||
return
|
||||
|
||||
if (dug)
|
||||
to_chat(user, "<span class='warning'>This area has already been dug!</span>")
|
||||
return
|
||||
|
||||
to_chat(user, "<span class='notice'>You start digging...</span>")
|
||||
playsound(src, 'sound/effects/shovel_dig.ogg', 50, 1)
|
||||
|
||||
if(do_after(user, digging_speed, target = src))
|
||||
if(istype(src, /turf/open/floor/plating/asteroid))
|
||||
to_chat(user, "<span class='notice'>You dig a hole.</span>")
|
||||
gets_dug()
|
||||
SSblackbox.add_details("pick_used_mining","[W.type]")
|
||||
|
||||
if(istype(W, /obj/item/storage/bag/ore))
|
||||
var/obj/item/storage/bag/ore/S = W
|
||||
if(S.collection_mode == 1)
|
||||
@@ -88,37 +52,16 @@
|
||||
var/turf/open/floor/light/F = T
|
||||
F.state = L.state
|
||||
playsound(src, 'sound/weapons/genhit.ogg', 50, 1)
|
||||
|
||||
/turf/open/floor/plating/asteroid/proc/gets_dug()
|
||||
if(dug)
|
||||
return
|
||||
for(var/i in 1 to 5)
|
||||
new sand_type(src)
|
||||
dug = 1
|
||||
icon_plating = "[environment_type]_dug"
|
||||
icon_state = "[environment_type]_dug"
|
||||
slowdown = 0
|
||||
return
|
||||
|
||||
return ..()
|
||||
|
||||
|
||||
/turf/open/floor/plating/asteroid/singularity_act()
|
||||
if(turf_z_is_planet(src))
|
||||
return ..()
|
||||
ChangeTurf(/turf/open/space)
|
||||
|
||||
/turf/open/floor/plating/asteroid/singularity_pull(S, current_size)
|
||||
if(dug)
|
||||
return
|
||||
switch(current_size)
|
||||
if(STAGE_THREE)
|
||||
if(!prob(30))
|
||||
gets_dug()
|
||||
if(STAGE_FOUR)
|
||||
if(prob(50))
|
||||
gets_dug()
|
||||
else
|
||||
if(current_size >= STAGE_FIVE && prob(70))
|
||||
gets_dug()
|
||||
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt
|
||||
name = "volcanic floor"
|
||||
@@ -127,7 +70,7 @@
|
||||
icon_state = "basalt"
|
||||
icon_plating = "basalt"
|
||||
environment_type = "basalt"
|
||||
sand_type = /obj/item/ore/glass/basalt
|
||||
archdrops = list(/obj/item/ore/glass/basalt = 5)
|
||||
floor_variance = 15
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt/lava //lava underneath
|
||||
@@ -147,10 +90,10 @@
|
||||
if("basalt5", "basalt9")
|
||||
B.set_light(1.4, 0.6, LIGHT_COLOR_LAVA) //barely anything!
|
||||
|
||||
/turf/open/floor/plating/asteroid/basalt/gets_dug()
|
||||
if(!dug)
|
||||
set_light(0)
|
||||
/turf/open/floor/plating/asteroid/basalt/ComponentActivated(datum/component/C)
|
||||
..()
|
||||
if(istype(C, /datum/component/archaeology))
|
||||
set_light(0)
|
||||
|
||||
|
||||
///////Surface. The surface is warm, but survivable without a suit. Internals are required. The floors break to chasms, which drop you into the underground.
|
||||
@@ -340,8 +283,8 @@
|
||||
initial_gas_mix = "TEMP=180"
|
||||
slowdown = 2
|
||||
environment_type = "snow"
|
||||
sand_type = /obj/item/stack/sheet/mineral/snow
|
||||
flags_1 = NONE
|
||||
archdrops = list(/obj/item/stack/sheet/mineral/snow = 5)
|
||||
|
||||
/turf/open/floor/plating/asteroid/snow/airless
|
||||
initial_gas_mix = "TEMP=2.7"
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
make_plating(1)
|
||||
|
||||
/turf/open/floor/engine/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
if(floor_tile)
|
||||
if(prob(30))
|
||||
|
||||
@@ -247,6 +247,7 @@
|
||||
icon_state = "r_wall"
|
||||
|
||||
/turf/closed/wall/r_wall/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
if(prob(30))
|
||||
dismantle_wall()
|
||||
|
||||
@@ -245,6 +245,7 @@
|
||||
QDEL_IN(O, 50)
|
||||
|
||||
/turf/closed/wall/singularity_pull(S, current_size)
|
||||
..()
|
||||
if(current_size >= STAGE_FIVE)
|
||||
if(prob(50))
|
||||
dismantle_wall()
|
||||
|
||||
@@ -524,12 +524,12 @@
|
||||
|
||||
/turf/proc/photograph(limit=20)
|
||||
var/image/I = new()
|
||||
I.overlays += src
|
||||
I.add_overlay(src)
|
||||
for(var/V in contents)
|
||||
var/atom/A = V
|
||||
if(A.invisibility)
|
||||
continue
|
||||
I.overlays += A
|
||||
I.add_overlay(A)
|
||||
if(limit)
|
||||
limit--
|
||||
else
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
GLOBAL_VAR(security_mode)
|
||||
GLOBAL_PROTECT(security_mode)
|
||||
|
||||
/world/New()
|
||||
log_world("World loaded at [time_stamp()]")
|
||||
|
||||
@@ -5,6 +8,8 @@
|
||||
|
||||
GLOB.config_error_log = GLOB.sql_error_log = GLOB.world_href_log = GLOB.world_runtime_log = GLOB.world_attack_log = GLOB.world_game_log = file("data/logs/config_error.log") //temporary file used to record errors with loading config, moved to log directory once logging is set bl
|
||||
|
||||
CheckSecurityMode()
|
||||
|
||||
make_datum_references_lists() //initialises global lists for referencing frequently used datums (so that we only ever do it once)
|
||||
|
||||
config = new
|
||||
@@ -94,6 +99,20 @@
|
||||
if(GLOB.round_id)
|
||||
log_game("Round ID: [GLOB.round_id]")
|
||||
|
||||
/world/proc/CheckSecurityMode()
|
||||
//try to write to data
|
||||
if(!text2file("The world is running at least safe mode", "data/server_security_check.lock"))
|
||||
GLOB.security_mode = SECURITY_ULTRASAFE
|
||||
warning("/tg/station 13 is not supported in ultrasafe security mode. Everything will break!")
|
||||
return
|
||||
|
||||
//try to shell
|
||||
if(shell("echo \"The world is running in trusted mode\"") != null)
|
||||
GLOB.security_mode = SECURITY_TRUSTED
|
||||
else
|
||||
GLOB.security_mode = SECURITY_SAFE
|
||||
warning("/tg/station 13 uses many file operations, a few shell()s, and some external call()s. Trusted mode is recommended. You can download our source code for your own browsing and compilation at https://github.com/tgstation/tgstation")
|
||||
|
||||
/world/Topic(T, addr, master, key)
|
||||
var/list/input = params2list(T)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user