diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 35994d09f5..12d263bf9d 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -58,6 +58,36 @@ attacher = user 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) user.set_machine(src) var/dat = {" Valve properties: @@ -91,8 +121,7 @@ toggle_valve() else if(attached_device) if(href_list["rem_device"]) - attached_device.forceMove(drop_location()) - attached_device.holder = null + attached_device.on_detach() attached_device = null update_icon() if(href_list["device"]) @@ -127,6 +156,10 @@ underlays += J if(attached_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() tank_two.air_contents.volume += tank_one.air_contents.volume diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index 85d45bd40b..3e291d0eee 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -3,6 +3,7 @@ #define WIRE_PULSE_SPECIAL (1<<2) #define WIRE_RADIO_RECEIVE (1<<3) #define WIRE_RADIO_PULSE (1<<4) +#define ASSEMBLY_BEEP_VOLUME 5 /obj/item/assembly name = "assembly" @@ -16,6 +17,8 @@ throw_speed = 3 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/list/attached_overlays = null var/obj/item/assembly_holder/holder = null @@ -30,14 +33,18 @@ /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 - return - -/obj/item/assembly/proc/describe() // Called by grenades to describe the state of the trigger (time left, etc) - return "The trigger assembly looks broken!" - + if(!holder) + return FALSE + setDir(holder.dir) + return TRUE /obj/item/assembly/proc/is_secured(mob/user) 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 -/obj/item/assembly/proc/pulsed(radio = 0) +/obj/item/assembly/proc/pulsed(radio = FALSE) if(wire_type & WIRE_RECEIVE) INVOKE_ASYNC(src, .proc/activate) 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 -/obj/item/assembly/proc/pulse(radio = 0) +/obj/item/assembly/proc/pulse(radio = FALSE) if(connected && wire_type) connected.pulse_assembly(src) return TRUE @@ -91,21 +98,19 @@ else to_chat(user, "Both devices must be in attachable mode to be attached together.") return - if(istype(W, /obj/item/screwdriver)) - if(toggle_secure()) - to_chat(user, "\The [src] is ready!") - else - to_chat(user, "\The [src] can now be attached!") - return ..() +/obj/item/assembly/screwdriver_act(mob/living/user, obj/item/I) + if(toggle_secure()) + to_chat(user, "\The [src] is ready!") + else + to_chat(user, "\The [src] can now be attached!") + add_fingerprint(user) + return TRUE /obj/item/assembly/examine(mob/user) ..() - if(secured) - to_chat(user, "\The [src] is secured and ready to be used.") - else - to_chat(user, "\The [src] can be attached to other things.") + to_chat(user, "\The [src] [secured? "is secured and ready to be used!" : "can be attached to other things."]") /obj/item/assembly/attack_self(mob/user) diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index daca7a5435..ca85255bf0 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -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/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) bombtank.examine(user) /obj/item/onetankbomb/update_icon() + cut_overlays() if(bombtank) icon = bombtank.icon icon_state = bombtank.icon_state @@ -30,29 +33,37 @@ if(istype(W, /obj/item/analyzer)) bombtank.attackby(W, user) return - if(istype(W, /obj/item/wrench) && !status) //This is basically bomb assembly code inverted. apparently it works. - - to_chat(user, "You disassemble [src].") + add_fingerprint(user) + ..() +/obj/item/onetankbomb/wrench_act(mob/living/user, obj/item/I) + to_chat(user, "You disassemble [src]!") + if(bombassembly) bombassembly.forceMove(drop_location()) bombassembly.master = null bombassembly = null - + if(bombtank) bombtank.forceMove(drop_location()) bombtank.master = null bombtank = null + qdel(src) + return TRUE - qdel(src) +/obj/item/onetankbomb/welder_act(mob/living/user, obj/item/I) + . = FALSE + if(status) + to_chat(user, "[bombtank] already has a pressure hole!") return - var/obj/item/weldingtool/WT = W - if((istype(WT) && WT.welding)) - if(!status) - status = TRUE - 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]") - to_chat(user, "A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.") - add_fingerprint(user) - ..() + if(!I.tool_start_check(user, amount=0)) + return + if(I.use_tool(src, user, 0, volume=40)) + status = TRUE + 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]") + to_chat(user, "A pressure hole has been bored to [bombtank] valve. \The [bombtank] can now be ignited.") + add_fingerprint(user) + return TRUE + /obj/item/onetankbomb/attack_self(mob/user) //pressing the bomb accesses its assembly bombassembly.attack_self(user, TRUE) @@ -60,16 +71,20 @@ return /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) - if(!src) + if(QDELETED(src)) return 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 else bombtank.release() +//Assembly / attached device memes + /obj/item/onetankbomb/Crossed(atom/movable/AM as mob|obj) //for mousetraps + . = ..() if(bombassembly) bombassembly.Crossed(AM) @@ -77,6 +92,26 @@ if(bombassembly) 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 ---------- diff --git a/code/modules/assembly/doorcontrol.dm b/code/modules/assembly/doorcontrol.dm index c3475b1839..f320872076 100644 --- a/code/modules/assembly/doorcontrol.dm +++ b/code/modules/assembly/doorcontrol.dm @@ -2,10 +2,10 @@ name = "blast door controller" desc = "A small electronic device able to control a blast door remotely." icon_state = "control" - attachable = 1 + attachable = TRUE var/id = null var/can_change_id = 0 - var/cooldown = 0//Door cooldowns + var/cooldown = FALSE //Door cooldowns /obj/item/assembly/control/examine(mob/user) ..() @@ -13,15 +13,14 @@ to_chat(user, "Its channel ID is '[id]'.") /obj/item/assembly/control/activate() - cooldown = 1 + cooldown = TRUE var/openclose for(var/obj/machinery/door/poddoor/M in GLOB.machines) if(M.id == src.id) if(openclose == null) openclose = M.density INVOKE_ASYNC(M, openclose ? /obj/machinery/door/poddoor.proc/open : /obj/machinery/door/poddoor.proc/close) - sleep(10) - cooldown = 0 + addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10) /obj/item/assembly/control/airlock @@ -38,7 +37,7 @@ */ /obj/item/assembly/control/airlock/activate() - cooldown = 1 + cooldown = TRUE var/doors_need_closing = FALSE var/list/obj/machinery/door/airlock/open_or_close = list() for(var/obj/machinery/door/airlock/D in GLOB.airlocks) @@ -66,8 +65,7 @@ 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) - sleep(10) - cooldown = 0 + addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10) /obj/item/assembly/control/massdriver @@ -75,7 +73,7 @@ desc = "A small electronic device able to control a mass driver." /obj/item/assembly/control/massdriver/activate() - cooldown = 1 + cooldown = TRUE for(var/obj/machinery/door/poddoor/M in GLOB.machines) if (M.id == src.id) INVOKE_ASYNC(M, /obj/machinery/door/poddoor.proc/open) @@ -92,8 +90,7 @@ if (M.id == src.id) INVOKE_ASYNC(M, /obj/machinery/door/poddoor.proc/close) - sleep(10) - cooldown = 0 + addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10) /obj/item/assembly/control/igniter @@ -101,7 +98,7 @@ desc = "A remote controller for a mounted igniter." /obj/item/assembly/control/igniter/activate() - cooldown = 1 + cooldown = TRUE for(var/obj/machinery/sparker/M in GLOB.machines) if (M.id == src.id) INVOKE_ASYNC(M, /obj/machinery/sparker.proc/ignite) @@ -112,22 +109,19 @@ M.on = !M.on M.icon_state = "igniter[M.on]" - sleep(30) - cooldown = 0 - + addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 30) /obj/item/assembly/control/flasher name = "flasher controller" desc = "A remote controller for a mounted flasher." /obj/item/assembly/control/flasher/activate() - cooldown = 1 + cooldown = TRUE for(var/obj/machinery/flasher/M in GLOB.machines) if(M.id == src.id) INVOKE_ASYNC(M, /obj/machinery/flasher.proc/flash) - sleep(50) - cooldown = 0 + addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 50) /obj/item/assembly/control/crematorium @@ -135,10 +129,9 @@ desc = "An evil-looking remote controller for a crematorium." /obj/item/assembly/control/crematorium/activate() - cooldown = 1 + cooldown = TRUE for (var/obj/structure/bodycontainer/crematorium/C in GLOB.crematoriums) if (C.id == id) C.cremate(usr) - sleep(50) - cooldown = 0 + addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 50) diff --git a/code/modules/assembly/flash.dm b/code/modules/assembly/flash.dm index cbfdb860f9..af0f5c7825 100644 --- a/code/modules/assembly/flash.dm +++ b/code/modules/assembly/flash.dm @@ -93,7 +93,7 @@ if(crit_fail || (world.time < last_trigger + cooldown)) return FALSE last_trigger = world.time - playsound(src, 'sound/weapons/flash.ogg', 100, 1) + playsound(src, 'sound/weapons/flash.ogg', 100, TRUE) times_used++ flash_recharge() update_icon(TRUE) @@ -195,6 +195,8 @@ /obj/item/assembly/flash/cyborg/attackby(obj/item/W, mob/user, params) return +/obj/item/assembly/flash/cyborg/screwdriver_act(mob/living/user, obj/item/I) + return /obj/item/assembly/flash/memorizer name = "memorizer" @@ -226,7 +228,7 @@ return FALSE overheat = TRUE 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) return TRUE @@ -272,7 +274,7 @@ return crit_fail = FALSE times_used = 0 - playsound(src, 'sound/items/deconstruct.ogg', 50, 1) + playsound(src, 'sound/items/deconstruct.ogg', 50, TRUE) update_icon() flash.crit_fail = TRUE flash.update_icon() diff --git a/code/modules/assembly/health.dm b/code/modules/assembly/health.dm index 633db327bf..78d3f686ab 100644 --- a/code/modules/assembly/health.dm +++ b/code/modules/assembly/health.dm @@ -3,10 +3,10 @@ desc = "Used for scanning and monitoring health." icon_state = "health" materials = list(MAT_METAL=800, MAT_GLASS=200) - attachable = 1 - secured = 0 + attachable = TRUE + secured = FALSE - var/scanning = 0 + var/scanning = FALSE var/health_scan var/alarm_health = 0 @@ -16,31 +16,28 @@ /obj/item/assembly/health/activate() if(!..()) - return 0//Cooldown check + return FALSE//Cooldown check toggle_scan() - return 0 + return TRUE /obj/item/assembly/health/toggle_secure() secured = !secured if(secured && scanning) START_PROCESSING(SSobj, src) else - scanning = 0 + scanning = FALSE STOP_PROCESSING(SSobj, src) update_icon() return secured -/obj/item/assembly/health/attackby(obj/item/W as obj, mob/user as mob) - if(istype(W, /obj/item/multitool)) - if(alarm_health == 0) - alarm_health = -90 - user.show_message("You toggle [src] to \"detect death\" mode.") - else - alarm_health = 0 - user.show_message("You toggle [src] to \"detect critical state\" mode.") - return +/obj/item/assembly/health/multitool_act(mob/living/user, obj/item/I) + if(alarm_health == 0) + alarm_health = -90 + to_chat(user, "You toggle [src] to \"detect death\" mode.") else - return ..() + alarm_health = 0 + to_chat(user, "You toggle [src] to \"detect critical state\" mode.") + return TRUE /obj/item/assembly/health/process() if(!scanning || !secured) @@ -58,7 +55,8 @@ health_scan = M.health if(health_scan <= alarm_health) 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() return return @@ -77,8 +75,9 @@ . = ..() if(!secured) user.show_message("The [name] is unsecured!") - return 0 - var/dat = "Health Sensor [scanning?"On":"Off"]" + return FALSE + var/dat = "Health Sensor" + dat += "
[scanning?"On":"Off"]" if(scanning && health_scan) dat += "
Health: [health_scan]" user << browse(dat, "window=hscan") diff --git a/code/modules/assembly/helpers.dm b/code/modules/assembly/helpers.dm index cb7bd59bb5..dd3f88bff4 100644 --- a/code/modules/assembly/helpers.dm +++ b/code/modules/assembly/helpers.dm @@ -1,3 +1,4 @@ +<<<<<<< HEAD // See _DEFINES/is_helpers.dm for type helpers /* @@ -13,4 +14,22 @@ Name: IsAssemblyHolder Desc: If true is an object that can hold an assemblyholder object */ /obj/proc/IsAssemblyHolder() - return 0 \ No newline at end of file + 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) diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index c830935132..031ce866ba 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -15,7 +15,7 @@ var/obj/item/assembly/a_right = null /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) @@ -37,6 +37,7 @@ a_left = A else a_right = A + A.holder_movement() /obj/item/assembly_holder/update_icon() cut_overlays() @@ -46,11 +47,16 @@ add_overlay("[O]_l") if(a_right) - var/mutable_appearance/right = mutable_appearance(icon, "[a_right.icon_state]_left") - right.transform = matrix(-1, 0, 0, 0, 1, 0) - for(var/O in a_right.attached_overlays) - right.add_overlay("[O]_l") - add_overlay(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") + right.transform = matrix(-1, 0, 0, 0, 1, 0) + for(var/O in a_right.attached_overlays) + right.add_overlay("[O]_l") + add_overlay(right) if(master) master.update_icon() @@ -69,32 +75,37 @@ /obj/item/assembly_holder/Move() . = ..() - if(a_left && a_right) + if(a_left) a_left.holder_movement() + if(a_right) 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 . = ..() if(.) return - if(a_left && a_right) - a_left.holder_movement() - a_right.holder_movement() + if(a_left) + a_left.attack_hand() + if(a_right) + a_right.attack_hand() -/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) - a_left.holder = null - a_left.forceMove(T) - if(a_right) - a_right.holder = null - a_right.forceMove(T) - qdel(src) - else - ..() +/obj/item/assembly_holder/screwdriver_act(mob/user, obj/item/tool) + to_chat(user, "You disassemble [src]!") + if(a_left) + a_left.on_detach() + a_left = null + if(a_right) + a_right.on_detach() + a_right = null + qdel(src) + return TRUE /obj/item/assembly_holder/attack_self(mob/user) src.add_fingerprint(user) @@ -115,12 +126,12 @@ /obj/item/assembly_holder/proc/process_activation(obj/D, normal = 1, special = 1) if(!D) - return 0 + return FALSE if((normal) && (a_right) && (a_left)) if(a_right != D) - a_right.pulsed(0) + a_right.pulsed(FALSE) if(a_left != D) - a_left.pulsed(0) + a_left.pulsed(FALSE) if(master) master.receive_signal() - return 1 + return TRUE diff --git a/code/modules/assembly/igniter.dm b/code/modules/assembly/igniter.dm index ef0949481a..2aae7db5e2 100644 --- a/code/modules/assembly/igniter.dm +++ b/code/modules/assembly/igniter.dm @@ -23,12 +23,12 @@ /obj/item/assembly/igniter/activate() if(!..()) - return 0//Cooldown check + return FALSE//Cooldown check var/turf/location = get_turf(loc) if(location) location.hotspot_expose(1000,1000) sparks.start() - return 1 + return TRUE /obj/item/assembly/igniter/attack_self(mob/user) activate() diff --git a/code/modules/assembly/infrared.dm b/code/modules/assembly/infrared.dm index 35a2074f94..4a6c9d2db3 100644 --- a/code/modules/assembly/infrared.dm +++ b/code/modules/assembly/infrared.dm @@ -3,6 +3,7 @@ desc = "Emits a visible or invisible beam and is triggered when the beam is interrupted." icon_state = "infrared" materials = list(MAT_METAL=1000, MAT_GLASS=500) + is_position_sensitive = TRUE var/on = FALSE var/visible = FALSE @@ -10,6 +11,7 @@ var/list/obj/effect/beam/i_beam/beams var/olddir = 0 var/datum/component/redirect/listener + var/hearing_range = 3 /obj/item/assembly/infra/Initialize() . = ..() @@ -30,23 +32,27 @@ refreshBeam() /obj/item/assembly/infra/Destroy() + STOP_PROCESSING(SSobj, src) QDEL_LIST(beams) - return ..() + . = ..() -/obj/item/assembly/infra/describe() - return "The infrared trigger is [on?"on":"off"]." +/obj/item/assembly/infra/examine(mob/user) + ..() + to_chat(user, "The infrared trigger is [on?"on":"off"].") /obj/item/assembly/infra/activate() if(!..()) - return 0//Cooldown check + return FALSE//Cooldown check on = !on + refreshBeam() update_icon() - return 1 + return TRUE /obj/item/assembly/infra/toggle_secure() secured = !secured if(secured) START_PROCESSING(SSobj, src) + refreshBeam() else QDEL_LIST(beams) STOP_PROCESSING(SSobj, src) @@ -59,13 +65,20 @@ if(on) add_overlay("infrared_on") attached_overlays += "infrared_on" + if(visible && secured) + add_overlay("infrared_visible") + attached_overlays += "infrared_visible" if(holder) holder.update_icon() return /obj/item/assembly/infra/dropped() - refreshBeam() + . = ..() + 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() /obj/item/assembly/infra/process() if(!on || !secured) @@ -74,7 +87,15 @@ /obj/item/assembly/infra/proc/refreshBeam() 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 var/turf/T = get_turf(src) var/_dir = dir @@ -82,6 +103,11 @@ if(_T) for(var/i in 1 to maxlength) 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 if(!I.Move(_T)) qdel(I) @@ -96,6 +122,12 @@ _T = get_step(_T, _dir) CHECK_TICK +/obj/item/assembly/infra/on_detach() + . = ..() + if(!.) + return + refreshBeam() + /obj/item/assembly/infra/attack_hand() . = ..() refreshBeam() @@ -116,19 +148,17 @@ setDir(olddir) 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) refreshBeam() switchListener(location) if(!secured || !on || next_activate > world.time) return FALSE - pulse(0) - audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 3) + pulse(FALSE) + 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 /obj/item/assembly/infra/proc/switchListener(turf/newloc) @@ -144,7 +174,9 @@ . = ..() if(is_secured(user)) user.set_machine(src) - var/dat = "Infrared Laser\nStatus: [on ? "On" : "Off"]
\nVisibility: [visible ? "Visible" : "Invisible"]
\n
" + var/dat = "Infrared Laser" + dat += "
Status: [on ? "On" : "Off"]" + dat += "
Visibility: [visible ? "Visible" : "Invisible"]" dat += "

Refresh" dat += "

Close" user << browse(dat, "window=infra") @@ -163,6 +195,7 @@ refreshBeam() if(href_list["visible"]) visible = !(visible) + update_icon() refreshBeam() if(href_list["close"]) usr << browse(null, "window=infra") diff --git a/code/modules/assembly/mousetrap.dm b/code/modules/assembly/mousetrap.dm index a4d7312887..58a3a5349a 100644 --- a/code/modules/assembly/mousetrap.dm +++ b/code/modules/assembly/mousetrap.dm @@ -2,17 +2,15 @@ name = "mousetrap" desc = "A handy little spring-loaded trap for catching pesty rodents." icon_state = "mousetrap" + item_state = "mousetrap" materials = list(MAT_METAL=100) - attachable = 1 - var/armed = 0 + attachable = TRUE + var/armed = FALSE /obj/item/assembly/mousetrap/examine(mob/user) ..() - if(armed) - to_chat(user, "The mousetrap is armed!") - else - to_chat(user, "The mousetrap is not armed.") + to_chat(user, "The pressure plate is [armed?"primed":"safe"].") /obj/item/assembly/mousetrap/activate() if(..()) @@ -22,13 +20,9 @@ var/mob/living/carbon/human/user = usr if((user.has_trait(TRAIT_DUMB) || user.has_trait(TRAIT_CLUMSY)) && prob(50)) to_chat(user, "Your hand slips, setting off the trigger!") - pulse(0) + pulse(FALSE) update_icon() - if(usr) - playsound(usr.loc, 'sound/weapons/handcuffs.ogg', 30, 1, -3) - -/obj/item/assembly/mousetrap/describe() - return "The pressure switch is [armed?"primed":"safe"]." + playsound(src, 'sound/weapons/handcuffs.ogg', 30, TRUE, -3) /obj/item/assembly/mousetrap/update_icon() if(armed) @@ -45,10 +39,10 @@ if(ishuman(target)) var/mob/living/carbon/human/H = target 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 update_icon() - pulse(0) + pulse(FALSE) return FALSE switch(type) if("feet") @@ -66,10 +60,10 @@ var/mob/living/simple_animal/mouse/M = target visible_message("SPLAT!") M.splat() - playsound(src.loc, 'sound/effects/snap.ogg', 50, 1) + playsound(src, 'sound/effects/snap.ogg', 50, TRUE) armed = FALSE update_icon() - pulse(0) + pulse(FALSE) /obj/item/assembly/mousetrap/attack_self(mob/living/carbon/human/user) @@ -87,7 +81,7 @@ to_chat(user, "You disarm [src].") armed = !armed 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 @@ -145,4 +139,4 @@ /obj/item/assembly/mousetrap/armed icon_state = "mousetraparmed" - armed = 1 + armed = TRUE diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index d79b4786c6..7f6a1fab12 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -3,34 +3,36 @@ desc = "Used for scanning and alerting when someone enters a certain proximity." icon_state = "prox" materials = list(MAT_METAL=800, MAT_GLASS=200) - attachable = 1 + attachable = TRUE - var/scanning = 0 - var/timing = 0 + var/scanning = FALSE + var/timing = FALSE var/time = 10 var/sensitivity = 1 - -/obj/item/assembly/prox_sensor/proc/toggle_scan() - - -/obj/item/assembly/prox_sensor/proc/sense() - + var/hearing_range = 3 /obj/item/assembly/prox_sensor/Initialize() . = ..() proximity_monitor = new(src, 0) + START_PROCESSING(SSobj, src) -/obj/item/assembly/prox_sensor/describe() - if(timing) - return "The proximity sensor is arming." - return "The proximity sensor is [scanning?"armed":"disarmed"]." +/obj/item/assembly/prox_sensor/Destroy() + STOP_PROCESSING(SSobj, src) + . = ..() + +/obj/item/assembly/prox_sensor/examine(mob/user) + ..() + to_chat(user, "The proximity sensor is [timing ? "arming" : (scanning ? "armed" : "disarmed")].") /obj/item/assembly/prox_sensor/activate() if(!..()) - return 0//Cooldown check - timing = !timing + return FALSE//Cooldown check + if(!scanning) + timing = !timing + else + scanning = FALSE update_icon() - return 1 + return TRUE /obj/item/assembly/prox_sensor/toggle_secure() secured = !secured @@ -38,8 +40,10 @@ if(scanning) toggle_scan() proximity_monitor.host = src - timing = 0 + timing = FALSE + STOP_PROCESSING(SSobj, src) else + START_PROCESSING(SSobj, src) proximity_monitor.host = loc update_icon() return secured @@ -51,25 +55,31 @@ sense() -/obj/item/assembly/prox_sensor/sense() +/obj/item/assembly/prox_sensor/proc/sense() if(!scanning || !secured || next_activate > world.time) - return 0 - pulse(0) - audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 3) + return FALSE + pulse(FALSE) + 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 + return TRUE /obj/item/assembly/prox_sensor/process() - if(timing) - time-- - if(time <= 0) - timing = 0 - toggle_scan(1) - time = initial(time) + if(!timing) + return + time-- + if(time <= 0) + timing = FALSE + toggle_scan(TRUE) + time = initial(time) -/obj/item/assembly/prox_sensor/toggle_scan(scan) +/obj/item/assembly/prox_sensor/proc/toggle_scan(scan) if(!secured) - return 0 + return FALSE scanning = scan proximity_monitor.SetRange(scanning ? sensitivity : 0) update_icon() @@ -98,8 +108,11 @@ if(is_secured(user)) var/second = time % 60 var/minute = (time - second) / 60 - var/dat = "Proximity Sensor\n[(timing ? "Arming" : "Not Arming")] [minute]:[second]\n- - + +\n" - dat += "
Armed":"1'>Unarmed"] (Movement sensor active when armed!)" + var/dat = "Proximity Sensor" + if(!scanning) + dat += "
[(timing ? "Arming" : "Not Arming")] [minute]:[second]" + dat += "
- - + +" + dat += "
Armed":"1'>Unarmed (Movement sensor active when armed!)"]" dat += "
Detection range: - [sensitivity] +" dat += "

Refresh" dat += "

Close" diff --git a/code/modules/assembly/shock_kit.dm b/code/modules/assembly/shock_kit.dm index 38f2acb45f..8d9ba9880c 100644 --- a/code/modules/assembly/shock_kit.dm +++ b/code/modules/assembly/shock_kit.dm @@ -13,18 +13,18 @@ qdel(part2) return ..() -/obj/item/assembly/shock_kit/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/wrench)) +/obj/item/assembly/shock_kit/wrench_act(mob/living/user, obj/item/I) + to_chat(user, "You disassemble [src].") + if(part1) part1.forceMove(drop_location()) - part2.forceMove(drop_location()) part1.master = null - part2.master = null part1 = null + if(part2) + part2.forceMove(drop_location()) + part2.master = null part2 = null - qdel(src) - return - add_fingerprint(user) - return + qdel(src) + return TRUE /obj/item/assembly/shock_kit/attack_self(mob/user) part1.attack_self(user) diff --git a/code/modules/assembly/signaler.dm b/code/modules/assembly/signaler.dm index 4b44397713..20bcf25138 100644 --- a/code/modules/assembly/signaler.dm +++ b/code/modules/assembly/signaler.dm @@ -7,17 +7,18 @@ righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi' materials = list(MAT_METAL=400, MAT_GLASS=120) wires = WIRE_RECEIVE | WIRE_PULSE | WIRE_RADIO_PULSE | WIRE_RADIO_RECEIVE - attachable = 1 + attachable = TRUE var/code = DEFAULT_SIGNALER_CODE var/frequency = FREQ_SIGNALER var/delay = 0 var/datum/radio_frequency/radio_connection var/suicider = null + var/hearing_range = 1 /obj/item/assembly/signaler/suicide_act(mob/living/carbon/user) user.visible_message("[user] eats \the [src]! If it is signaled, [user.p_they()] will die!") - playsound(src, 'sound/items/eatfood.ogg', 50, 1) + playsound(src, 'sound/items/eatfood.ogg', 50, TRUE) user.transferItemToLoc(src, user, TRUE) suicider = user return MANUAL_SUICIDE @@ -27,15 +28,14 @@ user.adjustOxyLoss(200)//it sends an electrical pulse to their heart, killing them. or something. user.death(0) -/obj/item/assembly/signaler/New() - ..() - spawn(40) - set_frequency(frequency) +/obj/item/assembly/signaler/Initialize() + . = ..() + set_frequency(frequency) /obj/item/assembly/signaler/Destroy() SSradio.remove_object(src,frequency) - return ..() + . = ..() /obj/item/assembly/signaler/activate() if(!..())//cooldown processing @@ -80,7 +80,7 @@ Code: /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") onclose(usr, "radio") return @@ -131,17 +131,22 @@ Code: return /obj/item/assembly/signaler/receive_signal(datum/signal/signal) + . = FALSE if(!signal) - return 0 + return if(signal.data["code"] != code) - return 0 + return if(!(src.wires & WIRE_RADIO_RECEIVE)) - return 0 + return if(suicider) manual_suicide(suicider) - pulse(1) - audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 1) - return + pulse(TRUE) + 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) + return TRUE /obj/item/assembly/signaler/proc/set_frequency(new_frequency) @@ -161,10 +166,11 @@ Code: /obj/item/assembly/signaler/reciever/activate() toggle_safety() - return 1 + return TRUE -/obj/item/assembly/signaler/reciever/describe() - return "The radio receiver is [on?"on":"off"]." +/obj/item/assembly/signaler/reciever/examine(mob/user) + ..() + to_chat(user, "The radio receiver is [on?"on":"off"].") /obj/item/assembly/signaler/reciever/receive_signal(datum/signal/signal) if(!on) @@ -183,11 +189,12 @@ Code: /obj/item/assembly/signaler/anomaly/receive_signal(datum/signal/signal) if(!signal) - return 0 + return FALSE if(signal.data["code"] != code) - return 0 + return FALSE for(var/obj/effect/anomaly/A in get_turf(src)) A.anomalyNeutralize() + return TRUE /obj/item/assembly/signaler/anomaly/attack_self() return @@ -196,3 +203,5 @@ Code: /obj/item/assembly/signaler/cyborg/attackby(obj/item/W, mob/user, params) return +/obj/item/assembly/signaler/cyborg/screwdriver_act(mob/living/user, obj/item/I) + return diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index 7c74c1ca77..993bf134e6 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -3,12 +3,13 @@ desc = "Used to time things. Works well with contraptions which has to count down. Tick tock." icon_state = "timer" materials = list(MAT_METAL=500, MAT_GLASS=50) - attachable = 1 + attachable = TRUE - var/timing = 0 + var/timing = FALSE var/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) user.visible_message("[user] looks at the timer and decides [user.p_their()] fate! It looks like [user.p_theyre()] going to commit suicide!") @@ -21,22 +22,24 @@ user.adjustOxyLoss(200) user.death(0) -/obj/item/assembly/timer/New() - ..() +/obj/item/assembly/timer/Initialize() + . = ..() START_PROCESSING(SSobj, src) -/obj/item/assembly/timer/describe() - if(timing) - return "The timer is counting down from [time]!" - return "The timer is set for [time] seconds." +/obj/item/assembly/timer/Destroy() + STOP_PROCESSING(SSobj, src) + . = ..() +/obj/item/assembly/timer/examine(mob/user) + ..() + to_chat(user, "The timer is [timing ? "counting down from [time]":"set for [time] seconds"].") /obj/item/assembly/timer/activate() if(!..()) - return 0//Cooldown check + return FALSE//Cooldown check timing = !timing update_icon() - return 1 + return TRUE /obj/item/assembly/timer/toggle_secure() @@ -44,7 +47,7 @@ if(secured) START_PROCESSING(SSobj, src) else - timing = 0 + timing = FALSE STOP_PROCESSING(SSobj, src) update_icon() return secured @@ -53,20 +56,25 @@ /obj/item/assembly/timer/proc/timer_end() if(!secured || next_activate > world.time) return FALSE - pulse(0) - audible_message("[icon2html(src, hearers(src))] *beep* *beep*", null, 3) + pulse(FALSE) + 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) - timing = 1 + timing = TRUE update_icon() /obj/item/assembly/timer/process() - if(timing) - time-- - if(time <= 0) - timing = 0 - timer_end() - time = saved_time + if(!timing) + return + time-- + if(time <= 0) + timing = FALSE + timer_end() + time = saved_time /obj/item/assembly/timer/update_icon() @@ -84,7 +92,9 @@ if(is_secured(user)) var/second = time % 60 var/minute = (time - second) / 60 - var/dat = "Timing Unit\n[(timing ? "Timing" : "Not Timing")] [minute]:[second]\n- - + +\n" + var/dat = "Timing Unit" + dat += "
[(timing ? "Timing" : "Not Timing")] [minute]:[second]" + dat += "
- - + +" dat += "

Stop repeating" : "1'>Set to repeat")]" dat += "

Refresh" dat += "

Close" @@ -95,7 +105,7 @@ /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") onclose(usr, "timer") return diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 71f51aaaf9..ca97752d90 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -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 name = "voice analyzer" desc = "A small electronic device able to record a voice sample, and send a signal when that sample is repeated." icon_state = "voice" materials = list(MAT_METAL=500, MAT_GLASS=50) flags_1 = HEAR_1 - attachable = 1 + attachable = TRUE verb_say = "beeps" verb_ask = "beeps" verb_exclaim = "beeps" - var/listening = 0 + var/listening = FALSE var/recorded = "" //the activation message var/mode = 1 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) switch(mode) - if(1) + if(INCLUSIVE_MODE) recorded = raw_message - listening = 0 + listening = FALSE say("Activation message is '[recorded]'.", message_language) - if(2) + if(EXCLUSIVE_MODE) recorded = raw_message - listening = 0 + listening = FALSE say("Activation message is '[recorded]'.", message_language) - if(3) + if(RECOGNIZER_MODE) recorded = speaker.GetVoice() - listening = 0 + listening = FALSE say("Your voice pattern is saved.", message_language) - if(4) + if(VOICE_SENSOR_MODE) if(length(raw_message)) addtimer(CALLBACK(src, .proc/pulse, 0), 10) /obj/item/assembly/voice/proc/check_activation(atom/movable/speaker, raw_message) - . = 0 + . = FALSE switch(mode) - if(1) + if(INCLUSIVE_MODE) if(findtext(raw_message, recorded)) - . = 1 - if(2) + . = TRUE + if(EXCLUSIVE_MODE) if(raw_message == recorded) - . = 1 - if(3) + . = TRUE + if(RECOGNIZER_MODE) if(speaker.GetVoice() == recorded) - . = 1 - if(4) + . = TRUE + if(VOICE_SENSOR_MODE) if(length(raw_message)) - . = 1 + . = TRUE -/obj/item/assembly/voice/attackby(obj/item/W, mob/user, params) - if(istype(W, /obj/item/multitool)) - mode %= modes.len - mode++ - to_chat(user, "You set [src] into a [modes[mode]] mode.") - listening = 0 - recorded = "" - else - return ..() +/obj/item/assembly/voice/multitool_act(mob/living/user, obj/item/I) + mode %= modes.len + mode++ + to_chat(user, "You set [src] into [modes[mode]] mode.") + listening = FALSE + recorded = "" + return TRUE /obj/item/assembly/voice/activate() - if(secured) - if(!holder) - listening = !listening - say("[listening ? "Now" : "No longer"] recording input.") + if(!secured || holder) + return FALSE + listening = !listening + say("[listening ? "Now" : "No longer"] recording input.") + return TRUE /obj/item/assembly/voice/attack_self(mob/user) if(!user) - return 0 + return FALSE activate() - return 1 + return TRUE /obj/item/assembly/voice/toggle_secure() . = ..() - listening = 0 + listening = FALSE + +#undef INCLUSIVE_MODE +#undef EXCLUSIVE_MODE +#undef RECOGNIZER_MODE +#undef VOICE_SENSOR_MODE diff --git a/code/modules/integrated_electronics/subtypes/input.dm b/code/modules/integrated_electronics/subtypes/input.dm index 042d6a3616..c810f87468 100644 --- a/code/modules/integrated_electronics/subtypes/input.dm +++ b/code/modules/integrated_electronics/subtypes/input.dm @@ -637,6 +637,7 @@ var/frequency = FREQ_SIGNALER var/code = DEFAULT_SIGNALER_CODE var/datum/radio_frequency/radio_connection + var/hearing_range = 1 /obj/item/integrated_circuit/input/signaler/Initialize() . = ..() @@ -690,7 +691,11 @@ return 0 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 name = "NTNet networking circuit" diff --git a/code/modules/mob/living/silicon/pai/software.dm b/code/modules/mob/living/silicon/pai/software.dm index b841ae95db..79baa0bad5 100644 --- a/code/modules/mob/living/silicon/pai/software.dm +++ b/code/modules/mob/living/silicon/pai/software.dm @@ -170,7 +170,8 @@ if(href_list["send"]) 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"]) var/new_frequency = (signaler.frequency + text2num(href_list["freq"])) diff --git a/icons/obj/assemblies.dmi b/icons/obj/assemblies.dmi index 5714953e3f..9cbc085624 100644 Binary files a/icons/obj/assemblies.dmi and b/icons/obj/assemblies.dmi differ diff --git a/icons/obj/assemblies/new_assemblies.dmi b/icons/obj/assemblies/new_assemblies.dmi index 0e561b6ff8..df9517aeaa 100644 Binary files a/icons/obj/assemblies/new_assemblies.dmi and b/icons/obj/assemblies/new_assemblies.dmi differ diff --git a/icons/obj/projectiles.dmi b/icons/obj/projectiles.dmi index 2d0d35f8a5..84e9f78add 100644 Binary files a/icons/obj/projectiles.dmi and b/icons/obj/projectiles.dmi differ