diff --git a/code/ATMOSPHERICS/pipeline.dm b/code/ATMOSPHERICS/pipeline.dm index aa65828231b..9a30d3936d9 100644 --- a/code/ATMOSPHERICS/pipeline.dm +++ b/code/ATMOSPHERICS/pipeline.dm @@ -220,11 +220,12 @@ var/pipenetwarnings = 10 total_thermal_energy += G.thermal_energy() total_heat_capacity += G.heat_capacity() - total_gas_mixture.temperature = total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0 + total_gas_mixture.temperature = total_heat_capacity ? total_thermal_energy/total_heat_capacity : 0 if(total_gas_mixture.volume > 0) //Update individual gas_mixtures by volume ratio - for(var/datum/gas_mixture/G in GL) + for(var/i in GL) + var/datum/gas_mixture/G = i G.copy_from(total_gas_mixture) var/list/G_gases = G.gases for(var/id in G_gases) diff --git a/code/__HELPERS/unsorted.dm b/code/__HELPERS/unsorted.dm index 5497e1ba8b1..20d35846a87 100644 --- a/code/__HELPERS/unsorted.dm +++ b/code/__HELPERS/unsorted.dm @@ -1182,3 +1182,35 @@ B --><-- A for(var/atom/location = A.loc, location, location = location.loc) if(location == src) return 1 + +proc/add_to_proximity_list(atom/A, range) + var/turf/T = get_turf(A) + var/list/L = block(locate(T.x - range, T.y - range, T.z), locate(T.x + range, T.y + range, T.z)) + for(var/B in L) + var/turf/C = B + C.proximity_checkers |= A + return L + +proc/remove_from_proximity_list(atom/A, range) + var/turf/T = get_turf(A) + var/list/L = block(locate(T.x - range, T.y - range, T.z), locate(T.x + range, T.y + range, T.z)) + for(var/B in L) + var/turf/C = B + C.proximity_checkers.Remove(A) + +proc/shift_proximity(atom/checker, atom/A, range, atom/B, newrange) + var/turf/T = get_turf(A) + var/turf/Q = get_turf(B) + if(T == Q && range == newrange) + return 0 + var/list/L = block(locate(T.x - range, T.y - range, T.z), locate(T.x + range, T.y + range, T.z)) + var/list/M = block(locate(Q.x - newrange, Q.y - newrange, Q.z), locate(Q.x + newrange, Q.y + newrange, Q.z)) + var/list/N = L - M + var/list/O = M - L + for(var/C in N) + var/turf/D = C + D.proximity_checkers.Remove(checker) + for(var/E in O) + var/turf/F = E + F.proximity_checkers |= checker + return 1 diff --git a/code/game/machinery/camera/motion.dm b/code/game/machinery/camera/motion.dm index b0b2b840af1..a7a0f0a847e 100644 --- a/code/game/machinery/camera/motion.dm +++ b/code/game/machinery/camera/motion.dm @@ -5,6 +5,16 @@ var/area/ai_monitored/area_motion = null var/alarm_delay = 30 // Don't forget, there's another 3 seconds in queueAlarm() +/obj/machinery/camera/New() + add_to_proximity_list(src, 1) //1 was default of everything + +/obj/machinery/camera/Move() + remove_from_proximity_list(src, 1) + ..() + +/obj/machinery/camera/Destroy() + remove_from_proximity_list(src, 1) + ..() /obj/machinery/camera/process() // motion camera event loop diff --git a/code/game/machinery/doors/airlock.dm b/code/game/machinery/doors/airlock.dm index 304d927c9dd..7b57aae3915 100644 --- a/code/game/machinery/doors/airlock.dm +++ b/code/game/machinery/doors/airlock.dm @@ -1113,11 +1113,6 @@ var/list/airlock_overlays = list() //Airlock is passable if it is open (!density), bot has access, and is not bolted shut or powered off) return !density || (check_access(ID) && !locked && hasPower()) -/obj/machinery/door/airlock/HasProximity(atom/movable/AM as mob|obj) - for (var/obj/A in contents) - A.HasProximity(AM) - return - /obj/machinery/door/airlock/emag_act(mob/user) if(!operating && density && hasPower() && !emagged) operating = 1 diff --git a/code/game/machinery/flasher.dm b/code/game/machinery/flasher.dm index c261956806f..00f5ad0e24b 100644 --- a/code/game/machinery/flasher.dm +++ b/code/game/machinery/flasher.dm @@ -26,6 +26,10 @@ ..() // ..() is EXTREMELY IMPORTANT, never forget to add it bulb = new /obj/item/device/assembly/flash/handheld(src) +/obj/machinery/flasher/Move() + remove_from_proximity_list(src, range) + ..() + /obj/machinery/flasher/power_change() if (powered() && anchored && bulb) stat &= ~NOPOWER @@ -127,11 +131,13 @@ overlays += "[base_state]-s" anchored = 1 power_change() + add_to_proximity_list(src, range) else user << "[src] can now be moved." overlays.Cut() anchored = 0 power_change() + remove_from_proximity_list(src, range) else ..() \ No newline at end of file diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 92b74435c6d..cc54f73b47c 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -318,6 +318,9 @@ spawn(rand(MIN_GROWTH_TIME, MAX_GROWTH_TIME)) Grow() +/obj/structure/alien/egg/Destroy() + remove_from_proximity_list(src, 1) + ..() /obj/structure/alien/egg/attack_paw(mob/living/user) return attack_hand(user) @@ -348,10 +351,11 @@ /obj/structure/alien/egg/proc/Grow() icon_state = "egg" status = GROWN - + add_to_proximity_list(src, 1) /obj/structure/alien/egg/proc/Burst(kill = 1) //drops and kills the hugger if any is remaining if(status == GROWN || status == GROWING) + remove_from_proximity_list(src, 1) icon_state = "egg_hatched" flick("egg_opening", src) status = BURSTING @@ -368,6 +372,9 @@ child.Attach(M) break +/obj/structure/alien/egg/Move() + remove_from_proximity_list(src, 1) + ..() /obj/structure/alien/egg/bullet_act(obj/item/projectile/Proj) health -= Proj.damage diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index eb13de0ce1a..a8de11836a8 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -60,12 +60,6 @@ attacher = user return - -/obj/item/device/transfer_valve/HasProximity(atom/movable/AM as mob|obj) - if(!attached_device) - return - attached_device.HasProximity(AM) - return /obj/item/device/transfer_valve/attack_self(mob/user) user.set_machine(src) var/dat = {" Valve properties: diff --git a/code/game/objects/items/weapons/grenades/chem_grenade.dm b/code/game/objects/items/weapons/grenades/chem_grenade.dm index 56031b41c4e..509999d5f92 100644 --- a/code/game/objects/items/weapons/grenades/chem_grenade.dm +++ b/code/game/objects/items/weapons/grenades/chem_grenade.dm @@ -143,9 +143,6 @@ /obj/item/weapon/grenade/chem_grenade/receive_signal() prime() -/obj/item/weapon/grenade/chem_grenade/HasProximity(atom/movable/AM) - if(nadeassembly) - nadeassembly.HasProximity(AM) /obj/item/weapon/grenade/chem_grenade/Crossed(atom/movable/AM) if(nadeassembly) diff --git a/code/game/objects/items/weapons/stunbaton.dm b/code/game/objects/items/weapons/stunbaton.dm index 43a79de4c46..79a25e3cd0b 100644 --- a/code/game/objects/items/weapons/stunbaton.dm +++ b/code/game/objects/items/weapons/stunbaton.dm @@ -181,3 +181,12 @@ stunforce = 5 hitcost = 2500 slot_flags = null + var/obj/item/device/assembly/igniter/sparkler = 0 + +/obj/item/weapon/melee/baton/cattleprod/New() + ..() + sparkler = new (src) + +/obj/item/weapon/melee/baton/cattleprod/baton_stun() + if(sparkler.activate()) + ..() \ No newline at end of file diff --git a/code/game/objects/items/weapons/weaponry.dm b/code/game/objects/items/weapons/weaponry.dm index 9087ec8dc77..910c3dfc84a 100644 --- a/code/game/objects/items/weapons/weaponry.dm +++ b/code/game/objects/items/weapons/weaponry.dm @@ -117,7 +117,7 @@ qdel(I) qdel(src) - else if(istype(I, /obj/item/weapon/wirecutters) && !(I.flags & NODROP)) + else if(istype(I, /obj/item/device/assembly/igniter) && !(I.flags & NODROP)) var/obj/item/weapon/melee/baton/cattleprod/P = new /obj/item/weapon/melee/baton/cattleprod if(!remove_item_from_storage(user)) @@ -125,7 +125,7 @@ user.unEquip(I) user.put_in_hands(P) - user << "You fasten the wirecutters to the top of the rod with the cable, prongs outward." + user << "You fasten [I] to the top of the rod with the cable." qdel(I) qdel(src) diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index a02fb4c3bca..ae925323705 100644 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -26,6 +26,8 @@ flags = 0 + var/list/proximity_checkers = list() + var/image/obscured //camerachunks /turf/New() ..() @@ -91,12 +93,9 @@ return 1 //Nothing found to block so return success! /turf/Entered(atom/movable/M) - var/loopsanity = 100 - for(var/atom/A in range(1)) - if(loopsanity == 0) - break - loopsanity-- - A.HasProximity(M, 1) + for(var/A in proximity_checkers) + var/atom/B = A + B.HasProximity(M) /turf/proc/is_plasteel_floor() return 0 diff --git a/code/modules/assembly/assembly.dm b/code/modules/assembly/assembly.dm index e55cf0149b2..a999ed9e2ee 100644 --- a/code/modules/assembly/assembly.dm +++ b/code/modules/assembly/assembly.dm @@ -25,6 +25,10 @@ var/const/WIRE_RADIO_RECEIVE = 8 //Allows Pulsed(1) to call Activate() var/const/WIRE_RADIO_PULSE = 16 //Allows Pulse(1) to send a radio message +/obj/item/device/assembly/proc/on_attach() + +/obj/item/device/assembly/proc/on_detach() + /obj/item/device/assembly/proc/holder_movement() //Called when the holder is moved return diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index 3a446749607..81e4a92f2e6 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -69,10 +69,6 @@ else bombtank.release() -/obj/item/device/onetankbomb/HasProximity(atom/movable/AM as mob|obj) - if(bombassembly) - bombassembly.HasProximity(AM) - /obj/item/device/onetankbomb/Crossed(atom/movable/AM as mob|obj) //for mousetraps if(bombassembly) bombassembly.Crossed(AM) diff --git a/code/modules/assembly/holder.dm b/code/modules/assembly/holder.dm index 6be68eb1a84..a4b7720d0c8 100644 --- a/code/modules/assembly/holder.dm +++ b/code/modules/assembly/holder.dm @@ -55,13 +55,6 @@ if(master) master.update_icon() -/obj/item/device/assembly_holder/HasProximity(atom/movable/AM as mob|obj) - if(a_left) - a_left.HasProximity(AM) - if(a_right) - a_right.HasProximity(AM) - - /obj/item/device/assembly_holder/Crossed(atom/movable/AM as mob|obj) if(a_left) a_left.Crossed(AM) diff --git a/code/modules/assembly/proximity.dm b/code/modules/assembly/proximity.dm index 79c8b67c0b5..ce2f468e0d6 100644 --- a/code/modules/assembly/proximity.dm +++ b/code/modules/assembly/proximity.dm @@ -9,6 +9,9 @@ var/scanning = 0 var/timing = 0 var/time = 10 + var/sensitivity = 1 + var/atom/oldloc + var/list/turfs_around = list() /obj/item/device/assembly/prox_sensor/proc/toggle_scan() @@ -19,12 +22,19 @@ /obj/item/device/assembly/prox_sensor/New() ..() SSobj.processing |= src + oldloc = loc /obj/item/device/assembly/prox_sensor/describe() if(timing) return "The proximity sensor is arming." return "The proximity sensor is [scanning?"armed":"disarmed"]." +/obj/item/device/assembly/prox_sensor/on_attach(datum/wires/w) + handle_move(w.holder) + +/obj/item/device/assembly/prox_sensor/on_detach(datum/wires/w) + handle_move(w.holder.loc) + /obj/item/device/assembly/prox_sensor/activate() if(!..()) return 0//Cooldown check @@ -35,12 +45,9 @@ /obj/item/device/assembly/prox_sensor/toggle_secure() secured = !secured - if(secured) - SSobj.processing |= src - else + if(!secured) scanning = 0 timing = 0 - SSobj.processing.Remove(src) update_icon() return secured @@ -52,7 +59,7 @@ /obj/item/device/assembly/prox_sensor/sense() - if((!secured)||(!scanning)||(cooldown > 0)) + if((!secured)||(cooldown > 0)) return 0 pulse(0) audible_message("\icon[src] *beep* *beep*", null, 3) @@ -66,22 +73,32 @@ time-- if(time <= 0) timing = 0 - toggle_scan() + toggle_scan(1) time = initial(time) - + handle_move(get_turf(loc)) /obj/item/device/assembly/prox_sensor/dropped() - spawn(0) - sense() + if(scanning) + spawn(0) + sense() -/obj/item/device/assembly/prox_sensor/toggle_scan() +/obj/item/device/assembly/prox_sensor/toggle_scan(scan) if(!secured) return 0 - scanning = !scanning + scanning = scan + if(scanning) + add_to_proximity_list(src, sensitivity) + else + remove_from_proximity_list(src, sensitivity) + oldloc = get_turf(loc) update_icon() - +/obj/item/device/assembly/prox_sensor/proc/sensitivity_change(value) + var/sense = min(max(sensitivity + value, 0), 5) + if(scanning) + shift_proximity(src, oldloc, sensitivity, loc, sense) + sensitivity = sense /obj/item/device/assembly/prox_sensor/update_icon() overlays.Cut() @@ -96,11 +113,15 @@ holder.update_icon() return +/obj/item/device/assembly/prox_sensor/proc/handle_move(atom/newloc) + if(scanning) + if(shift_proximity(src, oldloc, sensitivity, newloc, sensitivity)) + sense() + oldloc = newloc -/obj/item/device/assembly/prox_sensor/Move() +/obj/item/device/assembly/prox_sensor/Move(newloc) ..() - sense() - return + handle_move(newloc) /obj/item/device/assembly/prox_sensor/interact(mob/user)//TODO: Change this to the wires thingy @@ -108,7 +129,8 @@ var/second = time % 60 var/minute = (time - second) / 60 var/dat = "Proximity Sensor\n[(timing ? "Arming" : "Not Arming")] [minute]:[second]\n- - + +\n" - dat += "
[scanning?"Armed":"Unarmed"] (Movement sensor active when armed!)" + dat += "
Armed":"1'>Unarmed"] (Movement sensor active when armed!)" + dat += "
Detection range: - [sensitivity] +" dat += "

Refresh" dat += "

Close" user << browse(dat, "window=prox") @@ -123,8 +145,11 @@ onclose(usr, "prox") return + if(href_list["sense"]) + sensitivity_change(((href_list["sense"] == "up") ? 1 : -1)) + if(href_list["scanning"]) - toggle_scan() + toggle_scan(text2num(href_list["scanning"])) if(href_list["time"]) timing = text2num(href_list["time"]) diff --git a/code/modules/assembly/timer.dm b/code/modules/assembly/timer.dm index e889d6fc723..3432899486a 100644 --- a/code/modules/assembly/timer.dm +++ b/code/modules/assembly/timer.dm @@ -8,6 +8,8 @@ var/timing = 0 var/time = 5 + var/saved_time = 5 + var/loop = 0 /obj/item/device/assembly/timer/New() @@ -47,6 +49,8 @@ cooldown = 2 spawn(10) process_cooldown() + if(loop) + timing = 1 update_icon() @@ -56,7 +60,7 @@ if(time <= 0) timing = 0 timer_end() - time = initial(time) + time = saved_time /obj/item/device/assembly/timer/update_icon() @@ -74,6 +78,7 @@ var/second = time % 60 var/minute = (time - second) / 60 var/dat = "Timing Unit\n[(timing ? "Timing" : "Not Timing")] [minute]:[second]\n- - + +\n" + dat += "

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

Refresh" dat += "

Close" var/datum/browser/popup = new(user, "timer", name) @@ -96,11 +101,14 @@ bombers += timer_message log_game("[key_name(usr)] activated [src] attachment for [loc]") update_icon() + if(href_list["repeat"]) + loop = text2num(href_list["repeat"]) if(href_list["tp"]) var/tp = text2num(href_list["tp"]) time += tp time = min(max(round(time), 1), 600) + saved_time = time if(href_list["close"]) usr << browse(null, "window=timer") diff --git a/code/modules/assembly/voice.dm b/code/modules/assembly/voice.dm index 9364743c5db..71ef85ef8c5 100644 --- a/code/modules/assembly/voice.dm +++ b/code/modules/assembly/voice.dm @@ -11,20 +11,66 @@ verb_exclaim = "beeps" var/listening = 0 var/recorded = "" //the activation message + var/mode = 1 + var/global/list/modes = list("inclusive", + "exclusive", + "recognizer", + "voice sensor") /obj/item/device/assembly/voice/Hear(message, atom/movable/speaker, message_langs, raw_message, radio_freq, list/spans) if(speaker == src) return if(listening && !radio_freq) - recorded = raw_message - listening = 0 - say("Activation message is '[recorded]'.") + record_speech(speaker, raw_message) else - if(findtextEx(raw_message, recorded)) + if(check_activation(speaker, raw_message)) spawn(10) pulse(0) +/obj/item/device/assembly/voice/proc/record_speech(atom/movable/speaker, raw_message) + switch(mode) + if(1) + recorded = raw_message + listening = 0 + say("Activation message is '[recorded]'.") + if(2) + recorded = raw_message + listening = 0 + say("Activation message is '[recorded]'.") + if(3) + recorded = speaker.GetVoice() + listening = 0 + say("Your voice pattern is saved.") + if(4) + if(length(raw_message)) + spawn(10) + pulse(0) + +/obj/item/device/assembly/voice/proc/check_activation(atom/movable/speaker, raw_message) + . = 0 + switch(mode) + if(1) + if(findtextEx(raw_message, recorded)) + . = 1 + if(2) + if(raw_message == recorded) + . = 1 + if(3) + if(speaker.GetVoice() == recorded) + . = 1 + if(4) + if(length(raw_message)) + . = 1 + +/obj/item/device/assembly/voice/attackby(obj/item/weapon/W, mob/user, params) + if(istype(W, /obj/item/device/multitool)) + mode %= modes.len + mode++ + user << "You set [src] into a [modes[mode]] mode." + listening = 0 + recorded = "" + /obj/item/device/assembly/voice/activate() if(secured) if(!holder) diff --git a/code/modules/crafting/recipes.dm b/code/modules/crafting/recipes.dm index 1b242b34cfa..76e0cead24a 100644 --- a/code/modules/crafting/recipes.dm +++ b/code/modules/crafting/recipes.dm @@ -63,7 +63,7 @@ result = /obj/item/weapon/melee/baton/cattleprod reqs = list(/obj/item/weapon/restraints/handcuffs/cable = 1, /obj/item/stack/rods = 1, - /obj/item/weapon/wirecutters = 1, + /obj/item/device/assembly/igniter = 1, /obj/item/weapon/stock_parts/cell = 1) time = 80 parts = list(/obj/item/weapon/stock_parts/cell = 1) diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index 5093003a035..8e8cdeb2fc2 100644 Binary files a/icons/mob/inhands/items_lefthand.dmi and b/icons/mob/inhands/items_lefthand.dmi differ diff --git a/icons/mob/inhands/items_righthand.dmi b/icons/mob/inhands/items_righthand.dmi index f5868458340..37d22120d7d 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/obj/weapons.dmi b/icons/obj/weapons.dmi index 93ed62314d3..675da21434a 100644 Binary files a/icons/obj/weapons.dmi and b/icons/obj/weapons.dmi differ