Shows assemblies some love. ♥

This commit is contained in:
ShizCalev
2018-05-06 08:05:37 -04:00
committed by CitadelStationBot
parent 11c1e8fbf7
commit 6415ecdbe9
21 changed files with 432 additions and 261 deletions

View File

@@ -58,6 +58,36 @@
attacher = user attacher = user
return return
//Attached device memes
/obj/item/transfer_valve/Move()
. = ..()
if(attached_device)
attached_device.holder_movement()
/obj/item/transfer_valve/dropped()
. = ..()
if(attached_device)
attached_device.dropped()
/obj/item/transfer_valve/on_found(mob/finder)
if(attached_device)
attached_device.on_found(finder)
/obj/item/transfer_valve/Crossed(atom/movable/AM as mob|obj)
. = ..()
if(attached_device)
attached_device.Crossed(AM)
/obj/item/transfer_valve/attack_hand()//Triggers mousetraps
. = ..()
if(.)
return
if(attached_device)
attached_device.attack_hand()
//These keep attached devices synced up, for example a TTV with a mouse trap being found in a bag so it's triggered, or moving the TTV with an infrared beam sensor to update the beam's direction.
/obj/item/transfer_valve/attack_self(mob/user) /obj/item/transfer_valve/attack_self(mob/user)
user.set_machine(src) user.set_machine(src)
var/dat = {"<B> Valve properties: </B> var/dat = {"<B> Valve properties: </B>
@@ -91,8 +121,7 @@
toggle_valve() toggle_valve()
else if(attached_device) else if(attached_device)
if(href_list["rem_device"]) if(href_list["rem_device"])
attached_device.forceMove(drop_location()) attached_device.on_detach()
attached_device.holder = null
attached_device = null attached_device = null
update_icon() update_icon()
if(href_list["device"]) if(href_list["device"])
@@ -127,6 +156,10 @@
underlays += J underlays += J
if(attached_device) if(attached_device)
add_overlay("device") add_overlay("device")
if(istype(attached_device, /obj/item/assembly/infra))
var/obj/item/assembly/infra/sensor = attached_device
if(sensor.on && sensor.visible)
add_overlay("proxy_beam")
/obj/item/transfer_valve/proc/merge_gases() /obj/item/transfer_valve/proc/merge_gases()
tank_two.air_contents.volume += tank_one.air_contents.volume tank_two.air_contents.volume += tank_one.air_contents.volume

View File

@@ -3,6 +3,7 @@
#define WIRE_PULSE_SPECIAL (1<<2) #define WIRE_PULSE_SPECIAL (1<<2)
#define WIRE_RADIO_RECEIVE (1<<3) #define WIRE_RADIO_RECEIVE (1<<3)
#define WIRE_RADIO_PULSE (1<<4) #define WIRE_RADIO_PULSE (1<<4)
#define ASSEMBLY_BEEP_VOLUME 5
/obj/item/assembly /obj/item/assembly
name = "assembly" name = "assembly"
@@ -16,6 +17,8 @@
throw_speed = 3 throw_speed = 3
throw_range = 7 throw_range = 7
var/is_position_sensitive = FALSE //set to true if the device has different icons for each position.
//This will prevent things such as visible lasers from facing the incorrect direction when transformed by assembly_holder's update_icon()
var/secured = TRUE var/secured = TRUE
var/list/attached_overlays = null var/list/attached_overlays = null
var/obj/item/assembly_holder/holder = null var/obj/item/assembly_holder/holder = null
@@ -30,14 +33,18 @@
/obj/item/assembly/proc/on_attach() /obj/item/assembly/proc/on_attach()
/obj/item/assembly/proc/on_detach() /obj/item/assembly/proc/on_detach() //call this when detaching it from a device. handles any special functions that need to be updated ex post facto
if(!holder)
return FALSE
forceMove(holder.drop_location())
holder = null
return TRUE
/obj/item/assembly/proc/holder_movement() //Called when the holder is moved /obj/item/assembly/proc/holder_movement() //Called when the holder is moved
return if(!holder)
return FALSE
/obj/item/assembly/proc/describe() // Called by grenades to describe the state of the trigger (time left, etc) setDir(holder.dir)
return "The trigger assembly looks broken!" return TRUE
/obj/item/assembly/proc/is_secured(mob/user) /obj/item/assembly/proc/is_secured(mob/user)
if(!secured) if(!secured)
@@ -47,7 +54,7 @@
//Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs //Called when another assembly acts on this one, var/radio will determine where it came from for wire calcs
/obj/item/assembly/proc/pulsed(radio = 0) /obj/item/assembly/proc/pulsed(radio = FALSE)
if(wire_type & WIRE_RECEIVE) if(wire_type & WIRE_RECEIVE)
INVOKE_ASYNC(src, .proc/activate) INVOKE_ASYNC(src, .proc/activate)
if(radio && (wire_type & WIRE_RADIO_RECEIVE)) if(radio && (wire_type & WIRE_RADIO_RECEIVE))
@@ -56,7 +63,7 @@
//Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct //Called when this device attempts to act on another device, var/radio determines if it was sent via radio or direct
/obj/item/assembly/proc/pulse(radio = 0) /obj/item/assembly/proc/pulse(radio = FALSE)
if(connected && wire_type) if(connected && wire_type)
connected.pulse_assembly(src) connected.pulse_assembly(src)
return TRUE return TRUE
@@ -91,21 +98,19 @@
else else
to_chat(user, "<span class='warning'>Both devices must be in attachable mode to be attached together.</span>") to_chat(user, "<span class='warning'>Both devices must be in attachable mode to be attached together.</span>")
return return
if(istype(W, /obj/item/screwdriver)) ..()
/obj/item/assembly/screwdriver_act(mob/living/user, obj/item/I)
if(toggle_secure()) if(toggle_secure())
to_chat(user, "<span class='notice'>\The [src] is ready!</span>") to_chat(user, "<span class='notice'>\The [src] is ready!</span>")
else else
to_chat(user, "<span class='notice'>\The [src] can now be attached!</span>") to_chat(user, "<span class='notice'>\The [src] can now be attached!</span>")
return add_fingerprint(user)
..() return TRUE
/obj/item/assembly/examine(mob/user) /obj/item/assembly/examine(mob/user)
..() ..()
if(secured) to_chat(user, "<span class='notice'>\The [src] [secured? "is secured and ready to be used!" : "can be attached to other things."]</span>")
to_chat(user, "\The [src] is secured and ready to be used.")
else
to_chat(user, "\The [src] can be attached to other things.")
/obj/item/assembly/attack_self(mob/user) /obj/item/assembly/attack_self(mob/user)

View File

@@ -13,11 +13,14 @@
var/obj/item/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device var/obj/item/assembly_holder/bombassembly = null //The first part of the bomb is an assembly holder, holding an igniter+some device
var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank var/obj/item/tank/bombtank = null //the second part of the bomb is a plasma tank
/obj/item/onetankbomb/IsSpecialAssembly()
return TRUE
/obj/item/onetankbomb/examine(mob/user) /obj/item/onetankbomb/examine(mob/user)
bombtank.examine(user) bombtank.examine(user)
/obj/item/onetankbomb/update_icon() /obj/item/onetankbomb/update_icon()
cut_overlays()
if(bombtank) if(bombtank)
icon = bombtank.icon icon = bombtank.icon
icon_state = bombtank.icon_state icon_state = bombtank.icon_state
@@ -30,29 +33,37 @@
if(istype(W, /obj/item/analyzer)) if(istype(W, /obj/item/analyzer))
bombtank.attackby(W, user) bombtank.attackby(W, user)
return return
if(istype(W, /obj/item/wrench) && !status) //This is basically bomb assembly code inverted. apparently it works. add_fingerprint(user)
..()
to_chat(user, "<span class='notice'>You disassemble [src].</span>")
/obj/item/onetankbomb/wrench_act(mob/living/user, obj/item/I)
to_chat(user, "<span class='notice'>You disassemble [src]!</span>")
if(bombassembly)
bombassembly.forceMove(drop_location()) bombassembly.forceMove(drop_location())
bombassembly.master = null bombassembly.master = null
bombassembly = null bombassembly = null
if(bombtank)
bombtank.forceMove(drop_location()) bombtank.forceMove(drop_location())
bombtank.master = null bombtank.master = null
bombtank = null bombtank = null
qdel(src) qdel(src)
return TRUE
/obj/item/onetankbomb/welder_act(mob/living/user, obj/item/I)
. = FALSE
if(status)
to_chat(user, "<span class='notice'>[bombtank] already has a pressure hole!</span>")
return return
var/obj/item/weldingtool/WT = W if(!I.tool_start_check(user, amount=0))
if((istype(WT) && WT.welding)) return
if(!status) if(I.use_tool(src, user, 0, volume=40))
status = TRUE status = TRUE
GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]" GLOB.bombers += "[key_name(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]"
message_admins("[key_name_admin(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]") message_admins("[key_name_admin(user)] welded a single tank bomb. Temp: [bombtank.air_contents.temperature-T0C]")
to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>") to_chat(user, "<span class='notice'>A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.</span>")
add_fingerprint(user) add_fingerprint(user)
..() return TRUE
/obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly /obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly
bombassembly.attack_self(user, TRUE) bombassembly.attack_self(user, TRUE)
@@ -60,16 +71,20 @@
return return
/obj/item/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here. /obj/item/onetankbomb/receive_signal() //This is mainly called by the sensor through sense() to the holder, and from the holder to here.
visible_message("[icon2html(src, viewers(src))] *beep* *beep*", "*beep* *beep*") audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*")
playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
sleep(10) sleep(10)
if(!src) if(QDELETED(src))
return return
if(status) if(status)
bombtank.ignite() //if its not a dud, boom (or not boom if you made shitty mix) the ignite proc is below, in this file bombtank.ignite() //if its not a dud, boom (or not boom if you made shitty mix) the ignite proc is below, in this file
else else
bombtank.release() bombtank.release()
//Assembly / attached device memes
/obj/item/onetankbomb/Crossed(atom/movable/AM as mob|obj) //for mousetraps /obj/item/onetankbomb/Crossed(atom/movable/AM as mob|obj) //for mousetraps
. = ..()
if(bombassembly) if(bombassembly)
bombassembly.Crossed(AM) bombassembly.Crossed(AM)
@@ -77,6 +92,26 @@
if(bombassembly) if(bombassembly)
bombassembly.on_found(finder) bombassembly.on_found(finder)
/obj/item/onetankbomb/attack_hand() //also for mousetraps
. = ..()
if(.)
return
if(bombassembly)
bombassembly.attack_hand()
/obj/item/onetankbomb/Move()
. = ..()
if(bombassembly)
bombassembly.setDir(dir)
bombassembly.Move()
/obj/item/onetankbomb/dropped()
. = ..()
if(bombassembly)
bombassembly.dropped()
// ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ---------- // ---------- Procs below are for tanks that are used exclusively in 1-tank bombs ----------

View File

@@ -2,10 +2,10 @@
name = "blast door controller" name = "blast door controller"
desc = "A small electronic device able to control a blast door remotely." desc = "A small electronic device able to control a blast door remotely."
icon_state = "control" icon_state = "control"
attachable = 1 attachable = TRUE
var/id = null var/id = null
var/can_change_id = 0 var/can_change_id = 0
var/cooldown = 0//Door cooldowns var/cooldown = FALSE //Door cooldowns
/obj/item/assembly/control/examine(mob/user) /obj/item/assembly/control/examine(mob/user)
..() ..()
@@ -13,15 +13,14 @@
to_chat(user, "<span class='notice'>Its channel ID is '[id]'.</span>") to_chat(user, "<span class='notice'>Its channel ID is '[id]'.</span>")
/obj/item/assembly/control/activate() /obj/item/assembly/control/activate()
cooldown = 1 cooldown = TRUE
var/openclose var/openclose
for(var/obj/machinery/door/poddoor/M in GLOB.machines) for(var/obj/machinery/door/poddoor/M in GLOB.machines)
if(M.id == src.id) if(M.id == src.id)
if(openclose == null) if(openclose == null)
openclose = M.density openclose = M.density
INVOKE_ASYNC(M, openclose ? /obj/machinery/door/poddoor.proc/open : /obj/machinery/door/poddoor.proc/close) INVOKE_ASYNC(M, openclose ? /obj/machinery/door/poddoor.proc/open : /obj/machinery/door/poddoor.proc/close)
sleep(10) addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10)
cooldown = 0
/obj/item/assembly/control/airlock /obj/item/assembly/control/airlock
@@ -38,7 +37,7 @@
*/ */
/obj/item/assembly/control/airlock/activate() /obj/item/assembly/control/airlock/activate()
cooldown = 1 cooldown = TRUE
var/doors_need_closing = FALSE var/doors_need_closing = FALSE
var/list/obj/machinery/door/airlock/open_or_close = list() var/list/obj/machinery/door/airlock/open_or_close = list()
for(var/obj/machinery/door/airlock/D in GLOB.airlocks) for(var/obj/machinery/door/airlock/D in GLOB.airlocks)
@@ -66,8 +65,7 @@
for(var/D in open_or_close) for(var/D in open_or_close)
INVOKE_ASYNC(D, doors_need_closing ? /obj/machinery/door/airlock.proc/close : /obj/machinery/door/airlock.proc/open) INVOKE_ASYNC(D, doors_need_closing ? /obj/machinery/door/airlock.proc/close : /obj/machinery/door/airlock.proc/open)
sleep(10) addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10)
cooldown = 0
/obj/item/assembly/control/massdriver /obj/item/assembly/control/massdriver
@@ -75,7 +73,7 @@
desc = "A small electronic device able to control a mass driver." desc = "A small electronic device able to control a mass driver."
/obj/item/assembly/control/massdriver/activate() /obj/item/assembly/control/massdriver/activate()
cooldown = 1 cooldown = TRUE
for(var/obj/machinery/door/poddoor/M in GLOB.machines) for(var/obj/machinery/door/poddoor/M in GLOB.machines)
if (M.id == src.id) if (M.id == src.id)
INVOKE_ASYNC(M, /obj/machinery/door/poddoor.proc/open) INVOKE_ASYNC(M, /obj/machinery/door/poddoor.proc/open)
@@ -92,8 +90,7 @@
if (M.id == src.id) if (M.id == src.id)
INVOKE_ASYNC(M, /obj/machinery/door/poddoor.proc/close) INVOKE_ASYNC(M, /obj/machinery/door/poddoor.proc/close)
sleep(10) addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10)
cooldown = 0
/obj/item/assembly/control/igniter /obj/item/assembly/control/igniter
@@ -101,7 +98,7 @@
desc = "A remote controller for a mounted igniter." desc = "A remote controller for a mounted igniter."
/obj/item/assembly/control/igniter/activate() /obj/item/assembly/control/igniter/activate()
cooldown = 1 cooldown = TRUE
for(var/obj/machinery/sparker/M in GLOB.machines) for(var/obj/machinery/sparker/M in GLOB.machines)
if (M.id == src.id) if (M.id == src.id)
INVOKE_ASYNC(M, /obj/machinery/sparker.proc/ignite) INVOKE_ASYNC(M, /obj/machinery/sparker.proc/ignite)
@@ -112,22 +109,19 @@
M.on = !M.on M.on = !M.on
M.icon_state = "igniter[M.on]" M.icon_state = "igniter[M.on]"
sleep(30) addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 30)
cooldown = 0
/obj/item/assembly/control/flasher /obj/item/assembly/control/flasher
name = "flasher controller" name = "flasher controller"
desc = "A remote controller for a mounted flasher." desc = "A remote controller for a mounted flasher."
/obj/item/assembly/control/flasher/activate() /obj/item/assembly/control/flasher/activate()
cooldown = 1 cooldown = TRUE
for(var/obj/machinery/flasher/M in GLOB.machines) for(var/obj/machinery/flasher/M in GLOB.machines)
if(M.id == src.id) if(M.id == src.id)
INVOKE_ASYNC(M, /obj/machinery/flasher.proc/flash) INVOKE_ASYNC(M, /obj/machinery/flasher.proc/flash)
sleep(50) addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 50)
cooldown = 0
/obj/item/assembly/control/crematorium /obj/item/assembly/control/crematorium
@@ -135,10 +129,9 @@
desc = "An evil-looking remote controller for a crematorium." desc = "An evil-looking remote controller for a crematorium."
/obj/item/assembly/control/crematorium/activate() /obj/item/assembly/control/crematorium/activate()
cooldown = 1 cooldown = TRUE
for (var/obj/structure/bodycontainer/crematorium/C in GLOB.crematoriums) for (var/obj/structure/bodycontainer/crematorium/C in GLOB.crematoriums)
if (C.id == id) if (C.id == id)
C.cremate(usr) C.cremate(usr)
sleep(50) addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 50)
cooldown = 0

View File

@@ -93,7 +93,7 @@
if(crit_fail || (world.time < last_trigger + cooldown)) if(crit_fail || (world.time < last_trigger + cooldown))
return FALSE return FALSE
last_trigger = world.time last_trigger = world.time
playsound(src, 'sound/weapons/flash.ogg', 100, 1) playsound(src, 'sound/weapons/flash.ogg', 100, TRUE)
times_used++ times_used++
flash_recharge() flash_recharge()
update_icon(TRUE) update_icon(TRUE)
@@ -195,6 +195,8 @@
/obj/item/assembly/flash/cyborg/attackby(obj/item/W, mob/user, params) /obj/item/assembly/flash/cyborg/attackby(obj/item/W, mob/user, params)
return return
/obj/item/assembly/flash/cyborg/screwdriver_act(mob/living/user, obj/item/I)
return
/obj/item/assembly/flash/memorizer /obj/item/assembly/flash/memorizer
name = "memorizer" name = "memorizer"
@@ -226,7 +228,7 @@
return FALSE return FALSE
overheat = TRUE overheat = TRUE
addtimer(CALLBACK(src, .proc/cooldown), flashcd) addtimer(CALLBACK(src, .proc/cooldown), flashcd)
playsound(src, 'sound/weapons/flash.ogg', 100, 1) playsound(src, 'sound/weapons/flash.ogg', 100, TRUE)
update_icon(1) update_icon(1)
return TRUE return TRUE
@@ -272,7 +274,7 @@
return return
crit_fail = FALSE crit_fail = FALSE
times_used = 0 times_used = 0
playsound(src, 'sound/items/deconstruct.ogg', 50, 1) playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE)
update_icon() update_icon()
flash.crit_fail = TRUE flash.crit_fail = TRUE
flash.update_icon() flash.update_icon()

View File

@@ -3,10 +3,10 @@
desc = "Used for scanning and monitoring health." desc = "Used for scanning and monitoring health."
icon_state = "health" icon_state = "health"
materials = list(MAT_METAL=800, MAT_GLASS=200) materials = list(MAT_METAL=800, MAT_GLASS=200)
attachable = 1 attachable = TRUE
secured = 0 secured = FALSE
var/scanning = 0 var/scanning = FALSE
var/health_scan var/health_scan
var/alarm_health = 0 var/alarm_health = 0
@@ -16,31 +16,28 @@
/obj/item/assembly/health/activate() /obj/item/assembly/health/activate()
if(!..()) if(!..())
return 0//Cooldown check return FALSE//Cooldown check
toggle_scan() toggle_scan()
return 0 return TRUE
/obj/item/assembly/health/toggle_secure() /obj/item/assembly/health/toggle_secure()
secured = !secured secured = !secured
if(secured && scanning) if(secured && scanning)
START_PROCESSING(SSobj, src) START_PROCESSING(SSobj, src)
else else
scanning = 0 scanning = FALSE
STOP_PROCESSING(SSobj, src) STOP_PROCESSING(SSobj, src)
update_icon() update_icon()
return secured return secured
/obj/item/assembly/health/attackby(obj/item/W as obj, mob/user as mob) /obj/item/assembly/health/multitool_act(mob/living/user, obj/item/I)
if(istype(W, /obj/item/multitool))
if(alarm_health == 0) if(alarm_health == 0)
alarm_health = -90 alarm_health = -90
user.show_message("You toggle [src] to \"detect death\" mode.") to_chat(user, "<span class='notice'>You toggle [src] to \"detect death\" mode.</span>")
else else
alarm_health = 0 alarm_health = 0
user.show_message("You toggle [src] to \"detect critical state\" mode.") to_chat(user, "<span class='notice'>You toggle [src] to \"detect critical state\" mode.</span>")
return return TRUE
else
return ..()
/obj/item/assembly/health/process() /obj/item/assembly/health/process()
if(!scanning || !secured) if(!scanning || !secured)
@@ -58,7 +55,8 @@
health_scan = M.health health_scan = M.health
if(health_scan <= alarm_health) if(health_scan <= alarm_health)
pulse() pulse()
audible_message("[icon2html(src, hearers(src))] *beep* *beep*", "*beep* *beep*") audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*")
playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
toggle_scan() toggle_scan()
return return
return return
@@ -77,8 +75,9 @@
. = ..() . = ..()
if(!secured) if(!secured)
user.show_message("<span class='warning'>The [name] is unsecured!</span>") user.show_message("<span class='warning'>The [name] is unsecured!</span>")
return 0 return FALSE
var/dat = "<TT><B>Health Sensor</B> <A href='?src=[REF(src)];scanning=1'>[scanning?"On":"Off"]</A>" var/dat = "<TT><B>Health Sensor</B></TT>"
dat += "<BR><A href='?src=[REF(src)];scanning=1'>[scanning?"On":"Off"]</A>"
if(scanning && health_scan) if(scanning && health_scan)
dat += "<BR>Health: [health_scan]" dat += "<BR>Health: [health_scan]"
user << browse(dat, "window=hscan") user << browse(dat, "window=hscan")

View File

@@ -1,3 +1,4 @@
<<<<<<< HEAD
// See _DEFINES/is_helpers.dm for type helpers // See _DEFINES/is_helpers.dm for type helpers
/* /*
@@ -14,3 +15,21 @@ Desc: If true is an object that can hold an assemblyholder object
*/ */
/obj/proc/IsAssemblyHolder() /obj/proc/IsAssemblyHolder()
return 0 return 0
=======
// See _DEFINES/is_helpers.dm for type helpers
/*
Name: IsSpecialAssembly
Desc: If true is an object that can be attached to an assembly holder but is a special thing like a plasma can or door
*/
/obj/proc/IsSpecialAssembly()
return FALSE
/*
Name: IsAssemblyHolder
Desc: If true is an object that can hold an assemblyholder object
*/
/obj/proc/IsAssemblyHolder()
return FALSE
>>>>>>> b4d11c6... Shows assemblies some love. ♥ (#37632)

View File

@@ -15,7 +15,7 @@
var/obj/item/assembly/a_right = null var/obj/item/assembly/a_right = null
/obj/item/assembly_holder/IsAssemblyHolder() /obj/item/assembly_holder/IsAssemblyHolder()
return 1 return TRUE
/obj/item/assembly_holder/proc/assemble(obj/item/assembly/A, obj/item/assembly/A2, mob/user) /obj/item/assembly_holder/proc/assemble(obj/item/assembly/A, obj/item/assembly/A2, mob/user)
@@ -37,6 +37,7 @@
a_left = A a_left = A
else else
a_right = A a_right = A
A.holder_movement()
/obj/item/assembly_holder/update_icon() /obj/item/assembly_holder/update_icon()
cut_overlays() cut_overlays()
@@ -46,6 +47,11 @@
add_overlay("[O]_l") add_overlay("[O]_l")
if(a_right) if(a_right)
if(a_right.is_position_sensitive)
add_overlay("[a_right.icon_state]_right")
for(var/O in a_right.attached_overlays)
add_overlay("[O]_r")
else
var/mutable_appearance/right = mutable_appearance(icon, "[a_right.icon_state]_left") var/mutable_appearance/right = mutable_appearance(icon, "[a_right.icon_state]_left")
right.transform = matrix(-1, 0, 0, 0, 1, 0) right.transform = matrix(-1, 0, 0, 0, 1, 0)
for(var/O in a_right.attached_overlays) for(var/O in a_right.attached_overlays)
@@ -69,32 +75,37 @@
/obj/item/assembly_holder/Move() /obj/item/assembly_holder/Move()
. = ..() . = ..()
if(a_left && a_right) if(a_left)
a_left.holder_movement() a_left.holder_movement()
if(a_right)
a_right.holder_movement() a_right.holder_movement()
/obj/item/assembly_holder/dropped(mob/user)
. = ..()
if(a_left)
a_left.dropped()
if(a_right)
a_right.dropped()
/obj/item/assembly_holder/attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess /obj/item/assembly_holder/attack_hand()//Perhapse this should be a holder_pickup proc instead, can add if needbe I guess
. = ..() . = ..()
if(.) if(.)
return return
if(a_left && a_right)
a_left.holder_movement()
a_right.holder_movement()
/obj/item/assembly_holder/attackby(obj/item/W, mob/user, params)
if(istype(W, /obj/item/screwdriver))
var/turf/T = get_turf(src)
if(!T)
return 0
if(a_left) if(a_left)
a_left.holder = null a_left.attack_hand()
a_left.forceMove(T)
if(a_right) if(a_right)
a_right.holder = null a_right.attack_hand()
a_right.forceMove(T)
/obj/item/assembly_holder/screwdriver_act(mob/user, obj/item/tool)
to_chat(user, "<span class='notice'>You disassemble [src]!</span>")
if(a_left)
a_left.on_detach()
a_left = null
if(a_right)
a_right.on_detach()
a_right = null
qdel(src) qdel(src)
else return TRUE
..()
/obj/item/assembly_holder/attack_self(mob/user) /obj/item/assembly_holder/attack_self(mob/user)
src.add_fingerprint(user) src.add_fingerprint(user)
@@ -115,12 +126,12 @@
/obj/item/assembly_holder/proc/process_activation(obj/D, normal = 1, special = 1) /obj/item/assembly_holder/proc/process_activation(obj/D, normal = 1, special = 1)
if(!D) if(!D)
return 0 return FALSE
if((normal) && (a_right) && (a_left)) if((normal) && (a_right) && (a_left))
if(a_right != D) if(a_right != D)
a_right.pulsed(0) a_right.pulsed(FALSE)
if(a_left != D) if(a_left != D)
a_left.pulsed(0) a_left.pulsed(FALSE)
if(master) if(master)
master.receive_signal() master.receive_signal()
return 1 return TRUE

View File

@@ -23,12 +23,12 @@
/obj/item/assembly/igniter/activate() /obj/item/assembly/igniter/activate()
if(!..()) if(!..())
return 0//Cooldown check return FALSE//Cooldown check
var/turf/location = get_turf(loc) var/turf/location = get_turf(loc)
if(location) if(location)
location.hotspot_expose(1000,1000) location.hotspot_expose(1000,1000)
sparks.start() sparks.start()
return 1 return TRUE
/obj/item/assembly/igniter/attack_self(mob/user) /obj/item/assembly/igniter/attack_self(mob/user)
activate() activate()

View File

@@ -3,6 +3,7 @@
desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted." desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted."
icon_state = "infrared" icon_state = "infrared"
materials = list(MAT_METAL=1000, MAT_GLASS=500) materials = list(MAT_METAL=1000, MAT_GLASS=500)
is_position_sensitive = TRUE
var/on = FALSE var/on = FALSE
var/visible = FALSE var/visible = FALSE
@@ -10,6 +11,7 @@
var/list/obj/effect/beam/i_beam/beams var/list/obj/effect/beam/i_beam/beams
var/olddir = 0 var/olddir = 0
var/datum/component/redirect/listener var/datum/component/redirect/listener
var/hearing_range = 3
/obj/item/assembly/infra/Initialize() /obj/item/assembly/infra/Initialize()
. = ..() . = ..()
@@ -30,23 +32,27 @@
refreshBeam() refreshBeam()
/obj/item/assembly/infra/Destroy() /obj/item/assembly/infra/Destroy()
STOP_PROCESSING(SSobj, src)
QDEL_LIST(beams) QDEL_LIST(beams)
return ..() . = ..()
/obj/item/assembly/infra/describe() /obj/item/assembly/infra/examine(mob/user)
return "The infrared trigger is [on?"on":"off"]." ..()
to_chat(user, "<span class='notice'>The infrared trigger is [on?"on":"off"].</span>")
/obj/item/assembly/infra/activate() /obj/item/assembly/infra/activate()
if(!..()) if(!..())
return 0//Cooldown check return FALSE//Cooldown check
on = !on on = !on
refreshBeam()
update_icon() update_icon()
return 1 return TRUE
/obj/item/assembly/infra/toggle_secure() /obj/item/assembly/infra/toggle_secure()
secured = !secured secured = !secured
if(secured) if(secured)
START_PROCESSING(SSobj, src) START_PROCESSING(SSobj, src)
refreshBeam()
else else
QDEL_LIST(beams) QDEL_LIST(beams)
STOP_PROCESSING(SSobj, src) STOP_PROCESSING(SSobj, src)
@@ -59,12 +65,19 @@
if(on) if(on)
add_overlay("infrared_on") add_overlay("infrared_on")
attached_overlays += "infrared_on" attached_overlays += "infrared_on"
if(visible && secured)
add_overlay("infrared_visible")
attached_overlays += "infrared_visible"
if(holder) if(holder)
holder.update_icon() holder.update_icon()
return return
/obj/item/assembly/infra/dropped() /obj/item/assembly/infra/dropped()
. = ..()
if(holder)
holder_movement() //sync the dir of the device as well if it's contained in a TTV or an assembly holder
else
refreshBeam() refreshBeam()
/obj/item/assembly/infra/process() /obj/item/assembly/infra/process()
@@ -74,7 +87,15 @@
/obj/item/assembly/infra/proc/refreshBeam() /obj/item/assembly/infra/proc/refreshBeam()
QDEL_LIST(beams) QDEL_LIST(beams)
if(throwing || !on || !secured || !(isturf(loc) || holder && isturf(holder.loc))) if(throwing || !on || !secured)
return
if(holder)
if(holder.master) //incase the sensor is part of an assembly that's contained in another item, such as a single tank bomb
if(!holder.master.IsSpecialAssembly() || !isturf(holder.master.loc))
return
else if(!isturf(holder.loc)) //else just check where the holder is
return
else if(!isturf(loc)) //or just where the fuck we are in general
return return
var/turf/T = get_turf(src) var/turf/T = get_turf(src)
var/_dir = dir var/_dir = dir
@@ -82,6 +103,11 @@
if(_T) if(_T)
for(var/i in 1 to maxlength) for(var/i in 1 to maxlength)
var/obj/effect/beam/i_beam/I = new(T) var/obj/effect/beam/i_beam/I = new(T)
if(istype(holder, /obj/item/assembly_holder))
var/obj/item/assembly_holder/assembly_holder = holder
I.icon_state = "[initial(I.icon_state)]_[(assembly_holder.a_left == src) ? "l":"r"]" //Sync the offset of the beam with the position of the sensor.
else if(istype(holder, /obj/item/transfer_valve))
I.icon_state = "[initial(I.icon_state)]_ttv"
I.density = TRUE I.density = TRUE
if(!I.Move(_T)) if(!I.Move(_T))
qdel(I) qdel(I)
@@ -96,6 +122,12 @@
_T = get_step(_T, _dir) _T = get_step(_T, _dir)
CHECK_TICK CHECK_TICK
/obj/item/assembly/infra/on_detach()
. = ..()
if(!.)
return
refreshBeam()
/obj/item/assembly/infra/attack_hand() /obj/item/assembly/infra/attack_hand()
. = ..() . = ..()
refreshBeam() refreshBeam()
@@ -116,19 +148,17 @@
setDir(olddir) setDir(olddir)
olddir = null olddir = null
/obj/item/assembly/infra/holder_movement()
if(!holder)
return 0
refreshBeam()
return 1
/obj/item/assembly/infra/proc/trigger_beam(atom/movable/AM, turf/location) /obj/item/assembly/infra/proc/trigger_beam(atom/movable/AM, turf/location)
refreshBeam() refreshBeam()
switchListener(location) switchListener(location)
if(!secured || !on || next_activate > world.time) if(!secured || !on || next_activate > world.time)
return FALSE return FALSE
pulse(0) pulse(FALSE)
audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 3) audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*", null, hearing_range)
for(var/CHM in get_hearers_in_view(hearing_range, src))
if(ismob(CHM))
var/mob/LM = CHM
LM.playsound_local(get_turf(src), 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
next_activate = world.time + 30 next_activate = world.time + 30
/obj/item/assembly/infra/proc/switchListener(turf/newloc) /obj/item/assembly/infra/proc/switchListener(turf/newloc)
@@ -144,7 +174,9 @@
. = ..() . = ..()
if(is_secured(user)) if(is_secured(user))
user.set_machine(src) user.set_machine(src)
var/dat = "<TT><B>Infrared Laser</B>\n<B>Status</B>: [on ? "<A href='?src=[REF(src)];state=0'>On</A>" : "<A href='?src=[REF(src)];state=1'>Off</A>"]<BR>\n<B>Visibility</B>: [visible ? "<A href='?src=[REF(src)];visible=0'>Visible</A>" : "<A href='?src=[REF(src)];visible=1'>Invisible</A>"]<BR>\n</TT>" var/dat = "<TT><B>Infrared Laser</B></TT>"
dat += "<BR><B>Status</B>: [on ? "<A href='?src=[REF(src)];state=0'>On</A>" : "<A href='?src=[REF(src)];state=1'>Off</A>"]"
dat += "<BR><B>Visibility</B>: [visible ? "<A href='?src=[REF(src)];visible=0'>Visible</A>" : "<A href='?src=[REF(src)];visible=1'>Invisible</A>"]"
dat += "<BR><BR><A href='?src=[REF(src)];refresh=1'>Refresh</A>" dat += "<BR><BR><A href='?src=[REF(src)];refresh=1'>Refresh</A>"
dat += "<BR><BR><A href='?src=[REF(src)];close=1'>Close</A>" dat += "<BR><BR><A href='?src=[REF(src)];close=1'>Close</A>"
user << browse(dat, "window=infra") user << browse(dat, "window=infra")
@@ -163,6 +195,7 @@
refreshBeam() refreshBeam()
if(href_list["visible"]) if(href_list["visible"])
visible = !(visible) visible = !(visible)
update_icon()
refreshBeam() refreshBeam()
if(href_list["close"]) if(href_list["close"])
usr << browse(null, "window=infra") usr << browse(null, "window=infra")

View File

@@ -2,17 +2,15 @@
name = "mousetrap" name = "mousetrap"
desc = "A handy little spring-loaded trap for catching pesty rodents." desc = "A handy little spring-loaded trap for catching pesty rodents."
icon_state = "mousetrap" icon_state = "mousetrap"
item_state = "mousetrap"
materials = list(MAT_METAL=100) materials = list(MAT_METAL=100)
attachable = 1 attachable = TRUE
var/armed = 0 var/armed = FALSE
/obj/item/assembly/mousetrap/examine(mob/user) /obj/item/assembly/mousetrap/examine(mob/user)
..() ..()
if(armed) to_chat(user, "<span class='notice'>The pressure plate is [armed?"primed":"safe"].</span>")
to_chat(user, "The mousetrap is armed!")
else
to_chat(user, "The mousetrap is not armed.")
/obj/item/assembly/mousetrap/activate() /obj/item/assembly/mousetrap/activate()
if(..()) if(..())
@@ -22,13 +20,9 @@
var/mob/living/carbon/human/user = usr var/mob/living/carbon/human/user = usr
if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50)) if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50))
to_chat(user, "<span class='warning'>Your hand slips, setting off the trigger!</span>") to_chat(user, "<span class='warning'>Your hand slips, setting off the trigger!</span>")
pulse(0) pulse(FALSE)
update_icon() update_icon()
if(usr) playsound(src, 'sound/weapons/handcuffs.ogg', 30, TRUE, -3)
playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3)
/obj/item/assembly/mousetrap/describe()
return "The pressure switch is [armed?"primed":"safe"]."
/obj/item/assembly/mousetrap/update_icon() /obj/item/assembly/mousetrap/update_icon()
if(armed) if(armed)
@@ -45,10 +39,10 @@
if(ishuman(target)) if(ishuman(target))
var/mob/living/carbon/human/H = target var/mob/living/carbon/human/H = target
if(H.has_trait(TRAIT_PIERCEIMMUNE)) if(H.has_trait(TRAIT_PIERCEIMMUNE))
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
armed = FALSE armed = FALSE
update_icon() update_icon()
pulse(0) pulse(FALSE)
return FALSE return FALSE
switch(type) switch(type)
if("feet") if("feet")
@@ -66,10 +60,10 @@
var/mob/living/simple_animal/mouse/M = target var/mob/living/simple_animal/mouse/M = target
visible_message("<span class='boldannounce'>SPLAT!</span>") visible_message("<span class='boldannounce'>SPLAT!</span>")
M.splat() M.splat()
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) playsound(src, 'sound/effects/snap.ogg', 50, TRUE)
armed = FALSE armed = FALSE
update_icon() update_icon()
pulse(0) pulse(FALSE)
/obj/item/assembly/mousetrap/attack_self(mob/living/carbon/human/user) /obj/item/assembly/mousetrap/attack_self(mob/living/carbon/human/user)
@@ -87,7 +81,7 @@
to_chat(user, "<span class='notice'>You disarm [src].</span>") to_chat(user, "<span class='notice'>You disarm [src].</span>")
armed = !armed armed = !armed
update_icon() update_icon()
playsound(user.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3) playsound(src, 'sound/weapons/handcuffs.ogg', 30, TRUE, -3)
//ATTACK HAND IGNORING PARENT RETURN VALUE //ATTACK HAND IGNORING PARENT RETURN VALUE
@@ -145,4 +139,4 @@
/obj/item/assembly/mousetrap/armed /obj/item/assembly/mousetrap/armed
icon_state = "mousetraparmed" icon_state = "mousetraparmed"
armed = 1 armed = TRUE

View File

@@ -3,34 +3,36 @@
desc = "Used for scanning and alerting when someone enters a certain proximity." desc = "Used for scanning and alerting when someone enters a certain proximity."
icon_state = "prox" icon_state = "prox"
materials = list(MAT_METAL=800, MAT_GLASS=200) materials = list(MAT_METAL=800, MAT_GLASS=200)
attachable = 1 attachable = TRUE
var/scanning = 0 var/scanning = FALSE
var/timing = 0 var/timing = FALSE
var/time = 10 var/time = 10
var/sensitivity = 1 var/sensitivity = 1
var/hearing_range = 3
/obj/item/assembly/prox_sensor/proc/toggle_scan()
/obj/item/assembly/prox_sensor/proc/sense()
/obj/item/assembly/prox_sensor/Initialize() /obj/item/assembly/prox_sensor/Initialize()
. = ..() . = ..()
proximity_monitor = new(src, 0) proximity_monitor = new(src, 0)
START_PROCESSING(SSobj, src)
/obj/item/assembly/prox_sensor/describe() /obj/item/assembly/prox_sensor/Destroy()
if(timing) STOP_PROCESSING(SSobj, src)
return "<span class='notice'>The proximity sensor is arming.</span>" . = ..()
return "The proximity sensor is [scanning?"armed":"disarmed"]."
/obj/item/assembly/prox_sensor/examine(mob/user)
..()
to_chat(user, "<span class='notice'>The proximity sensor is [timing ? "arming" : (scanning ? "armed" : "disarmed")].</span>")
/obj/item/assembly/prox_sensor/activate() /obj/item/assembly/prox_sensor/activate()
if(!..()) if(!..())
return 0//Cooldown check return FALSE//Cooldown check
if(!scanning)
timing = !timing timing = !timing
else
scanning = FALSE
update_icon() update_icon()
return 1 return TRUE
/obj/item/assembly/prox_sensor/toggle_secure() /obj/item/assembly/prox_sensor/toggle_secure()
secured = !secured secured = !secured
@@ -38,8 +40,10 @@
if(scanning) if(scanning)
toggle_scan() toggle_scan()
proximity_monitor.host = src proximity_monitor.host = src
timing = 0 timing = FALSE
STOP_PROCESSING(SSobj, src)
else else
START_PROCESSING(SSobj, src)
proximity_monitor.host = loc proximity_monitor.host = loc
update_icon() update_icon()
return secured return secured
@@ -51,25 +55,31 @@
sense() sense()
/obj/item/assembly/prox_sensor/sense() /obj/item/assembly/prox_sensor/proc/sense()
if(!scanning || !secured || next_activate > world.time) if(!scanning || !secured || next_activate > world.time)
return 0 return FALSE
pulse(0) pulse(FALSE)
audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 3) audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*", null, hearing_range)
for(var/CHM in get_hearers_in_view(hearing_range, src))
if(ismob(CHM))
var/mob/LM = CHM
LM.playsound_local(get_turf(src), 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
next_activate = world.time + 30 next_activate = world.time + 30
return TRUE
/obj/item/assembly/prox_sensor/process() /obj/item/assembly/prox_sensor/process()
if(timing) if(!timing)
return
time-- time--
if(time <= 0) if(time <= 0)
timing = 0 timing = FALSE
toggle_scan(1) toggle_scan(TRUE)
time = initial(time) time = initial(time)
/obj/item/assembly/prox_sensor/toggle_scan(scan) /obj/item/assembly/prox_sensor/proc/toggle_scan(scan)
if(!secured) if(!secured)
return 0 return FALSE
scanning = scan scanning = scan
proximity_monitor.SetRange(scanning ? sensitivity : 0) proximity_monitor.SetRange(scanning ? sensitivity : 0)
update_icon() update_icon()
@@ -98,8 +108,11 @@
if(is_secured(user)) if(is_secured(user))
var/second = time % 60 var/second = time % 60
var/minute = (time - second) / 60 var/minute = (time - second) / 60
var/dat = "<TT><B>Proximity Sensor</B>\n[(timing ? "<A href='?src=[REF(src)];time=0'>Arming</A>" : "<A href='?src=[REF(src)];time=1'>Not Arming</A>")] [minute]:[second]\n<A href='?src=[REF(src)];tp=-30'>-</A> <A href='?src=[REF(src)];tp=-1'>-</A> <A href='?src=[REF(src)];tp=1'>+</A> <A href='?src=[REF(src)];tp=30'>+</A>\n</TT>" var/dat = "<TT><B>Proximity Sensor</B></TT>"
dat += "<BR><A href='?src=[REF(src)];scanning=[scanning?"0'>Armed":"1'>Unarmed"]</A> (Movement sensor active when armed!)" if(!scanning)
dat += "<BR>[(timing ? "<A href='?src=[REF(src)];time=0'>Arming</A>" : "<A href='?src=[REF(src)];time=1'>Not Arming</A>")] [minute]:[second]"
dat += "<BR><A href='?src=[REF(src)];tp=-30'>-</A> <A href='?src=[REF(src)];tp=-1'>-</A> <A href='?src=[REF(src)];tp=1'>+</A> <A href='?src=[REF(src)];tp=30'>+</A>"
dat += "<BR><A href='?src=[REF(src)];scanning=[scanning?"0'>Armed":"1'>Unarmed (Movement sensor active when armed!)"]</A>"
dat += "<BR>Detection range: <A href='?src=[REF(src)];sense=down'>-</A> [sensitivity] <A href='?src=[REF(src)];sense=up'>+</A>" dat += "<BR>Detection range: <A href='?src=[REF(src)];sense=down'>-</A> [sensitivity] <A href='?src=[REF(src)];sense=up'>+</A>"
dat += "<BR><BR><A href='?src=[REF(src)];refresh=1'>Refresh</A>" dat += "<BR><BR><A href='?src=[REF(src)];refresh=1'>Refresh</A>"
dat += "<BR><BR><A href='?src=[REF(src)];close=1'>Close</A>" dat += "<BR><BR><A href='?src=[REF(src)];close=1'>Close</A>"

View File

@@ -13,18 +13,18 @@
qdel(part2) qdel(part2)
return ..() return ..()
/obj/item/assembly/shock_kit/attackby(obj/item/W, mob/user, params) /obj/item/assembly/shock_kit/wrench_act(mob/living/user, obj/item/I)
if(istype(W, /obj/item/wrench)) to_chat(user, "<span class='notice'>You disassemble [src].</span>")
if(part1)
part1.forceMove(drop_location()) part1.forceMove(drop_location())
part2.forceMove(drop_location())
part1.master = null part1.master = null
part2.master = null
part1 = null part1 = null
if(part2)
part2.forceMove(drop_location())
part2.master = null
part2 = null part2 = null
qdel(src) qdel(src)
return return TRUE
add_fingerprint(user)
return
/obj/item/assembly/shock_kit/attack_self(mob/user) /obj/item/assembly/shock_kit/attack_self(mob/user)
part1.attack_self(user) part1.attack_self(user)

View File

@@ -7,17 +7,18 @@
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
materials = list(MAT_METAL=400, MAT_GLASS=120) materials = list(MAT_METAL=400, MAT_GLASS=120)
wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE
attachable = 1 attachable = TRUE
var/code = DEFAULT_SIGNALER_CODE var/code = DEFAULT_SIGNALER_CODE
var/frequency = FREQ_SIGNALER var/frequency = FREQ_SIGNALER
var/delay = 0 var/delay = 0
var/datum/radio_frequency/radio_connection var/datum/radio_frequency/radio_connection
var/suicider = null var/suicider = null
var/hearing_range = 1
/obj/item/assembly/signaler/suicide_act(mob/living/carbon/user) /obj/item/assembly/signaler/suicide_act(mob/living/carbon/user)
user.visible_message("<span class='suicide'>[user] eats \the [src]! If it is signaled, [user.p_they()] will die!</span>") user.visible_message("<span class='suicide'>[user] eats \the [src]! If it is signaled, [user.p_they()] will die!</span>")
playsound(src, 'sound/items/eatfood.ogg', 50, 1) playsound(src, 'sound/items/eatfood.ogg', 50, TRUE)
user.transferItemToLoc(src, user, TRUE) user.transferItemToLoc(src, user, TRUE)
suicider = user suicider = user
return MANUAL_SUICIDE return MANUAL_SUICIDE
@@ -27,15 +28,14 @@
user.adjustOxyLoss(200)//it sends an electrical pulse to their heart, killing them. or something. user.adjustOxyLoss(200)//it sends an electrical pulse to their heart, killing them. or something.
user.death(0) user.death(0)
/obj/item/assembly/signaler/New() /obj/item/assembly/signaler/Initialize()
..() . = ..()
spawn(40)
set_frequency(frequency) set_frequency(frequency)
/obj/item/assembly/signaler/Destroy() /obj/item/assembly/signaler/Destroy()
SSradio.remove_object(src,frequency) SSradio.remove_object(src,frequency)
return ..() . = ..()
/obj/item/assembly/signaler/activate() /obj/item/assembly/signaler/activate()
if(!..())//cooldown processing if(!..())//cooldown processing
@@ -80,7 +80,7 @@ Code:
/obj/item/assembly/signaler/Topic(href, href_list) /obj/item/assembly/signaler/Topic(href, href_list)
..() ..()
if(!usr.canmove || usr.stat || usr.restrained() || !in_range(loc, usr)) if(!usr.canUseTopic(src, BE_CLOSE))
usr << browse(null, "window=radio") usr << browse(null, "window=radio")
onclose(usr, "radio") onclose(usr, "radio")
return return
@@ -131,17 +131,22 @@ Code:
return return
/obj/item/assembly/signaler/receive_signal(datum/signal/signal) /obj/item/assembly/signaler/receive_signal(datum/signal/signal)
. = FALSE
if(!signal) if(!signal)
return 0 return
if(signal.data["code"] != code) if(signal.data["code"] != code)
return 0 return
if(!(src.wires & WIRE_RADIO_RECEIVE)) if(!(src.wires & WIRE_RADIO_RECEIVE))
return 0 return
if(suicider) if(suicider)
manual_suicide(suicider) manual_suicide(suicider)
pulse(1) pulse(TRUE)
audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 1) audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*", null, hearing_range)
return for(var/CHM in get_hearers_in_view(hearing_range, src))
if(ismob(CHM))
var/mob/LM = CHM
LM.playsound_local(get_turf(src), 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
return TRUE
/obj/item/assembly/signaler/proc/set_frequency(new_frequency) /obj/item/assembly/signaler/proc/set_frequency(new_frequency)
@@ -161,10 +166,11 @@ Code:
/obj/item/assembly/signaler/reciever/activate() /obj/item/assembly/signaler/reciever/activate()
toggle_safety() toggle_safety()
return 1 return TRUE
/obj/item/assembly/signaler/reciever/describe() /obj/item/assembly/signaler/reciever/examine(mob/user)
return "The radio receiver is [on?"on":"off"]." ..()
to_chat(user, "<span class='notice'>The radio receiver is [on?"on":"off"].</span>")
/obj/item/assembly/signaler/reciever/receive_signal(datum/signal/signal) /obj/item/assembly/signaler/reciever/receive_signal(datum/signal/signal)
if(!on) if(!on)
@@ -183,11 +189,12 @@ Code:
/obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal) /obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal)
if(!signal) if(!signal)
return 0 return FALSE
if(signal.data["code"] != code) if(signal.data["code"] != code)
return 0 return FALSE
for(var/obj/effect/anomaly/A in get_turf(src)) for(var/obj/effect/anomaly/A in get_turf(src))
A.anomalyNeutralize() A.anomalyNeutralize()
return TRUE
/obj/item/assembly/signaler/anomaly/attack_self() /obj/item/assembly/signaler/anomaly/attack_self()
return return
@@ -196,3 +203,5 @@ Code:
/obj/item/assembly/signaler/cyborg/attackby(obj/item/W, mob/user, params) /obj/item/assembly/signaler/cyborg/attackby(obj/item/W, mob/user, params)
return return
/obj/item/assembly/signaler/cyborg/screwdriver_act(mob/living/user, obj/item/I)
return

View File

@@ -3,12 +3,13 @@
desc = "Used to time things. Works well with contraptions which has to count down. Tick tock." desc = "Used to time things. Works well with contraptions which has to count down. Tick tock."
icon_state = "timer" icon_state = "timer"
materials = list(MAT_METAL=500, MAT_GLASS=50) materials = list(MAT_METAL=500, MAT_GLASS=50)
attachable = 1 attachable = TRUE
var/timing = 0 var/timing = FALSE
var/time = 5 var/time = 5
var/saved_time = 5 var/saved_time = 5
var/loop = 0 var/loop = FALSE
var/hearing_range = 3
/obj/item/assembly/timer/suicide_act(mob/living/user) /obj/item/assembly/timer/suicide_act(mob/living/user)
user.visible_message("<span class='suicide'>[user] looks at the timer and decides [user.p_their()] fate! It looks like [user.p_theyre()] going to commit suicide!</span>") user.visible_message("<span class='suicide'>[user] looks at the timer and decides [user.p_their()] fate! It looks like [user.p_theyre()] going to commit suicide!</span>")
@@ -21,22 +22,24 @@
user.adjustOxyLoss(200) user.adjustOxyLoss(200)
user.death(0) user.death(0)
/obj/item/assembly/timer/New() /obj/item/assembly/timer/Initialize()
..() . = ..()
START_PROCESSING(SSobj, src) START_PROCESSING(SSobj, src)
/obj/item/assembly/timer/describe() /obj/item/assembly/timer/Destroy()
if(timing) STOP_PROCESSING(SSobj, src)
return "The timer is counting down from [time]!" . = ..()
return "The timer is set for [time] seconds."
/obj/item/assembly/timer/examine(mob/user)
..()
to_chat(user, "<span class='notice'>The timer is [timing ? "counting down from [time]":"set for [time] seconds"].</span>")
/obj/item/assembly/timer/activate() /obj/item/assembly/timer/activate()
if(!..()) if(!..())
return 0//Cooldown check return FALSE//Cooldown check
timing = !timing timing = !timing
update_icon() update_icon()
return 1 return TRUE
/obj/item/assembly/timer/toggle_secure() /obj/item/assembly/timer/toggle_secure()
@@ -44,7 +47,7 @@
if(secured) if(secured)
START_PROCESSING(SSobj, src) START_PROCESSING(SSobj, src)
else else
timing = 0 timing = FALSE
STOP_PROCESSING(SSobj, src) STOP_PROCESSING(SSobj, src)
update_icon() update_icon()
return secured return secured
@@ -53,18 +56,23 @@
/obj/item/assembly/timer/proc/timer_end() /obj/item/assembly/timer/proc/timer_end()
if(!secured || next_activate > world.time) if(!secured || next_activate > world.time)
return FALSE return FALSE
pulse(0) pulse(FALSE)
audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 3) audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*", null, hearing_range)
for(var/CHM in get_hearers_in_view(hearing_range, src))
if(ismob(CHM))
var/mob/LM = CHM
LM.playsound_local(get_turf(src), 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
if(loop) if(loop)
timing = 1 timing = TRUE
update_icon() update_icon()
/obj/item/assembly/timer/process() /obj/item/assembly/timer/process()
if(timing) if(!timing)
return
time-- time--
if(time <= 0) if(time <= 0)
timing = 0 timing = FALSE
timer_end() timer_end()
time = saved_time time = saved_time
@@ -84,7 +92,9 @@
if(is_secured(user)) if(is_secured(user))
var/second = time % 60 var/second = time % 60
var/minute = (time - second) / 60 var/minute = (time - second) / 60
var/dat = "<TT><B>Timing Unit</B>\n[(timing ? "<A href='?src=[REF(src)];time=0'>Timing</A>" : "<A href='?src=[REF(src)];time=1'>Not Timing</A>")] [minute]:[second]\n<A href='?src=[REF(src)];tp=-30'>-</A> <A href='?src=[REF(src)];tp=-1'>-</A> <A href='?src=[REF(src)];tp=1'>+</A> <A href='?src=[REF(src)];tp=30'>+</A>\n</TT>" var/dat = "<TT><B>Timing Unit</B></TT>"
dat += "<BR>[(timing ? "<A href='?src=[REF(src)];time=0'>Timing</A>" : "<A href='?src=[REF(src)];time=1'>Not Timing</A>")] [minute]:[second]"
dat += "<BR><A href='?src=[REF(src)];tp=-30'>-</A> <A href='?src=[REF(src)];tp=-1'>-</A> <A href='?src=[REF(src)];tp=1'>+</A> <A href='?src=[REF(src)];tp=30'>+</A>"
dat += "<BR><BR><A href='?src=[REF(src)];repeat=[(loop ? "0'>Stop repeating" : "1'>Set to repeat")]</A>" dat += "<BR><BR><A href='?src=[REF(src)];repeat=[(loop ? "0'>Stop repeating" : "1'>Set to repeat")]</A>"
dat += "<BR><BR><A href='?src=[REF(src)];refresh=1'>Refresh</A>" dat += "<BR><BR><A href='?src=[REF(src)];refresh=1'>Refresh</A>"
dat += "<BR><BR><A href='?src=[REF(src)];close=1'>Close</A>" dat += "<BR><BR><A href='?src=[REF(src)];close=1'>Close</A>"
@@ -95,7 +105,7 @@
/obj/item/assembly/timer/Topic(href, href_list) /obj/item/assembly/timer/Topic(href, href_list)
..() ..()
if(usr.incapacitated() || !in_range(loc, usr)) if(!usr.canUseTopic(src, BE_CLOSE))
usr << browse(null, "window=timer") usr << browse(null, "window=timer")
onclose(usr, "timer") onclose(usr, "timer")
return return

View File

@@ -1,14 +1,19 @@
#define INCLUSIVE_MODE 1
#define EXCLUSIVE_MODE 2
#define RECOGNIZER_MODE 3
#define VOICE_SENSOR_MODE 4
/obj/item/assembly/voice /obj/item/assembly/voice
name = "voice analyzer" name = "voice analyzer"
desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated." desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated."
icon_state = "voice" icon_state = "voice"
materials = list(MAT_METAL=500, MAT_GLASS=50) materials = list(MAT_METAL=500, MAT_GLASS=50)
flags_1 = HEAR_1 flags_1 = HEAR_1
attachable = 1 attachable = TRUE
verb_say = "beeps" verb_say = "beeps"
verb_ask = "beeps" verb_ask = "beeps"
verb_exclaim = "beeps" verb_exclaim = "beeps"
var/listening = 0 var/listening = FALSE
var/recorded = "" //the activation message var/recorded = "" //the activation message
var/mode = 1 var/mode = 1
var/static/list/modes = list("inclusive", var/static/list/modes = list("inclusive",
@@ -32,60 +37,64 @@
/obj/item/assembly/voice/proc/record_speech(atom/movable/speaker, raw_message, datum/language/message_language) /obj/item/assembly/voice/proc/record_speech(atom/movable/speaker, raw_message, datum/language/message_language)
switch(mode) switch(mode)
if(1) if(INCLUSIVE_MODE)
recorded = raw_message recorded = raw_message
listening = 0 listening = FALSE
say("Activation message is '[recorded]'.", message_language) say("Activation message is '[recorded]'.", message_language)
if(2) if(EXCLUSIVE_MODE)
recorded = raw_message recorded = raw_message
listening = 0 listening = FALSE
say("Activation message is '[recorded]'.", message_language) say("Activation message is '[recorded]'.", message_language)
if(3) if(RECOGNIZER_MODE)
recorded = speaker.GetVoice() recorded = speaker.GetVoice()
listening = 0 listening = FALSE
say("Your voice pattern is saved.", message_language) say("Your voice pattern is saved.", message_language)
if(4) if(VOICE_SENSOR_MODE)
if(length(raw_message)) if(length(raw_message))
addtimer(CALLBACK(src, .proc/pulse, 0), 10) addtimer(CALLBACK(src, .proc/pulse, 0), 10)
/obj/item/assembly/voice/proc/check_activation(atom/movable/speaker, raw_message) /obj/item/assembly/voice/proc/check_activation(atom/movable/speaker, raw_message)
. = 0 . = FALSE
switch(mode) switch(mode)
if(1) if(INCLUSIVE_MODE)
if(findtext(raw_message, recorded)) if(findtext(raw_message, recorded))
. = 1 . = TRUE
if(2) if(EXCLUSIVE_MODE)
if(raw_message == recorded) if(raw_message == recorded)
. = 1 . = TRUE
if(3) if(RECOGNIZER_MODE)
if(speaker.GetVoice() == recorded) if(speaker.GetVoice() == recorded)
. = 1 . = TRUE
if(4) if(VOICE_SENSOR_MODE)
if(length(raw_message)) if(length(raw_message))
. = 1 . = TRUE
/obj/item/assembly/voice/attackby(obj/item/W, mob/user, params) /obj/item/assembly/voice/multitool_act(mob/living/user, obj/item/I)
if(istype(W, /obj/item/multitool))
mode %= modes.len mode %= modes.len
mode++ mode++
to_chat(user, "You set [src] into a [modes[mode]] mode.") to_chat(user, "<span class='notice'>You set [src] into [modes[mode]] mode.</span>")
listening = 0 listening = FALSE
recorded = "" recorded = ""
else return TRUE
return ..()
/obj/item/assembly/voice/activate() /obj/item/assembly/voice/activate()
if(secured) if(!secured || holder)
if(!holder) return FALSE
listening = !listening listening = !listening
say("[listening ? "Now" : "No longer"] recording input.") say("[listening ? "Now" : "No longer"] recording input.")
return TRUE
/obj/item/assembly/voice/attack_self(mob/user) /obj/item/assembly/voice/attack_self(mob/user)
if(!user) if(!user)
return 0 return FALSE
activate() activate()
return 1 return TRUE
/obj/item/assembly/voice/toggle_secure() /obj/item/assembly/voice/toggle_secure()
. = ..() . = ..()
listening = 0 listening = FALSE
#undef INCLUSIVE_MODE
#undef EXCLUSIVE_MODE
#undef RECOGNIZER_MODE
#undef VOICE_SENSOR_MODE

View File

@@ -637,6 +637,7 @@
var/frequency = FREQ_SIGNALER var/frequency = FREQ_SIGNALER
var/code = DEFAULT_SIGNALER_CODE var/code = DEFAULT_SIGNALER_CODE
var/datum/radio_frequency/radio_connection var/datum/radio_frequency/radio_connection
var/hearing_range = 1
/obj/item/integrated_circuit/input/signaler/Initialize() /obj/item/integrated_circuit/input/signaler/Initialize()
. = ..() . = ..()
@@ -690,7 +691,11 @@
return 0 return 0
activate_pin(3) activate_pin(3)
audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 1) audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*", null, hearing_range)
for(var/CHM in get_hearers_in_view(hearing_range, src))
if(ismob(CHM))
var/mob/LM = CHM
LM.playsound_local(get_turf(src), 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
/obj/item/integrated_circuit/input/ntnet_packet /obj/item/integrated_circuit/input/ntnet_packet
name = "NTNet networking circuit" name = "NTNet networking circuit"

View File

@@ -170,7 +170,8 @@
if(href_list["send"]) if(href_list["send"])
signaler.send_activation() signaler.send_activation()
audible_message("[icon2html(src, world)] *beep* *beep*") audible_message("[icon2html(src, hearers(src))] *beep* *beep* *beep*")
playsound(src, 'sound/machines/triple_beep.ogg', ASSEMBLY_BEEP_VOLUME, TRUE)
if(href_list["freq"]) if(href_list["freq"])
var/new_frequency = (signaler.frequency + text2num(href_list["freq"])) var/new_frequency = (signaler.frequency + text2num(href_list["freq"]))

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 114 KiB