diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index aac6fae9fdd..77044baed50 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -16139,11 +16139,13 @@ /turf/open/floor/iron, /area/station/security/checkpoint/medical) "eyX" = ( -/obj/item/kirbyplants/random, /obj/machinery/newscaster/directional/north, /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, +/obj/structure/table/reinforced, +/obj/item/mod/module/plasma_stabilizer, +/obj/item/mod/module/thermal_regulator, /turf/open/floor/iron, /area/station/security/office) "ezd" = ( @@ -30432,8 +30434,7 @@ "iuQ" = ( /obj/machinery/door/window/brigdoor/security/cell/right/directional/west{ id = "brig1"; - name = "Cell 1"; - req_access = list("brig") + name = "Cell 1" }, /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -50275,8 +50276,7 @@ "nKk" = ( /obj/machinery/door/window/brigdoor/security/cell/right/directional/west{ id = "brig2"; - name = "Cell 2"; - req_access = list("brig") + name = "Cell 2" }, /obj/structure/cable, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, @@ -54572,9 +54572,7 @@ /turf/open/floor/iron, /area/station/science/lab) "oPY" = ( -/obj/structure/closet/secure_closet/bar{ - req_access = list("bar") - }, +/obj/structure/closet/secure_closet/bar, /obj/item/storage/photo_album/bar, /obj/item/radio/intercom/directional/east, /obj/item/storage/dice, @@ -62543,6 +62541,7 @@ /obj/effect/turf_decal/tile/red/half/contrasted{ dir = 1 }, +/obj/item/kirbyplants/random, /turf/open/floor/iron, /area/station/security/office) "qZQ" = ( diff --git a/_maps/map_files/IceBoxStation/IceBoxStation.dmm b/_maps/map_files/IceBoxStation/IceBoxStation.dmm index 643f829b273..10cc9f1c74c 100644 --- a/_maps/map_files/IceBoxStation/IceBoxStation.dmm +++ b/_maps/map_files/IceBoxStation/IceBoxStation.dmm @@ -50797,6 +50797,8 @@ /area/station/commons/vacant_room/commissary) "qsX" = ( /obj/structure/table, +/obj/item/mod/module/plasma_stabilizer, +/obj/item/mod/module/thermal_regulator, /obj/item/assembly/flash/handheld, /turf/open/floor/iron/dark/textured_half{ dir = 1 diff --git a/_maps/map_files/KiloStation/KiloStation.dmm b/_maps/map_files/KiloStation/KiloStation.dmm index 113e2bf87bb..a28e7791062 100644 --- a/_maps/map_files/KiloStation/KiloStation.dmm +++ b/_maps/map_files/KiloStation/KiloStation.dmm @@ -13488,9 +13488,7 @@ /turf/open/floor/iron/dark, /area/station/security/prison) "dZe" = ( -/obj/structure/closet/secure_closet/bar{ - req_access = list("bar") - }, +/obj/structure/closet/secure_closet/bar, /obj/item/flashlight/lantern, /obj/effect/turf_decal/tile/neutral, /obj/effect/turf_decal/tile/neutral{ @@ -14890,6 +14888,7 @@ /obj/effect/turf_decal/tile/neutral/half/contrasted{ dir = 1 }, +/obj/item/inspector, /turf/open/floor/iron/dark, /area/station/security/office) "eso" = ( @@ -52022,9 +52021,8 @@ /area/station/hallway/primary/starboard) "oHe" = ( /obj/structure/table/reinforced, -/obj/item/paper_bin, -/obj/item/pen, -/obj/item/inspector, +/obj/item/mod/module/plasma_stabilizer, +/obj/item/mod/module/thermal_regulator, /turf/open/floor/iron/dark, /area/station/security/office) "oHh" = ( @@ -56523,12 +56521,14 @@ /area/station/security/courtroom) "pUA" = ( /obj/structure/table/reinforced, -/obj/item/book/manual/wiki/security_space_law, -/obj/item/taperecorder, /obj/structure/disposalpipe/segment{ dir = 4 }, /obj/effect/turf_decal/tile/neutral/half/contrasted, +/obj/item/paper_bin, +/obj/item/taperecorder, +/obj/item/book/manual/wiki/security_space_law, +/obj/item/pen, /turf/open/floor/iron/dark, /area/station/security/office) "pUH" = ( @@ -65939,8 +65939,7 @@ dir = 4 }, /obj/structure/sign/barsign{ - pixel_y = 32; - req_access = list("bar") + pixel_y = 32 }, /turf/open/floor/wood, /area/station/service/bar/atrium) diff --git a/_maps/map_files/MetaStation/MetaStation.dmm b/_maps/map_files/MetaStation/MetaStation.dmm index 73c93475b17..3ca11454474 100644 --- a/_maps/map_files/MetaStation/MetaStation.dmm +++ b/_maps/map_files/MetaStation/MetaStation.dmm @@ -4947,9 +4947,7 @@ /turf/closed/wall, /area/station/medical/office) "bNf" = ( -/obj/structure/closet/secure_closet/bar{ - req_access = list("bar") - }, +/obj/structure/closet/secure_closet/bar, /obj/machinery/light/small/directional/west, /obj/machinery/light_switch/directional/north, /turf/open/floor/wood, @@ -36149,8 +36147,7 @@ "mUD" = ( /obj/structure/closet/secure_closet/bar{ pixel_x = -3; - pixel_y = -1; - req_access = list("bar") + pixel_y = -1 }, /obj/effect/decal/cleanable/dirt/dust, /obj/machinery/light_switch/directional/north, @@ -53309,9 +53306,7 @@ /obj/structure/cable, /obj/effect/mapping_helpers/airlock/access/any/service/maintenance, /obj/effect/mapping_helpers/airlock/access/any/service/library, -/obj/effect/mapping_helpers/airlock/unres{ - dir = 2 - }, +/obj/effect/mapping_helpers/airlock/unres, /turf/open/floor/plating, /area/station/maintenance/port) "sQB" = ( @@ -55887,6 +55882,12 @@ pixel_x = -3; pixel_y = 8 }, +/obj/item/mod/module/plasma_stabilizer{ + pixel_x = 16 + }, +/obj/item/mod/module/thermal_regulator{ + pixel_x = 16 + }, /turf/open/floor/iron/dark, /area/station/security/office) "tJV" = ( diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index e9e5a56c2d0..e526db4b138 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -13802,9 +13802,7 @@ /turf/open/floor/iron, /area/station/hallway/secondary/command) "eJo" = ( -/obj/structure/closet/secure_closet/bar{ - req_access = list("bar") - }, +/obj/structure/closet/secure_closet/bar, /obj/item/stack/spacecash/c100, /obj/item/stack/spacecash/c10, /turf/open/floor/wood, @@ -16801,8 +16799,7 @@ /area/station/science/xenobiology) "fOd" = ( /obj/machinery/door/airlock/hatch{ - name = "Ladder Access Hatch"; - req_one_access = null + name = "Ladder Access Hatch" }, /obj/structure/disposalpipe/segment{ dir = 4 @@ -18094,8 +18091,7 @@ /area/station/maintenance/starboard/greater) "glk" = ( /obj/machinery/door/airlock/hatch{ - name = "Ladder Access Hatch"; - req_one_access = null + name = "Ladder Access Hatch" }, /obj/structure/disposalpipe/segment{ dir = 4 @@ -23982,8 +23978,7 @@ /area/station/service/chapel/monastery) "ila" = ( /obj/machinery/door/airlock/hatch{ - name = "Ladder Access Hatch"; - req_one_access = null + name = "Ladder Access Hatch" }, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/effect/decal/cleanable/dirt, @@ -24569,8 +24564,7 @@ /area/station/science/research) "ivZ" = ( /obj/machinery/door/airlock/hatch{ - name = "Ladder Access Hatch"; - req_one_access = null + name = "Ladder Access Hatch" }, /obj/effect/decal/cleanable/dirt, /turf/open/floor/iron/smooth, @@ -28648,14 +28642,6 @@ }, /turf/open/floor/iron, /area/station/security/prison) -"jOF" = ( -/obj/machinery/door/airlock/hatch{ - name = "Ladder Access Hatch"; - req_one_access = null - }, -/obj/effect/decal/cleanable/dirt, -/turf/open/floor/iron/smooth, -/area/station/hallway/primary/tram/right) "jOM" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on/layer4{ dir = 4 @@ -50853,8 +50839,7 @@ dir = 8 }, /obj/machinery/door/airlock/hatch{ - name = "Ladder Access Hatch"; - req_one_access = null + name = "Ladder Access Hatch" }, /turf/open/floor/iron/smooth, /area/station/hallway/primary/tram/left) @@ -54316,8 +54301,7 @@ /area/station/cargo/storage) "srb" = ( /obj/machinery/door/airlock/hatch{ - name = "Ladder Access Hatch"; - req_one_access = null + name = "Ladder Access Hatch" }, /obj/structure/disposalpipe/segment{ dir = 4 @@ -68219,6 +68203,8 @@ /area/station/engineering/supermatter/room) "xfW" = ( /obj/structure/table, +/obj/item/mod/module/plasma_stabilizer, +/obj/item/mod/module/thermal_regulator, /turf/open/floor/iron, /area/station/security/office) "xgb" = ( @@ -183449,7 +183435,7 @@ vPB vrV pUv bMb -jOF +qDK bMb vUE vUE diff --git a/code/__DEFINES/dcs/signals/signals_proxmonitor.dm b/code/__DEFINES/dcs/signals/signals_proxmonitor.dm new file mode 100644 index 00000000000..2124c80ec54 --- /dev/null +++ b/code/__DEFINES/dcs/signals/signals_proxmonitor.dm @@ -0,0 +1,4 @@ +/// Called when a projectile dampener captures an object. +#define COMSIG_DAMPENER_CAPTURE "dampener_capture" +/// Called when a projectile dampener releases an object. +#define COMSIG_DAMPENER_RELEASE "dampener_release" diff --git a/code/datums/proximity_monitor/fields/peaceborg_dampener.dm b/code/datums/proximity_monitor/fields/projectile_dampener.dm similarity index 54% rename from code/datums/proximity_monitor/fields/peaceborg_dampener.dm rename to code/datums/proximity_monitor/fields/projectile_dampener.dm index 9d2549e89c2..c66c74b7795 100644 --- a/code/datums/proximity_monitor/fields/peaceborg_dampener.dm +++ b/code/datums/proximity_monitor/fields/projectile_dampener.dm @@ -1,7 +1,7 @@ //Projectile dampening field that slows projectiles and lowers their damage for an energy cost deducted every 1/5 second. //Only use square radius for this! -/datum/proximity_monitor/advanced/peaceborg_dampener +/datum/proximity_monitor/advanced/projectile_dampener var/static/image/edgeturf_south = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_south") var/static/image/edgeturf_north = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_north") var/static/image/edgeturf_west = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_west") @@ -11,43 +11,33 @@ var/static/image/northeast_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_northeast") var/static/image/southeast_corner = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_southeast") var/static/image/generic_edge = image('icons/effects/fields.dmi', icon_state = "projectile_dampen_generic") - var/obj/item/borg/projectile_dampen/projector = null var/list/obj/projectile/tracked = list() var/list/obj/projectile/staging = list() // lazylist that keeps track of the overlays added to the edge of the field var/list/edgeturf_effects -/datum/proximity_monitor/advanced/peaceborg_dampener/New(atom/_host, range, _ignore_if_not_on_turf = TRUE, obj/item/borg/projectile_dampen/projector) +/datum/proximity_monitor/advanced/projectile_dampener/New(atom/_host, range, _ignore_if_not_on_turf = TRUE, atom/projector) ..() - src.projector = projector + RegisterSignal(projector, COMSIG_PARENT_QDELETING, .proc/on_projector_del) recalculate_field() START_PROCESSING(SSfastprocess, src) -/datum/proximity_monitor/advanced/peaceborg_dampener/Destroy() - projector = null +/datum/proximity_monitor/advanced/projectile_dampener/Destroy() STOP_PROCESSING(SSfastprocess, src) + for(var/obj/projectile/projectile in tracked) + release_projectile(projectile) return ..() -/datum/proximity_monitor/advanced/peaceborg_dampener/process() - if(!istype(projector)) - qdel(src) - return +/datum/proximity_monitor/advanced/projectile_dampener/process() var/list/ranged = list() - for(var/obj/projectile/P in range(current_range, get_turf(host))) - ranged += P - for(var/obj/projectile/P in tracked) - if(!(P in ranged) || !P.loc) - release_projectile(P) - for(var/mob/living/silicon/robot/R in range(current_range, get_turf(host))) - if(R.has_buckled_mobs()) - for(var/mob/living/L in R.buckled_mobs) - L.visible_message(span_warning("[L] is knocked off of [R] by the charge in [R]'s chassis induced by the hyperkinetic dampener field!")) //I know it's bad. - L.Paralyze(10) - R.unbuckle_mob(L) - do_sparks(5, 0, L) + for(var/obj/projectile/projectile in range(current_range, get_turf(host))) + ranged += projectile + for(var/obj/projectile/projectile in tracked) + if(!(projectile in ranged) || !projectile.loc) + release_projectile(projectile) ..() -/datum/proximity_monitor/advanced/peaceborg_dampener/setup_edge_turf(turf/target) +/datum/proximity_monitor/advanced/projectile_dampener/setup_edge_turf(turf/target) . = ..() var/image/overlay = get_edgeturf_overlay(get_edgeturf_direction(target)) var/obj/effect/abstract/effect = new(target) // Makes the field visible to players. @@ -58,14 +48,14 @@ effect.plane = ABOVE_GAME_PLANE LAZYSET(edgeturf_effects, target, effect) -/datum/proximity_monitor/advanced/peaceborg_dampener/cleanup_edge_turf(turf/target) +/datum/proximity_monitor/advanced/projectile_dampener/cleanup_edge_turf(turf/target) . = ..() var/obj/effect/abstract/effect = LAZYACCESS(edgeturf_effects, target) LAZYREMOVE(edgeturf_effects, target) if(effect) qdel(effect) -/datum/proximity_monitor/advanced/peaceborg_dampener/proc/get_edgeturf_overlay(direction) +/datum/proximity_monitor/advanced/projectile_dampener/proc/get_edgeturf_overlay(direction) switch(direction) if(NORTH) return edgeturf_north @@ -86,24 +76,37 @@ else return generic_edge -/datum/proximity_monitor/advanced/peaceborg_dampener/proc/capture_projectile(obj/projectile/P, track_projectile = TRUE) - if(P in tracked) +/datum/proximity_monitor/advanced/projectile_dampener/proc/capture_projectile(obj/projectile/projectile) + if(projectile in tracked) return - projector.dampen_projectile(P, track_projectile) - if(track_projectile) - tracked += P + SEND_SIGNAL(src, COMSIG_DAMPENER_CAPTURE, projectile) + tracked += projectile -/datum/proximity_monitor/advanced/peaceborg_dampener/proc/release_projectile(obj/projectile/P) - projector.restore_projectile(P) - tracked -= P +/datum/proximity_monitor/advanced/projectile_dampener/proc/release_projectile(obj/projectile/projectile) + SEND_SIGNAL(src, COMSIG_DAMPENER_RELEASE, projectile) + tracked -= projectile -/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_uncrossed(atom/movable/movable, turf/location) +/datum/proximity_monitor/advanced/projectile_dampener/proc/on_projector_del(datum/source) + SIGNAL_HANDLER + + qdel(src) + +/datum/proximity_monitor/advanced/projectile_dampener/field_edge_uncrossed(atom/movable/movable, turf/location) if(istype(movable, /obj/projectile) && get_dist(movable, host) > current_range) if(movable in tracked) release_projectile(movable) - else - capture_projectile(movable, FALSE) -/datum/proximity_monitor/advanced/peaceborg_dampener/field_edge_crossed(atom/movable/movable, turf/location) +/datum/proximity_monitor/advanced/projectile_dampener/field_edge_crossed(atom/movable/movable, turf/location) if(istype(movable, /obj/projectile) && !(movable in tracked)) capture_projectile(movable) + +/datum/proximity_monitor/advanced/projectile_dampener/peaceborg/process(delta_time) + for(var/mob/living/silicon/robot/borg in range(current_range, get_turf(host))) + if(!borg.has_buckled_mobs()) + continue + for(var/mob/living/buckled_mob in borg.buckled_mobs) + buckled_mob.visible_message(span_warning("[buckled_mob] is knocked off of [borg] by the charge in [borg]'s chassis induced by the hyperkinetic dampener field!")) //I know it's bad. + buckled_mob.Paralyze(1 SECONDS) + borg.unbuckle_mob(buckled_mob) + do_sparks(5, 0, buckled_mob) + ..() diff --git a/code/game/objects/items/bodybag.dm b/code/game/objects/items/bodybag.dm index db784a5297c..f020c0c5033 100644 --- a/code/game/objects/items/bodybag.dm +++ b/code/game/objects/items/bodybag.dm @@ -20,11 +20,12 @@ deploy_bodybag(user, target) /obj/item/bodybag/proc/deploy_bodybag(mob/user, atom/location) - var/obj/structure/closet/body_bag/R = new unfoldedbag_path(location) - R.open(user) - R.add_fingerprint(user) - R.foldedbag_instance = src + var/obj/structure/closet/body_bag/item_bag = new unfoldedbag_path(location) + item_bag.open(user) + item_bag.add_fingerprint(user) + item_bag.foldedbag_instance = src moveToNullspace() + return item_bag /obj/item/bodybag/suicide_act(mob/user) if(isopenturf(user.loc)) @@ -62,15 +63,16 @@ return ..() /obj/item/bodybag/bluespace/deploy_bodybag(mob/user, atom/location) - var/obj/structure/closet/body_bag/R = new unfoldedbag_path(location) - for(var/atom/movable/A in contents) - A.forceMove(R) - if(isliving(A)) - to_chat(A, span_notice("You suddenly feel air around you! You're free!")) - R.open(user) - R.add_fingerprint(user) - R.foldedbag_instance = src + var/obj/structure/closet/body_bag/item_bag = new unfoldedbag_path(location) + for(var/atom/movable/inside in contents) + inside.forceMove(item_bag) + if(isliving(inside)) + to_chat(inside, span_notice("You suddenly feel air around you! You're free!")) + item_bag.open(user) + item_bag.add_fingerprint(user) + item_bag.foldedbag_instance = src moveToNullspace() + return item_bag /obj/item/bodybag/bluespace/container_resist_act(mob/living/user) if(user.incapacitated()) @@ -113,10 +115,14 @@ icon_state = "prisonerenvirobag_folded" unfoldedbag_path = /obj/structure/closet/body_bag/environmental/prisoner +/obj/item/bodybag/environmental/prisoner/pressurized + name = "pressurized prisoner transport bag" + unfoldedbag_path = /obj/structure/closet/body_bag/environmental/prisoner/pressurized + /obj/item/bodybag/environmental/prisoner/syndicate name = "syndicate prisoner transport bag" desc = "An alteration of Nanotrasen's environmental protection bag which has been used in several high-profile kidnappings. Designed to keep a victim unconscious, alive, and secured until they are transported to a required location." icon = 'icons/obj/bodybag.dmi' icon_state = "syndieenvirobag_folded" - unfoldedbag_path = /obj/structure/closet/body_bag/environmental/prisoner/syndicate + unfoldedbag_path = /obj/structure/closet/body_bag/environmental/prisoner/pressurized/syndicate resistance_flags = ACID_PROOF | FIRE_PROOF | FREEZE_PROOF | LAVA_PROOF diff --git a/code/game/objects/items/robot/items/tools.dm b/code/game/objects/items/robot/items/tools.dm index 1d68e1f5d7c..f4f436b8306 100644 --- a/code/game/objects/items/robot/items/tools.dm +++ b/code/game/objects/items/robot/items/tools.dm @@ -1,4 +1,4 @@ -#define PKBORG_DAMPEN_CYCLE_DELAY (2 SECONDS) +#define PKBORG_DAMPEN_CYCLE_DELAY 2 SECONDS /obj/item/cautery/prt //it's a subtype of cauteries so that it inherits the cautery sprites and behavior and stuff, because I'm too lazy to make sprites for this thing name = "plating repair tool" @@ -30,7 +30,7 @@ /// The owner of the dampener var/mob/living/silicon/robot/host = null /// The field - var/datum/proximity_monitor/advanced/peaceborg_dampener/dampening_field + var/datum/proximity_monitor/advanced/projectile_dampener/peaceborg/dampening_field var/projectile_damage_coefficient = 0.5 /// Energy cost per tracked projectile damage amount per second var/projectile_damage_tick_ecost_coefficient = 10 @@ -96,6 +96,8 @@ QDEL_NULL(dampening_field) var/mob/living/silicon/robot/owner = get_host() dampening_field = new(owner, field_radius, TRUE, src) + RegisterSignal(dampening_field, COMSIG_DAMPENER_CAPTURE, .proc/dampen_projectile) + RegisterSignal(dampening_field, COMSIG_DAMPENER_RELEASE, .proc/restore_projectile) owner?.model.allow_riding = FALSE active = TRUE @@ -158,11 +160,8 @@ host.cell.use(energy_recharge * delta_time * energy_recharge_cyborg_drain_coefficient) energy += energy_recharge * delta_time -/obj/item/borg/projectile_dampen/proc/dampen_projectile(obj/projectile/projectile, track_projectile = TRUE) - if(tracked[projectile]) - return - if(track_projectile) - tracked[projectile] = projectile.damage +/obj/item/borg/projectile_dampen/proc/dampen_projectile(obj/projectile/projectile) + tracked[projectile] = projectile.damage projectile.damage *= projectile_damage_coefficient projectile.speed *= projectile_speed_coefficient projectile.add_overlay(projectile_effect) diff --git a/code/game/objects/structures/crates_lockers/closets/bodybag.dm b/code/game/objects/structures/crates_lockers/closets/bodybag.dm index 6e0f50fbc55..76e390a75a2 100644 --- a/code/game/objects/structures/crates_lockers/closets/bodybag.dm +++ b/code/game/objects/structures/crates_lockers/closets/bodybag.dm @@ -166,7 +166,7 @@ mob_storage_capacity = 1 contents_pressure_protection = 0.8 contents_thermal_insulation = 0.5 - foldedbag_path = /obj/item/bodybag/environmental/ + foldedbag_path = /obj/item/bodybag/environmental var/list/weather_protection = list(TRAIT_ASHSTORM_IMMUNE, TRAIT_RADSTORM_IMMUNE, TRAIT_SNOWSTORM_IMMUNE, TRAIT_VOIDSTORM_IMMUNE) // Does not protect against lava or the The Floor Is Lava spell. /obj/structure/closet/body_bag/environmental/Initialize(mapload) @@ -181,7 +181,7 @@ icon_state = "ntenvirobag" contents_pressure_protection = 1 contents_thermal_insulation = 1 - foldedbag_path = /obj/item/bodybag/environmental/nanotrasen/ + foldedbag_path = /obj/item/bodybag/environmental/nanotrasen weather_protection = list(TRAIT_WEATHER_IMMUNE) /// Securable enviro. bags @@ -191,7 +191,7 @@ desc = "Intended for transport of prisoners through hazardous environments, this environmental protection bag comes with straps to keep an occupant secure." icon = 'icons/obj/bodybag.dmi' icon_state = "prisonerenvirobag" - foldedbag_path = /obj/item/bodybag/environmental/prisoner/ + foldedbag_path = /obj/item/bodybag/environmental/prisoner breakout_time = 4 MINUTES // because it's probably about as hard to get out of this as it is to get out of a straightjacket. /// How long it takes to sinch the bag. var/sinch_time = 10 SECONDS @@ -301,7 +301,55 @@ log_game("[key_name(user)] [sinched ? "sinched":"unsinched"] secure environmental bag [src] at [AREACOORD(src)]") update_appearance() -/obj/structure/closet/body_bag/environmental/prisoner/syndicate +/obj/structure/closet/body_bag/environmental/prisoner/pressurized + name = "pressurized prisoner transport bag" + foldedbag_path = /obj/item/bodybag/environmental/prisoner/pressurized + /// The contents of the gas to be distributed to an occupant once sinched down. Set in Initialize() + var/datum/gas_mixture/air_contents = null + +/obj/structure/closet/body_bag/environmental/prisoner/pressurized/Initialize(mapload) + . = ..() + refresh_air() + +/obj/structure/closet/body_bag/environmental/prisoner/pressurized/proc/refresh_air() + air_contents = null + air_contents = new(50) //liters + air_contents.temperature = T20C + + air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrogen) + air_contents.gases[/datum/gas/oxygen][MOLES] = (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD + air_contents.gases[/datum/gas/nitrogen][MOLES] = (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD + +/obj/structure/closet/body_bag/environmental/prisoner/pressurized/Destroy() + if(air_contents) + QDEL_NULL(air_contents) + return ..() + +/obj/structure/closet/body_bag/environmental/prisoner/pressurized/return_air() + if(sinched) + refresh_air() + return air_contents + return ..() + +/obj/structure/closet/body_bag/environmental/prisoner/pressurized/remove_air(amount) + if(sinched) + refresh_air() + return air_contents.remove(amount) // The internals for this bag are bottomless. + return ..(amount) + +/obj/structure/closet/body_bag/environmental/prisoner/pressurized/return_analyzable_air() + if(sinched) + refresh_air() + return air_contents + return ..() + +/obj/structure/closet/body_bag/environmental/prisoner/pressurized/togglelock(mob/living/user, silent) + . = ..() + if(sinched) + for(var/mob/living/target in contents) + to_chat(target, span_warning("You hear a faint hiss, and a white mist fills your vision...")) + +/obj/structure/closet/body_bag/environmental/prisoner/pressurized/syndicate name = "syndicate prisoner transport bag" desc = "An alteration of Nanotrasen's environmental protection bag which has been used in several high-profile kidnappings. Designed to keep a victim unconscious, alive, and secured during transport." icon = 'icons/obj/bodybag.dmi' @@ -312,14 +360,8 @@ weather_protection = list(TRAIT_WEATHER_IMMUNE) breakout_time = 8 MINUTES sinch_time = 20 SECONDS - // The contents of the gas to be distributed to an occupant once sinched down. Set in Initialize() - var/datum/gas_mixture/air_contents = null -/obj/structure/closet/body_bag/environmental/prisoner/syndicate/Initialize(mapload) - . = ..() - refresh_air() - -/obj/structure/closet/body_bag/environmental/prisoner/syndicate/proc/refresh_air() +/obj/structure/closet/body_bag/environmental/prisoner/pressurized/syndicate/refresh_air() air_contents = null air_contents = new(50) //liters air_contents.temperature = T20C @@ -327,33 +369,3 @@ air_contents.assert_gases(/datum/gas/oxygen, /datum/gas/nitrous_oxide) air_contents.gases[/datum/gas/oxygen][MOLES] = (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * O2STANDARD air_contents.gases[/datum/gas/nitrous_oxide][MOLES] = (ONE_ATMOSPHERE*50)/(R_IDEAL_GAS_EQUATION*T20C) * N2STANDARD - -/obj/structure/closet/body_bag/environmental/prisoner/syndicate/Destroy() - if(air_contents) - QDEL_NULL(air_contents) - - return ..() - -/obj/structure/closet/body_bag/environmental/prisoner/syndicate/return_air() - if(sinched) - refresh_air() - return air_contents - return ..() - -/obj/structure/closet/body_bag/environmental/prisoner/syndicate/remove_air(amount) - if(sinched) - refresh_air() - return air_contents.remove(amount) // The internals for this bag are bottomless. Syndicate bluespace trickery. - return ..(amount) - -/obj/structure/closet/body_bag/environmental/prisoner/syndicate/return_analyzable_air() - if(sinched) - refresh_air() - return air_contents - return ..() - -/obj/structure/closet/body_bag/environmental/prisoner/syndicate/togglelock(mob/living/user, silent) - . = ..() - if(sinched) - for(var/mob/living/target in contents) - to_chat(target, span_warning("You hear a faint hiss, and a white mist fills your vision...")) diff --git a/code/modules/mob/living/simple_animal/hostile/illusion.dm b/code/modules/mob/living/simple_animal/hostile/illusion.dm index 3d2bc4e9429..4d6c130437e 100644 --- a/code/modules/mob/living/simple_animal/hostile/illusion.dm +++ b/code/modules/mob/living/simple_animal/hostile/illusion.dm @@ -76,3 +76,11 @@ /mob/living/simple_animal/hostile/illusion/escape/AttackingTarget() return FALSE + +/mob/living/simple_animal/hostile/illusion/mirage + AIStatus = AI_OFF + density = FALSE + +/mob/living/simple_animal/hostile/illusion/mirage/death(gibbed) + do_sparks(rand(3, 6), FALSE, src) + return ..() diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm index 9e90120fc58..eddc7ab7f2a 100644 --- a/code/modules/mod/mod_theme.dm +++ b/code/modules/mod/mod_theme.dm @@ -615,8 +615,7 @@ leading to an overall lower capacity for modules." default_skin = "security" armor = list(MELEE = 15, BULLET = 15, LASER = 15, ENERGY = 15, BOMB = 25, BIO = 100, FIRE = 75, ACID = 75, WOUND = 15) - siemens_coefficient = 0 - complexity_max = DEFAULT_MAX_COMPLEXITY - 5 + complexity_max = DEFAULT_MAX_COMPLEXITY - 3 slowdown_inactive = 1 slowdown_active = 0.5 allowed_suit_storage = list( @@ -671,8 +670,6 @@ armor = list(MELEE = 15, BULLET = 15, LASER = 15, ENERGY = 15, BOMB = 40, BIO = 100, FIRE = 100, ACID = 95, WOUND = 15) resistance_flags = FIRE_PROOF max_heat_protection_temperature = FIRE_SUIT_MAX_TEMP_PROTECT - siemens_coefficient = 0 - complexity_max = DEFAULT_MAX_COMPLEXITY - 5 slowdown_inactive = 0.75 slowdown_active = 0.25 allowed_suit_storage = list( diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index e45ed1151ca..9bc81a1246d 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -109,6 +109,8 @@ /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/flashlight, /obj/item/mod/module/pepper_shoulders, + /obj/item/mod/module/criminalcapture, + /obj/item/mod/module/dispenser/mirage, ) /obj/item/mod/control/pre_equipped/safeguard @@ -119,6 +121,8 @@ /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/flashlight, /obj/item/mod/module/jetpack, + /obj/item/mod/module/megaphone, + /obj/item/mod/module/projectile_dampener, /obj/item/mod/module/pepper_shoulders, ) diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index fbcf26394e7..dbdfa805695 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -317,6 +317,7 @@ balloon_alert(mod.wearer, "[dispensed] dispensed") playsound(src, 'sound/machines/click.ogg', 100, TRUE) drain_power(use_power_cost) + return dispensed ///Longfall - Nullifies fall damage, removing charge instead. /obj/item/mod/module/longfall diff --git a/code/modules/mod/modules/modules_security.dm b/code/modules/mod/modules/modules_security.dm index 7edb6235d78..32376ec10d2 100644 --- a/code/modules/mod/modules/modules_security.dm +++ b/code/modules/mod/modules/modules_security.dm @@ -219,3 +219,196 @@ /obj/item/mod/module/holster/Destroy() QDEL_NULL(holstered) return ..() + +///Megaphone - Lets you speak loud. +/obj/item/mod/module/megaphone + name = "MOD megaphone module" + desc = "A microchip megaphone linked to a MODsuit, for very important purposes, like: loudness." + icon_state = "megaphone" + module_type = MODULE_TOGGLE + complexity = 1 + use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + incompatible_modules = list(/obj/item/mod/module/megaphone) + cooldown_time = 0.5 SECONDS + /// List of spans we add to the speaker. + var/list/voicespan = list(SPAN_COMMAND) + +/obj/item/mod/module/megaphone/on_activation() + . = ..() + if(!.) + return + RegisterSignal(mod.wearer, COMSIG_MOB_SAY, .proc/handle_speech) + +/obj/item/mod/module/megaphone/on_deactivation(display_message = TRUE, deleting = FALSE) + . = ..() + if(!.) + return + UnregisterSignal(mod.wearer, COMSIG_MOB_SAY) + +/obj/item/mod/module/megaphone/proc/handle_speech(datum/source, list/speech_args) + SIGNAL_HANDLER + + speech_args[SPEECH_SPANS] |= voicespan + drain_power(use_power_cost) + +///Criminal Capture - Lets you put people in transport bags. +/obj/item/mod/module/criminalcapture + name = "MOD criminal capture module" + desc = "The private security that had orders to take in people dead were quite \ + happy with their space-proofed suit, but for those who wanted to bring back \ + whomever their targets were still breathing needed a way to \"share\" the \ + space-proofing. And thus: criminal capture! Creates a prisoner transport bag \ + around the apprehended that has breathable atmos and even stabilizes critical \ + conditions." + icon_state = "criminalcapture" + module_type = MODULE_ACTIVE + complexity = 2 + use_power_cost = DEFAULT_CHARGE_DRAIN * 0.5 + incompatible_modules = list(/obj/item/mod/module/criminalcapture) + cooldown_time = 0.5 SECONDS + /// Max bag capacity. + var/max_capacity = 3 + /// Time to capture a prisoner. + var/capture_time = 1 SECONDS + /// Time to pack a bodybag up. + var/packup_time = 0.5 SECONDS + /// List of our capture bags. + var/list/criminal_capture_bags = list() + +/obj/item/mod/module/criminalcapture/Initialize(mapload) + . = ..() + for(var/i in 1 to max_capacity) + criminal_capture_bags += new /obj/structure/closet/body_bag/environmental/prisoner/pressurized(src) + +/obj/item/mod/module/criminalcapture/on_select_use(atom/target) + . = ..() + if(!.) + return + if(!mod.wearer.Adjacent(target)) + return + if(isliving(target)) + var/mob/living/living_target = target + var/turf/target_turf = get_turf(living_target) + playsound(src, 'sound/items/zip.ogg', 25, TRUE) + if(!do_after(mod.wearer, capture_time, target = living_target)) + balloon_alert(mod.wearer, "interrupted!") + return + var/obj/structure/closet/body_bag/environmental/prisoner/dropped_bag = pop(criminal_capture_bags) + dropped_bag.forceMove(target_turf) + dropped_bag.close() + living_target.forceMove(dropped_bag) + else if(istype(target, /obj/structure/closet/body_bag/environmental/prisoner) || istype(target, /obj/item/bodybag/environmental/prisoner)) + var/obj/item/bodybag/environmental/prisoner/bag = target + if(criminal_capture_bags.len >= max_capacity) + balloon_alert(mod.wearer, "bag limit reached!") + return + playsound(src, 'sound/items/zip.ogg', 25, TRUE) + if(!do_after(mod.wearer, packup_time, target = bag)) + balloon_alert(mod.wearer, "interrupted!") + return + if(criminal_capture_bags.len >= max_capacity) + balloon_alert(mod.wearer, "bag limit reached!") + return + if(locate(/mob/living) in bag) + balloon_alert(mod.wearer, "living creatures inside!") + return + if(istype(bag, /obj/item/bodybag/environmental/prisoner)) + bag = bag.deploy_bodybag(mod.wearer, get_turf(bag)) + var/obj/structure/closet/body_bag/environmental/prisoner/structure_bag = bag + if(!structure_bag.opened) + structure_bag.open(mod.wearer, force = TRUE) + bag.forceMove(src) + criminal_capture_bags += bag + balloon_alert(mod.wearer, "bag stored") + else + balloon_alert(mod.wearer, "invalid target!") + +///Mirage grenade dispenser - Dispenses grenades that copy the user's appearance. +/obj/item/mod/module/dispenser/mirage + name = "MOD mirage grenade dispenser module" + desc = "This module can create mirage grenades at the user's liking. These grenades create holographic copies of the user." + icon_state = "mirage_grenade" + cooldown_time = 20 SECONDS + overlay_state_inactive = "module_mirage_grenade" + dispense_type = /obj/item/grenade/mirage + +/obj/item/mod/module/dispenser/mirage/on_use() + . = ..() + if(!.) + return + var/obj/item/grenade/mirage/grenade = . + grenade.arm_grenade(mod.wearer) + +/obj/item/grenade/mirage + name = "mirage grenade" + desc = "A special device that, when activated, produces a holographic copy of the user." + icon_state = "mirage" + inhand_icon_state = "flashbang" + det_time = 3 SECONDS + /// Mob that threw the grenade. + var/mob/living/thrower + +/obj/item/grenade/mirage/arm_grenade(mob/user, delayoverride, msg, volume) + . = ..() + thrower = user + +/obj/item/grenade/mirage/detonate(mob/living/lanced_by) + . = ..() + do_sparks(rand(3, 6), FALSE, src) + if(thrower) + var/mob/living/simple_animal/hostile/illusion/mirage/mirage = new(get_turf(src)) + mirage.Copy_Parent(thrower, 15 SECONDS) + qdel(src) + +///Projectile Dampener - Weakens projectiles in range. +/obj/item/mod/module/projectile_dampener + name = "MOD projectile dampener module" + desc = "Using technology from peaceborgs, this module weakens all projectiles in nearby range." + icon_state = "projectile_dampener" + module_type = MODULE_TOGGLE + complexity = 3 + active_power_cost = DEFAULT_CHARGE_DRAIN + incompatible_modules = list(/obj/item/mod/module/projectile_dampener) + cooldown_time = 1.5 SECONDS + /// Radius of the dampening field. + var/field_radius = 2 + /// Damage multiplier on projectiles. + var/damage_multiplier = 0.75 + /// Speed multiplier on projectiles, higher means slower. + var/speed_multiplier = 2.5 + /// List of all tracked projectiles. + var/list/tracked_projectiles = list() + /// Effect image on projectiles. + var/image/projectile_effect + /// The dampening field + var/datum/proximity_monitor/advanced/projectile_dampener/dampening_field + +/obj/item/mod/module/projectile_dampener/Initialize(mapload) + . = ..() + projectile_effect = image('icons/effects/fields.dmi', "projectile_dampen_effect") + +/obj/item/mod/module/projectile_dampener/on_activation() + . = ..() + if(!.) + return + if(istype(dampening_field)) + QDEL_NULL(dampening_field) + dampening_field = new(mod.wearer, field_radius, TRUE, src) + RegisterSignal(dampening_field, COMSIG_DAMPENER_CAPTURE, .proc/dampen_projectile) + RegisterSignal(dampening_field, COMSIG_DAMPENER_RELEASE, .proc/release_projectile) + +/obj/item/mod/module/projectile_dampener/on_deactivation(display_message, deleting = FALSE) + . = ..() + if(!.) + return + QDEL_NULL(dampening_field) + +/obj/item/mod/module/projectile_dampener/proc/dampen_projectile(datum/source, obj/projectile/projectile) + projectile.damage *= damage_multiplier + projectile.speed *= speed_multiplier + projectile.add_overlay(projectile_effect) + +/obj/item/mod/module/projectile_dampener/proc/release_projectile(datum/source, obj/projectile/projectile) + projectile.damage /= damage_multiplier + projectile.speed /= speed_multiplier + projectile.cut_overlay(projectile_effect) diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index 5fbfd23cbc6..8054199f5ed 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -1068,6 +1068,7 @@ materials = list(/datum/material/iron = 6000, /datum/material/uranium = 2000, /datum/material/glass = 1000, /datum/material/plasma = 1000) departmental_flags = DEPARTMENT_BITFLAG_SECURITY research_icon_state = "security-plating" + build_type = PROTOLATHE /datum/design/mod_plating/cosmohonk id = "mod_plating_cosmohonk" diff --git a/icons/mob/clothing/modsuit/mod_modules.dmi b/icons/mob/clothing/modsuit/mod_modules.dmi index aaf9541d5b7..c61251221af 100644 Binary files a/icons/mob/clothing/modsuit/mod_modules.dmi and b/icons/mob/clothing/modsuit/mod_modules.dmi differ diff --git a/icons/obj/clothing/modsuit/mod_modules.dmi b/icons/obj/clothing/modsuit/mod_modules.dmi index e41fc164a2a..5840b69721c 100644 Binary files a/icons/obj/clothing/modsuit/mod_modules.dmi and b/icons/obj/clothing/modsuit/mod_modules.dmi differ diff --git a/icons/obj/grenade.dmi b/icons/obj/grenade.dmi index 209698c7133..8c4da6d43ed 100644 Binary files a/icons/obj/grenade.dmi and b/icons/obj/grenade.dmi differ diff --git a/tgstation.dme b/tgstation.dme index 22d60469960..495745da794 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -234,6 +234,7 @@ #include "code\__DEFINES\dcs\signals\signals_object.dm" #include "code\__DEFINES\dcs\signals\signals_operating_computer.dm" #include "code\__DEFINES\dcs\signals\signals_painting.dm" +#include "code\__DEFINES\dcs\signals\signals_proxmonitor.dm" #include "code\__DEFINES\dcs\signals\signals_radiation.dm" #include "code\__DEFINES\dcs\signals\signals_reagent.dm" #include "code\__DEFINES\dcs\signals\signals_restaurant.dm" @@ -1119,7 +1120,7 @@ #include "code\datums\proximity_monitor\field.dm" #include "code\datums\proximity_monitor\proximity_monitor.dm" #include "code\datums\proximity_monitor\fields\gravity.dm" -#include "code\datums\proximity_monitor\fields\peaceborg_dampener.dm" +#include "code\datums\proximity_monitor\fields\projectile_dampener.dm" #include "code\datums\proximity_monitor\fields\timestop.dm" #include "code\datums\quirks\_quirk.dm" #include "code\datums\quirks\good.dm"