diff --git a/_maps/RandomRuins/SpaceRuins/bus.dmm b/_maps/RandomRuins/SpaceRuins/bus.dmm index bb0156a4b7e52..1cd3d0f7ec261 100644 --- a/_maps/RandomRuins/SpaceRuins/bus.dmm +++ b/_maps/RandomRuins/SpaceRuins/bus.dmm @@ -19,7 +19,8 @@ "an" = ( /obj/structure/fluff/bus/passable/seat, /obj/item/toy/plush/pkplush{ - pixel_z = 17 + pixel_z = 17; + anchored = 1 }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" @@ -39,7 +40,8 @@ pixel_y = 15 }, /obj/item/toy/plush/lizard_plushie/green{ - pixel_z = 17 + pixel_z = 17; + anchored = 1 }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" @@ -49,7 +51,8 @@ /obj/structure/fluff/bus/passable/seat, /obj/effect/decal/cleanable/dirt, /obj/item/clothing/head/helmet/knight{ - pixel_z = 16 + pixel_z = 16; + anchored = 1 }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" @@ -60,11 +63,13 @@ /obj/item/grown/novaflower{ offset_at_init = 0; pixel_z = 24; - pixel_y = 1 + pixel_y = 1; + anchored = 1 }, /obj/item/food/grown/watermelon{ offset_at_init = 0; - pixel_z = 17 + pixel_z = 17; + anchored = 1 }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" @@ -75,15 +80,18 @@ /obj/effect/decal/cleanable/dirt, /obj/item/toy/plush/moth{ pixel_z = 26; - pixel_y = 2 + pixel_y = 2; + anchored = 1 }, /obj/item/food/grown/citrus/orange{ offset_at_init = 0; pixel_z = 18; - pixel_y = 1 + pixel_y = 1; + anchored = 1 }, /obj/item/toy/talking/ai{ - pixel_z = 16 + pixel_z = 16; + anchored = 1 }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" @@ -149,10 +157,12 @@ /obj/item/bodypart/arm/right{ pixel_z = 25; pixel_y = 1; - pixel_x = -4 + pixel_x = -4; + anchored = 1 }, /obj/item/food/meat/slab/penguin{ - pixel_z = 13 + pixel_z = 13; + anchored = 1 }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" @@ -188,12 +198,14 @@ /obj/item/food/grown/tomato{ offset_at_init = 0; pixel_z = 23; - pixel_y = 2 + pixel_y = 2; + anchored = 1 }, /obj/item/food/donut/plain{ pixel_z = 15; pixel_y = 1; - pixel_x = 1 + pixel_x = 1; + anchored = 1 }, /obj/effect/decal/cleanable/ants{ pixel_z = 8; @@ -291,7 +303,8 @@ /obj/effect/decal/cleanable/dirt, /obj/item/toy/plush/awakenedplushie{ pixel_z = 26; - pixel_y = 1 + pixel_y = 1; + anchored = 1 }, /obj/machinery/telecomms/server{ pixel_z = 12; @@ -384,11 +397,13 @@ /obj/item/toy/singlecard{ pixel_z = 24; pixel_y = 1; - pixel_x = 0 + pixel_x = 0; + anchored = 1 }, /obj/item/food/grown/potato{ offset_at_init = 0; - pixel_z = 15 + pixel_z = 15; + anchored = 1 }, /turf/open/floor/iron/dark/airless{ icon_state = "bus" diff --git a/_maps/map_files/Birdshot/birdshot.dmm b/_maps/map_files/Birdshot/birdshot.dmm index 3b567283936bd..e26e63400333f 100644 --- a/_maps/map_files/Birdshot/birdshot.dmm +++ b/_maps/map_files/Birdshot/birdshot.dmm @@ -22386,6 +22386,12 @@ }, /turf/open/floor/engine/co2, /area/station/engineering/atmos/space_catwalk) +"izw" = ( +/obj/machinery/transport/tram_controller/tcomms{ + configured_transport_id = "bird_2" + }, +/turf/open/floor/circuit, +/area/station/tcommsat/server) "izB" = ( /obj/effect/turf_decal/tile/neutral/fourcorners, /obj/structure/sign/painting/library{ @@ -40716,6 +40722,7 @@ /obj/machinery/atmospherics/pipe/smart/manifold4w/scrubbers/hidden/layer2, /obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4, /obj/structure/disposalpipe/segment, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, /turf/open/floor/catwalk_floor, /area/station/engineering/break_room) "oJn" = ( @@ -54321,13 +54328,14 @@ /turf/open/floor/iron, /area/station/hallway/primary/aft) "sKD" = ( -/obj/machinery/door/airlock/engineering{ - name = "Engine Airlock" - }, /obj/machinery/door/firedoor, /obj/effect/mapping_helpers/airlock/access/any/engineering/construction, /obj/structure/cable, /obj/effect/landmark/navigate_destination, +/obj/effect/mapping_helpers/airlock/access/any/engineering/general, +/obj/machinery/door/airlock/engineering{ + name = "Main Engineering" + }, /turf/open/floor/catwalk_floor, /area/station/engineering/break_room) "sKE" = ( @@ -58360,8 +58368,10 @@ /turf/open/floor/iron/dark, /area/station/medical/pharmacy) "tUD" = ( -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, +/obj/machinery/transport/tram_controller/tcomms{ + configured_transport_id = "bird_1" + }, +/turf/open/floor/circuit, /area/station/tcommsat/server) "tUH" = ( /obj/structure/disposalpipe/segment, @@ -121802,7 +121812,7 @@ wos udv tSq mvo -tUD +izw bFw ulK cdn diff --git a/_maps/map_files/tramstation/tramstation.dmm b/_maps/map_files/tramstation/tramstation.dmm index 229fd20cbcc5b..a1da07d798773 100644 --- a/_maps/map_files/tramstation/tramstation.dmm +++ b/_maps/map_files/tramstation/tramstation.dmm @@ -6765,7 +6765,10 @@ dir = 8 }, /obj/item/radio/intercom/directional/west, -/obj/item/paper/fluff/jobs/engineering/frequencies, +/obj/item/toy/plush/lizard_plushie/green{ + name = "Runs-The-Rails"; + desc = "An adorable, hard working lizard that runs in circles to keep the tram operating safely." + }, /turf/open/floor/iron, /area/station/tcommsat/computer) "boc" = ( @@ -26721,6 +26724,7 @@ }, /obj/item/folder/blue, /obj/item/pen/blue, +/obj/item/paper/fluff/jobs/engineering/frequencies, /turf/open/floor/iron, /area/station/tcommsat/computer) "iDQ" = ( @@ -61751,6 +61755,10 @@ "uGW" = ( /turf/closed/wall, /area/station/cargo/miningdock) +"uGX" = ( +/obj/machinery/transport/tram_controller/tcomms, +/turf/open/floor/iron/dark/telecomms, +/area/station/tcommsat/server) "uHb" = ( /obj/machinery/airalarm/directional/north, /obj/machinery/photocopier, @@ -98247,7 +98255,7 @@ dwR ngp dwR dwR -cXL +ney ney sMr sMr @@ -98505,7 +98513,7 @@ gga rBW ffN sMr -sMr +uGX drH ney tms @@ -98761,7 +98769,7 @@ ocK ngp dwR dwR -cXL +sMr sMr sMr sMr diff --git a/_maps/shuttles/ert_bounty.dmm b/_maps/shuttles/ert_bounty.dmm index 46c6f03f11691..03be12a36a771 100644 --- a/_maps/shuttles/ert_bounty.dmm +++ b/_maps/shuttles/ert_bounty.dmm @@ -21,14 +21,34 @@ shuttle_id = "huntership" }, /obj/structure/fans/tiny, -/turf/open/floor/plating, +/turf/open/floor/pod/dark, /area/shuttle/hunter) "d" = ( -/obj/structure/sign/warning/vacuum/external, -/turf/closed/wall/mineral/plastitanium, +/obj/structure/table, +/obj/item/tape{ + pixel_y = 17; + pixel_x = -12 + }, +/obj/item/reagent_containers/cup/glass/dry_ramen{ + pixel_x = 4; + pixel_y = -4 + }, +/turf/open/floor/pod/dark, /area/shuttle/hunter) "f" = ( /obj/structure/table, +/obj/structure/sign/poster/contraband/bountyhunters/directional/north, +/obj/item/storage/toolbox/mechanical{ + pixel_y = 8 + }, +/obj/item/reagent_containers/cup/glass/coffee{ + pixel_x = 9; + pixel_y = -3 + }, +/obj/effect/spawner/random/bureaucracy/pen{ + pixel_x = -6; + pixel_y = -7 + }, /turf/open/floor/pod/light, /area/shuttle/hunter) "h" = ( @@ -37,6 +57,7 @@ /area/shuttle/hunter) "i" = ( /obj/structure/tank_dispenser/oxygen, +/obj/effect/turf_decal/stripes/full, /turf/open/floor/pod/dark, /area/shuttle/hunter) "j" = ( @@ -44,11 +65,16 @@ /turf/open/floor/pod/dark, /area/shuttle/hunter) "k" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/structure/table/reinforced, +/obj/item/book/manual/wiki/security_space_law{ + pixel_y = 6; + pixel_x = -5 }, -/obj/machinery/light/floor, -/turf/open/floor/pod/dark, +/obj/item/grenade/chem_grenade/cleaner{ + pixel_x = 8; + pixel_y = 14 + }, +/turf/open/floor/pod/light, /area/shuttle/hunter) "l" = ( /obj/machinery/power/shuttle_engine/propulsion{ @@ -60,8 +86,9 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/light/small/directional/west, -/turf/open/floor/plating, +/obj/effect/mapping_helpers/airlock/cyclelink_helper, +/obj/machinery/door/airlock/external/ruin, +/turf/open/floor/pod/dark, /area/shuttle/hunter) "n" = ( /turf/closed/wall/mineral/plastitanium, @@ -70,7 +97,14 @@ /obj/effect/turf_decal/stripes/line{ dir = 1 }, -/turf/open/floor/plating, +/turf/open/floor/pod/dark, +/area/shuttle/hunter) +"q" = ( +/obj/structure/closet/crate/bin, +/obj/item/grenade/chem_grenade/glitter/pink, +/obj/item/trash/can, +/obj/item/cigbutt, +/turf/open/floor/pod/dark, /area/shuttle/hunter) "r" = ( /obj/structure/chair/office{ @@ -105,11 +139,11 @@ /turf/open/floor/plating/airless, /area/shuttle/hunter) "w" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper{ +/obj/effect/turf_decal/stripes/line{ dir = 1 }, -/obj/machinery/door/airlock/external/ruin, -/turf/open/floor/plating, +/obj/structure/sign/warning/vacuum/directional/west, +/turf/open/floor/pod/dark, /area/shuttle/hunter) "x" = ( /obj/structure/chair/office{ @@ -126,12 +160,15 @@ /turf/open/floor/pod/dark, /area/shuttle/hunter) "z" = ( -/obj/structure/sign/poster/contraband/bountyhunters, -/turf/closed/wall/mineral/plastitanium, +/obj/structure/table/reinforced, +/obj/item/storage/fancy/cigarettes/cigars/havana{ + pixel_y = 6 + }, +/turf/open/floor/pod/light, /area/shuttle/hunter) "A" = ( /obj/effect/turf_decal/stripes/line{ - dir = 9 + dir = 8 }, /turf/open/floor/pod/dark, /area/shuttle/hunter) @@ -141,21 +178,30 @@ /area/shuttle/hunter) "D" = ( /obj/machinery/power/smes, +/obj/effect/turf_decal/stripes/full, /turf/open/floor/pod/dark, /area/shuttle/hunter) "E" = ( /obj/structure/table, -/obj/item/phone, +/obj/item/food/donut/plain{ + pixel_y = -10; + pixel_x = -4 + }, +/obj/item/reagent_containers/cup/glass/dry_ramen{ + pixel_x = -4; + pixel_y = 15 + }, /turf/open/floor/pod/dark, /area/shuttle/hunter) "F" = ( /obj/effect/mapping_helpers/airlock/cyclelink_helper, /obj/machinery/door/airlock/external/ruin, /obj/structure/fans/tiny, -/turf/open/floor/plating, +/turf/open/floor/pod/dark, /area/shuttle/hunter) "G" = ( -/turf/open/floor/plating, +/obj/machinery/light/small/directional/west, +/turf/open/floor/pod/dark, /area/shuttle/hunter) "H" = ( /obj/machinery/computer/camera_advanced/shuttle_docker/syndicate/hunter{ @@ -172,8 +218,11 @@ /area/shuttle/hunter) "J" = ( /obj/effect/turf_decal/stripes/line, -/obj/machinery/light/small/directional/west, -/turf/open/floor/plating, +/obj/effect/mapping_helpers/airlock/cyclelink_helper{ + dir = 1 + }, +/obj/machinery/door/airlock/external/ruin, +/turf/open/floor/pod/dark, /area/shuttle/hunter) "K" = ( /obj/structure/chair/office{ @@ -198,24 +247,52 @@ /area/shuttle/hunter) "P" = ( /obj/structure/table, +/obj/item/toy/cards/deck{ + pixel_y = 3; + pixel_x = -3 + }, +/obj/item/multitool{ + pixel_x = 10; + pixel_y = 5 + }, /turf/open/floor/pod/dark, /area/shuttle/hunter) "Q" = ( -/obj/effect/mapping_helpers/airlock/cyclelink_helper, -/obj/machinery/door/airlock/external/ruin, -/turf/open/floor/plating, +/obj/effect/turf_decal/stripes/line, +/obj/structure/sign/warning/vacuum/directional/west, +/turf/open/floor/pod/dark, /area/shuttle/hunter) "R" = ( /obj/structure/table, /obj/item/binoculars, +/obj/item/reagent_containers/cup/glass/coffee{ + pixel_y = 16; + pixel_x = -7 + }, /turf/open/floor/pod/dark, /area/shuttle/hunter) "S" = ( +/obj/structure/table/reinforced, +/obj/item/paper{ + pixel_y = 2; + pixel_x = 2 + }, +/obj/item/paper{ + pixel_y = 5; + pixel_x = -4 + }, +/obj/item/stamp/centcom{ + pixel_x = 6; + pixel_y = 5 + }, +/obj/item/pen/fourcolor{ + pixel_x = -4 + }, /turf/open/floor/pod/light, /area/shuttle/hunter) "T" = ( /obj/effect/turf_decal/stripes/line, -/turf/open/floor/plating, +/turf/open/floor/pod/dark, /area/shuttle/hunter) "V" = ( /obj/machinery/computer/camera_advanced{ @@ -226,30 +303,40 @@ "X" = ( /obj/structure/rack, /obj/item/grenade/c4{ - pixel_x = -1; - pixel_y = 1 + pixel_x = -4; + pixel_y = 3 }, /obj/item/grenade/c4{ - pixel_x = -6; - pixel_y = 7 + pixel_x = 3; + pixel_y = 1 }, /obj/item/grenade/c4{ - pixel_x = 7; - pixel_y = -5 + pixel_x = 11; + pixel_y = -1 }, +/obj/effect/turf_decal/stripes/full, /turf/open/floor/pod/dark, /area/shuttle/hunter) "Y" = ( /obj/structure/table, -/obj/item/storage/toolbox/mechanical, /obj/machinery/light/small/directional/north, +/obj/item/phone{ + pixel_x = 8; + pixel_y = 7 + }, +/obj/item/cigbutt/cigarbutt{ + pixel_x = 7; + pixel_y = -10 + }, +/obj/item/paper_bin{ + pixel_x = -9; + pixel_y = 6 + }, /turf/open/floor/pod/light, /area/shuttle/hunter) "Z" = ( -/obj/effect/turf_decal/stripes/line{ - dir = 10 - }, -/turf/open/floor/pod/dark, +/obj/structure/bookcase/random/reference, +/turf/open/floor/pod/light, /area/shuttle/hunter) (1,1,1) = {" @@ -330,15 +417,15 @@ n (6,1,1) = {" n n -d n n -O -O -O +n +A +A +A +n n n -d n n "} @@ -348,9 +435,9 @@ p G J w -A -k -Z +O +B +O Q m G @@ -363,9 +450,9 @@ n h n n -j -j -j +q +O +O n n h @@ -391,7 +478,7 @@ a a a h -z +n f E P @@ -408,7 +495,7 @@ a a n Y -P +d R O t @@ -436,13 +523,13 @@ a a a a -h n -j -j +n +n +n j n -h +n a a a @@ -452,11 +539,11 @@ a a a h -S +Z O B O -S +k h a a @@ -471,7 +558,7 @@ S u I u -S +z h a a diff --git a/_maps/templates/small_shuttle_1.dmm b/_maps/templates/small_shuttle_1.dmm index a8a7ab9b7df7e..362d17d79ac25 100644 --- a/_maps/templates/small_shuttle_1.dmm +++ b/_maps/templates/small_shuttle_1.dmm @@ -22,7 +22,7 @@ /turf/open/floor/mineral/titanium/blue, /area/template_noop) "j" = ( -/obj/machinery/door/unpowered/shuttle, +/obj/machinery/door/airlock/titanium, /turf/open/floor/mineral/titanium/blue, /area/template_noop) "l" = ( diff --git a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm index bf6e68f127c71..cf6a5a12ef7cc 100644 --- a/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm +++ b/code/__DEFINES/dcs/signals/signals_mob/signals_mob_living.dm @@ -280,3 +280,5 @@ #define COMSIG_LIVING_THROW_MODE_TOGGLE "living_throw_mode_toggle" ///From /datum/component/happiness() #define COMSIG_MOB_HAPPINESS_CHANGE "happiness_change" +/// From /obj/item/melee/baton/baton_effect(): (datum/source, mob/living/user, /obj/item/melee/baton) +#define COMSIG_MOB_BATONED "mob_batoned" diff --git a/code/__DEFINES/projectiles.dm b/code/__DEFINES/projectiles.dm index ae61c5e50b7f0..ed4c66b799c59 100644 --- a/code/__DEFINES/projectiles.dm +++ b/code/__DEFINES/projectiles.dm @@ -53,13 +53,11 @@ /// The caliber used by the harpoon gun. #define CALIBER_HARPOON "harpoon" /// The caliber used by the rebar crossbow. -#define CALIBER_REBAR "sharpened iron rod" +#define CALIBER_REBAR "sharpened rod" /// The caliber used by the rebar crossbow when forced to hold 2 rods. -#define CALIBER_REBAR_FORCED "sharpened iron rod" +#define CALIBER_REBAR_FORCED "sharpened rod" /// The caliber used by the syndicate rebar crossbow. -#define CALIBER_REBAR_SYNDIE "jagged iron rod" -/// The caliber used by the syndicate rebar crossbow. -#define CALIBER_REBAR_SYNDIE_NORMAL "sharpened iron rod" +#define CALIBER_REBAR_SYNDIE "sharpened rod" /// The caliber used by the meat hook. #define CALIBER_HOOK "hook" /// The caliber used by the changeling tentacle mutation. diff --git a/code/controllers/subsystem/transport.dm b/code/controllers/subsystem/transport.dm index db8d19fa060a4..2f870eb674035 100644 --- a/code/controllers/subsystem/transport.dm +++ b/code/controllers/subsystem/transport.dm @@ -170,10 +170,6 @@ PROCESSING_SUBSYSTEM_DEF(transport) /datum/controller/subsystem/processing/transport/proc/pre_departure(datum/transport_controller/linear/tram/transport_controller, request_flags) log_transport("Sub: [transport_controller.specific_transport_id] start pre-departure. Info: [SUB_TS_STATUS]") - // Tram Malfunction event - if(transport_controller.controller_status & COMM_ERROR) - request_flags |= BYPASS_SENSORS - // Lock the physical controls of the tram transport_controller.set_status_code(PRE_DEPARTURE, TRUE) transport_controller.set_status_code(CONTROLS_LOCKED, TRUE) diff --git a/code/datums/brain_damage/phobia.dm b/code/datums/brain_damage/phobia.dm index cf97c2e6e855c..9394bc98f5790 100644 --- a/code/datums/brain_damage/phobia.dm +++ b/code/datums/brain_damage/phobia.dm @@ -10,6 +10,9 @@ /// Cooldown for freakouts to prevent permastunning. COOLDOWN_DECLARE(scare_cooldown) + ///What mood event to apply when we see the thing & freak out. + var/datum/mood_event/mood_event_type + var/regex/trigger_regex //instead of cycling every atom, only cycle the relevant types var/list/trigger_mobs @@ -34,6 +37,10 @@ trigger_species = GLOB.phobia_species[phobia_type] ..() +/datum/brain_trauma/mild/phobia/on_lose(silent) + owner.clear_mood_event("phobia_[phobia_type]") + return ..() + /datum/brain_trauma/mild/phobia/on_life(seconds_per_tick, times_fired) ..() if(HAS_TRAIT(owner, TRAIT_FEARLESS)) @@ -107,6 +114,8 @@ COOLDOWN_START(src, scare_cooldown, 12 SECONDS) if(owner.stat == DEAD) return + if(mood_event_type) + owner.add_mood_event("phobia_[phobia_type]", mood_event_type) var/message = pick("spooks you to the bone", "shakes you up", "terrifies you", "sends you into a panic", "sends chills down your spine") if(reason) to_chat(owner, span_userdanger("Seeing [span_phobia(reason.name)] [message]!")) @@ -193,6 +202,7 @@ /datum/brain_trauma/mild/phobia/heresy phobia_type = "heresy" + mood_event_type = /datum/mood_event/heresy random_gain = FALSE /datum/brain_trauma/mild/phobia/insects @@ -217,6 +227,7 @@ /datum/brain_trauma/mild/phobia/skeletons phobia_type = "skeletons" + mood_event_type = /datum/mood_event/spooked random_gain = FALSE /datum/brain_trauma/mild/phobia/snakes diff --git a/code/datums/components/crafting/equipment.dm b/code/datums/components/crafting/equipment.dm index e7971488d638f..7e7b7aca26f24 100644 --- a/code/datums/components/crafting/equipment.dm +++ b/code/datums/components/crafting/equipment.dm @@ -249,3 +249,14 @@ tool_paths = list(/obj/item/bikehorn) time = 40 SECONDS category = CAT_EQUIPMENT + +/datum/crafting_recipe/rebar_quiver + name = "Rebar Storage Quiver" + result = /obj/item/storage/bag/rebar_quiver + time = 10 + reqs = list( + /obj/item/tank/internals/oxygen = 1, + /obj/item/stack/cable_coil = 15, + ) + category = CAT_EQUIPMENT + tool_behaviors = list(TOOL_WELDER, TOOL_WIRECUTTER) diff --git a/code/datums/components/crafting/ranged_weapon.dm b/code/datums/components/crafting/ranged_weapon.dm index 88b721d3cb639..b646c4472ed98 100644 --- a/code/datums/components/crafting/ranged_weapon.dm +++ b/code/datums/components/crafting/ranged_weapon.dm @@ -225,7 +225,7 @@ /datum/crafting_recipe/rebarxbowforced name = "Forced Rebar Crossbow" - desc = "Get an extra shot in your crossbow... for a chance of shooting yourself when you fire it." + desc = "A much quicker reload... for a chance of shooting yourself when you fire it." result = /obj/item/gun/ballistic/rifle/rebarxbow/forced reqs = list( /obj/item/gun/ballistic/rifle/rebarxbow = 1, diff --git a/code/datums/components/crafting/weapon_ammo.dm b/code/datums/components/crafting/weapon_ammo.dm index 32f34f2ae751c..f68ff58072c67 100644 --- a/code/datums/components/crafting/weapon_ammo.dm +++ b/code/datums/components/crafting/weapon_ammo.dm @@ -12,6 +12,15 @@ time = 0.5 SECONDS category = CAT_WEAPON_AMMO +/datum/crafting_recipe/paperball + name = "Paper Ball" + result = /obj/item/ammo_casing/rebar/paperball + reqs = list( + /obj/item/paper = 1, + ) + time = 0.1 SECONDS + category = CAT_WEAPON_AMMO + /datum/crafting_recipe/rebarsyndie name = "jagged iron rod" result = /obj/item/ammo_casing/rebar/syndie @@ -19,10 +28,20 @@ /obj/item/stack/rods = 1, ) tool_behaviors = list(TOOL_WIRECUTTER) - time = 0.5 SECONDS + time = 0.1 SECONDS category = CAT_WEAPON_AMMO crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_MUST_BE_LEARNED +/datum/crafting_recipe/healium_bolt + name = "healium crystal crossbow bolt" + result = /obj/item/ammo_casing/rebar/healium + reqs = list( + /obj/item/grenade/gas_crystal/healium_crystal = 1 + ) + time = 0.1 SECONDS + category = CAT_WEAPON_AMMO + crafting_flags = CRAFT_CHECK_DENSITY + /datum/crafting_recipe/pulseslug name = "Pulse Slug Shell" result = /obj/item/ammo_casing/shotgun/pulseslug diff --git a/code/datums/components/fishing_spot.dm b/code/datums/components/fishing_spot.dm index fb20588f8c5a1..414c17b6d15e3 100644 --- a/code/datums/components/fishing_spot.dm +++ b/code/datums/components/fishing_spot.dm @@ -84,6 +84,8 @@ if(denial_reason) to_chat(user, span_warning(denial_reason)) return COMPONENT_NO_AFTERATTACK + // In case the fishing source has anything else to do before beginning to fish. + fish_source.on_start_fishing(rod, user, parent) start_fishing_challenge(rod, user) return COMPONENT_NO_AFTERATTACK diff --git a/code/datums/elements/spooky.dm b/code/datums/elements/spooky.dm index f80c98e2796af..30a04f6348b20 100644 --- a/code/datums/elements/spooky.dm +++ b/code/datums/elements/spooky.dm @@ -47,6 +47,8 @@ C.set_jitter_if_lower(30 SECONDS) C.set_stutter(40 SECONDS) + C.add_mood_event("spooked", /datum/mood_event/spooked) + /datum/element/spooky/proc/spectral_change(mob/living/carbon/human/H, mob/user) if((H.getStaminaLoss() > 95) && (!istype(H.dna.species, /datum/species/skeleton)) && (!istype(H.dna.species, /datum/species/golem)) && (!istype(H.dna.species, /datum/species/android)) && (!istype(H.dna.species, /datum/species/jelly))) H.Paralyze(20) @@ -63,12 +65,12 @@ new instrument(T) else to_chat(H, span_boldwarning("The spooky gods forgot to ship your instrument. Better luck next unlife.")) - to_chat(H, span_boldnotice("You are the spooky skeleton!")) + to_chat(H, span_boldnotice("You are a spooky skeleton!")) to_chat(H, span_boldnotice("A new life and identity has begun. Help your fellow skeletons into bringing out the spooky-pocalypse. You haven't forgotten your past life, and are still beholden to past loyalties.")) change_name(H) //time for a new name! /datum/element/spooky/proc/change_name(mob/living/carbon/human/spooked) - var/skeleton_name = sanitize_name(tgui_input_text(spooked, "Enter your new skeleton name", "Spookifier", spooked.real_name, MAX_NAME_LEN)) + var/skeleton_name = spooked.client ? sanitize_name(tgui_input_text(spooked, "Enter your new skeleton name", "Spookifier", spooked.real_name, MAX_NAME_LEN)) : null if(!skeleton_name) - skeleton_name = "spooky skeleton" + skeleton_name = "\improper spooky skeleton" spooked.fully_replace_character_name(null, skeleton_name) diff --git a/code/datums/mood_events/generic_negative_events.dm b/code/datums/mood_events/generic_negative_events.dm index e6cf8f2d3d80e..20a803434f40d 100644 --- a/code/datums/mood_events/generic_negative_events.dm +++ b/code/datums/mood_events/generic_negative_events.dm @@ -332,11 +332,16 @@ mood_change *= people_laughing_at_you return ..() -//These are unused so far but I want to remember them to use them later /datum/mood_event/surgery description = "THEY'RE CUTTING ME OPEN!!" mood_change = -8 +/datum/mood_event/surgery/success + timeout = 3 MINUTES + +/datum/mood_event/surgery/failure + timeout = 10 MINUTES + /datum/mood_event/bald description = "I need something to cover my head..." mood_change = -3 diff --git a/code/datums/quirks/negative_quirks/chronic_illness.dm b/code/datums/quirks/negative_quirks/chronic_illness.dm index 663d41381987e..f0809b55d2b0f 100644 --- a/code/datums/quirks/negative_quirks/chronic_illness.dm +++ b/code/datums/quirks/negative_quirks/chronic_illness.dm @@ -9,8 +9,10 @@ hardcore_value = 12 mail_goodies = list(/obj/item/storage/pill_bottle/sansufentanyl) -/datum/quirk/item_quirk/chronic_illness/add_unique(client/client_source) +/datum/quirk/item_quirk/chronic_illness/add(client/client_source) var/datum/disease/chronic_illness/hms = new /datum/disease/chronic_illness() quirk_holder.ForceContractDisease(hms) + +/datum/quirk/item_quirk/chronic_illness/add_unique(client/client_source) give_item_to_holder(/obj/item/storage/pill_bottle/sansufentanyl, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK),flavour_text = "You've been provided with medication to help manage your condition. Take it regularly to avoid complications.") give_item_to_holder(/obj/item/healthanalyzer/simple/disease, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK)) diff --git a/code/datums/quirks/negative_quirks/hemiplegic.dm b/code/datums/quirks/negative_quirks/hemiplegic.dm index b82ad434dfbe2..ac073d4ef8865 100644 --- a/code/datums/quirks/negative_quirks/hemiplegic.dm +++ b/code/datums/quirks/negative_quirks/hemiplegic.dm @@ -16,7 +16,7 @@ associated_typepath = /datum/quirk/hemiplegic customization_options = list(/datum/preference/choiced/hemiplegic) -/datum/quirk/hemiplegic/add_unique(client/client_source) +/datum/quirk/hemiplegic/add(client/client_source) var/datum/brain_trauma/severe/paralysis/hemiplegic/side_choice = GLOB.side_choice_hemiplegic[client_source?.prefs?.read_preference(/datum/preference/choiced/hemiplegic)] if(isnull(side_choice)) // Client gone or they chose a random side side_choice = GLOB.side_choice_hemiplegic[pick(GLOB.side_choice_hemiplegic)] diff --git a/code/datums/quirks/neutral_quirks/heretochromatic.dm b/code/datums/quirks/neutral_quirks/heretochromatic.dm index 194262952709c..311cbf66868f0 100644 --- a/code/datums/quirks/neutral_quirks/heretochromatic.dm +++ b/code/datums/quirks/neutral_quirks/heretochromatic.dm @@ -7,11 +7,7 @@ value = 0 mail_goodies = list(/obj/item/clothing/glasses/eyepatch) -// Only your first eyes are heterochromatic -// If someone comes and says "well mr coder you can have DNA bound heterochromia so it's not unrealistic -// to allow all inserted replacement eyes to become heterochromatic or for it to transfer between mobs" -// Then just change this to [proc/add] I really don't care -/datum/quirk/heterochromatic/add_unique(client/client_source) +/datum/quirk/heterochromatic/add(client/client_source) var/color = client_source?.prefs.read_preference(/datum/preference/color/heterochromatic) if(!color) return diff --git a/code/datums/quirks/positive_quirks/bilingual.dm b/code/datums/quirks/positive_quirks/bilingual.dm index 408a952cfe18a..20123dbe87afb 100644 --- a/code/datums/quirks/positive_quirks/bilingual.dm +++ b/code/datums/quirks/positive_quirks/bilingual.dm @@ -12,7 +12,7 @@ associated_typepath = /datum/quirk/bilingual customization_options = list(/datum/preference/choiced/language) -/datum/quirk/bilingual/add_unique(client/client_source) +/datum/quirk/bilingual/add(client/client_source) var/wanted_language = client_source?.prefs.read_preference(/datum/preference/choiced/language) var/datum/language/language_type if(wanted_language == "Random") diff --git a/code/datums/quirks/positive_quirks/settler.dm b/code/datums/quirks/positive_quirks/settler.dm index 81402c050cdd8..9b52403404b12 100644 --- a/code/datums/quirks/positive_quirks/settler.dm +++ b/code/datums/quirks/positive_quirks/settler.dm @@ -15,14 +15,16 @@ /obj/item/gps, ) -/datum/quirk/item_quirk/settler/add_unique(client/client_source) - give_item_to_holder(/obj/item/storage/box/papersack/wheat, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) - give_item_to_holder(/obj/item/storage/toolbox/fishing/small, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) +/datum/quirk/item_quirk/settler/add(client/client_source) var/mob/living/carbon/human/human_quirkholder = quirk_holder human_quirkholder.set_mob_height(HUMAN_HEIGHT_SHORTEST) human_quirkholder.add_movespeed_modifier(/datum/movespeed_modifier/settler) human_quirkholder.physiology.hunger_mod *= 0.5 //good for you, shortass, you don't get hungry nearly as often +/datum/quirk/item_quirk/settler/add_unique(client/client_source) + give_item_to_holder(/obj/item/storage/box/papersack/wheat, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) + give_item_to_holder(/obj/item/storage/toolbox/fishing/small, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS)) + /datum/quirk/item_quirk/settler/remove() if(QDELING(quirk_holder)) return diff --git a/code/datums/quirks/positive_quirks/signer.dm b/code/datums/quirks/positive_quirks/signer.dm index 8ff95d25e4a67..9e354ec71492f 100644 --- a/code/datums/quirks/positive_quirks/signer.dm +++ b/code/datums/quirks/positive_quirks/signer.dm @@ -7,8 +7,10 @@ medical_record_text = "Patient can communicate with sign language." mail_goodies = list(/obj/item/clothing/gloves/radio) -/datum/quirk/item_quirk/signer/add_unique(client/client_source) +/datum/quirk/item_quirk/signer/add(client/client_source) quirk_holder.AddComponent(/datum/component/sign_language) + +/datum/quirk/item_quirk/signer/add_unique(client/client_source) var/obj/item/clothing/gloves/gloves_type = /obj/item/clothing/gloves/radio if(isplasmaman(quirk_holder)) gloves_type = /obj/item/clothing/gloves/color/plasmaman/radio diff --git a/code/datums/quirks/positive_quirks/spacer.dm b/code/datums/quirks/positive_quirks/spacer.dm index 991c2001fbb08..4be27fe16b2e2 100644 --- a/code/datums/quirks/positive_quirks/spacer.dm +++ b/code/datums/quirks/positive_quirks/spacer.dm @@ -42,7 +42,6 @@ // Yes, it's assumed for planetary maps that you start at gravity sickness. check_z(quirk_holder, skip_timers = TRUE) -/datum/quirk/spacer_born/add_unique(client/client_source) // drift slightly faster through zero G quirk_holder.inertia_move_delay *= 0.8 diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm index d9263411f7b08..8a994350be856 100644 --- a/code/game/gamemodes/objective_items.dm +++ b/code/game/gamemodes/objective_items.dm @@ -243,8 +243,12 @@ difficulty = 3 steal_hint = "A self-defense weapon standard-issue for all heads of staffs barring the Head of Security. Rarely found off of their person." +/datum/objective_item/steal/traitor/telebaton/check_special_completion(obj/item/thing) + return thing.type == /obj/item/melee/baton/telescopic + /obj/item/melee/baton/telescopic/add_stealing_item_objective() - return add_item_to_steal(src, /obj/item/melee/baton/telescopic) + if(type == /obj/item/melee/baton/telescopic) + return add_item_to_steal(src, /obj/item/melee/baton/telescopic) /datum/objective_item/steal/traitor/cargo_budget name = "cargo's departmental budget" diff --git a/code/game/machinery/doors/unpowered.dm b/code/game/machinery/doors/unpowered.dm deleted file mode 100644 index 6a9fea4741921..0000000000000 --- a/code/game/machinery/doors/unpowered.dm +++ /dev/null @@ -1,25 +0,0 @@ -/obj/machinery/door/unpowered - -/obj/machinery/door/unpowered/Bumped(atom/movable/AM) - if(src.locked) - return - ..() - return - - -/obj/machinery/door/unpowered/attackby(obj/item/I, mob/user, params) - if(locked) - return - else - return ..() - -/obj/machinery/door/unpowered/emag_act(mob/user, obj/item/card/emag/emag_card) - return FALSE - -/obj/machinery/door/unpowered/shuttle - icon = 'icons/turf/shuttle.dmi' - name = "door" - icon_state = "door1" - opacity = TRUE - density = TRUE - explosion_block = 1 diff --git a/code/game/objects/items/broom.dm b/code/game/objects/items/broom.dm index 6b89ab7b7926e..4f7cb137d3009 100644 --- a/code/game/objects/items/broom.dm +++ b/code/game/objects/items/broom.dm @@ -68,13 +68,24 @@ * * user - The user of the pushbroom * * A - The atom which is located at the location to push atoms from */ -/obj/item/pushbroom/proc/sweep(mob/user, atom/A) +/obj/item/pushbroom/proc/sweep(mob/user, atom/atom) SIGNAL_HANDLER - var/turf/current_item_loc = isturf(A) ? A : A.loc + do_sweep(src, user, atom, user.dir) + +/** +* Sweep objects in the direction we're facing towards our direction +* Arguments +* * broomer - The object being used for brooming +* * user - The person who is brooming +* * target - The object or tile that's target of a broom click or being moved into +* * sweep_dir - The directions in which we sweep objects +*/ +/proc/do_sweep(obj/broomer, mob/user, atom/target, sweep_dir) + var/turf/current_item_loc = isturf(target) ? target : target.loc if (!isturf(current_item_loc)) return - var/turf/new_item_loc = get_step(current_item_loc, user.dir) + var/turf/new_item_loc = get_step(current_item_loc, sweep_dir) var/list/items_to_sweep = list() var/i = 1 @@ -86,16 +97,15 @@ if(i > BROOM_PUSH_LIMIT) break - SEND_SIGNAL(new_item_loc, COMSIG_TURF_RECEIVE_SWEEPED_ITEMS, src, user, items_to_sweep) + SEND_SIGNAL(new_item_loc, COMSIG_TURF_RECEIVE_SWEEPED_ITEMS, broomer, user, items_to_sweep) if(!length(items_to_sweep)) return for (var/obj/item/garbage in items_to_sweep) - garbage.Move(new_item_loc, user.dir) - - playsound(loc, 'sound/weapons/thudswoosh.ogg', 30, TRUE, -1) + garbage.Move(new_item_loc, sweep_dir) + playsound(current_item_loc, 'sound/weapons/thudswoosh.ogg', 30, TRUE, -1) /obj/item/pushbroom/cyborg name = "cyborg push broom" diff --git a/code/game/objects/items/granters/crafting/rebarxbowsyndie.dm b/code/game/objects/items/granters/crafting/rebarxbowsyndie.dm index fd38d4f4ccb20..04cee4e18a792 100644 --- a/code/game/objects/items/granters/crafting/rebarxbowsyndie.dm +++ b/code/game/objects/items/granters/crafting/rebarxbowsyndie.dm @@ -1,5 +1,5 @@ /obj/item/book/granter/crafting_recipe/dusting/rebarxbowsyndie_ammo - name = "SYNDICATE REBAR CROSSBOW OWNERS MANUAL" + name = "SYNDICATE REBAR CROSSBOW AMMO CRAFTING MANUAL" desc = "This book will self destruct upon being read a second time." crafting_recipe_types = list( /datum/crafting_recipe/rebarsyndie diff --git a/code/game/objects/items/handcuffs.dm b/code/game/objects/items/handcuffs.dm index 4ab568fdd4f96..ffcb5d1857cda 100644 --- a/code/game/objects/items/handcuffs.dm +++ b/code/game/objects/items/handcuffs.dm @@ -451,7 +451,7 @@ * Does not trigger on tiny mobs. * If ignore_movetypes is FALSE, does not trigger on floating / flying / etc. mobs. */ -/obj/item/restraints/legcuffs/beartrap/proc/spring_trap(atom/movable/target, ignore_movetypes = FALSE) +/obj/item/restraints/legcuffs/beartrap/proc/spring_trap(atom/movable/target, ignore_movetypes = FALSE, hit_prone = FALSE) if(!armed || !isturf(loc) || !isliving(target)) return @@ -477,7 +477,7 @@ victim.visible_message(span_danger("[victim] triggers \the [src]."), \ span_userdanger("You trigger \the [src]!")) var/def_zone = BODY_ZONE_CHEST - if(iscarbon(victim) && victim.body_position == STANDING_UP) + if(iscarbon(victim) && (victim.body_position == STANDING_UP || hit_prone)) var/mob/living/carbon/carbon_victim = victim def_zone = pick(BODY_ZONE_L_LEG, BODY_ZONE_R_LEG) if(!carbon_victim.legcuffed && carbon_victim.num_legs >= 2) //beartrap can't cuff your leg if there's already a beartrap or legcuffs, or you don't have two legs. @@ -595,7 +595,9 @@ /obj/item/restraints/legcuffs/bola/energy/ensnare(atom/hit_atom) var/obj/item/restraints/legcuffs/beartrap/energy/cyborg/B = new (get_turf(hit_atom)) - B.spring_trap(hit_atom, ignore_movetypes = TRUE) + B.spring_trap(hit_atom, ignore_movetypes = TRUE, hit_prone = TRUE) + if(B.loc != hit_atom) + qdel(B) qdel(src) /** diff --git a/code/game/objects/items/melee/baton.dm b/code/game/objects/items/melee/baton.dm index b576ef5d41c33..112c527ec28a9 100644 --- a/code/game/objects/items/melee/baton.dm +++ b/code/game/objects/items/melee/baton.dm @@ -212,6 +212,7 @@ if(!trait_check) target.Knockdown((isnull(stun_override) ? knockdown_time : stun_override)) additional_effects_non_cyborg(target, user) + SEND_SIGNAL(target, COMSIG_MOB_BATONED, user, src) return TRUE /// Description for trying to stun when still on cooldown. diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index b4c12d75a30c3..2d886163a50ba 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -57,7 +57,7 @@ // Handles adding items with the module /obj/item/borg/upgrade/proc/install_items(mob/living/silicon/robot/borg, mob/living/user = usr, list/items) for(var/item_to_add in items) - var/obj/item/module_item = new item_to_add(borg.model.modules) + var/obj/item/module_item = new item_to_add(borg.model) borg.model.basic_modules += module_item borg.model.add_module(module_item, FALSE, TRUE) return TRUE @@ -756,9 +756,11 @@ desc = "An upgrade to the service model cyborg, to help provide mobile service." icon_state = "cyborg_upgrade3" require_model = TRUE - model_type = list(/obj/item/rolling_table_dock) + model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE + items_to_add = list(/obj/item/rolling_table_dock) + /obj/item/borg/upgrade/service_cookbook name = "Service Cyborg Cookbook" desc = "An upgrade to the service model cyborg, that lets them create more foods." @@ -767,7 +769,7 @@ model_type = list(/obj/item/robot_model/service) model_flags = BORG_MODEL_SERVICE - model_type = list(/obj/item/borg/cookbook) + items_to_add = list(/obj/item/borg/cookbook) ///This isn't an upgrade or part of the same path, but I'm gonna just stick it here because it's a tool used on cyborgs. //A reusable tool that can bring borgs back to life. They gotta be repaired first, though. diff --git a/code/game/objects/items/stacks/sheets/mineral.dm b/code/game/objects/items/stacks/sheets/mineral.dm index f6e7d797fd95c..4e4e1db1f9a1e 100644 --- a/code/game/objects/items/stacks/sheets/mineral.dm +++ b/code/game/objects/items/stacks/sheets/mineral.dm @@ -282,8 +282,9 @@ GLOBAL_LIST_INIT(bananium_recipes, list ( \ walltype = /turf/closed/wall/mineral/titanium GLOBAL_LIST_INIT(titanium_recipes, list ( \ - new/datum/stack_recipe("Titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20, crafting_flags = NONE, category = CAT_TILES), \ - new/datum/stack_recipe("Shuttle seat", /obj/structure/chair/comfy/shuttle, 2, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_FURNITURE), \ + new /datum/stack_recipe("Titanium tile", /obj/item/stack/tile/mineral/titanium, 1, 4, 20, crafting_flags = NONE, category = CAT_TILES), \ + new /datum/stack_recipe("Shuttle seat", /obj/structure/chair/comfy/shuttle, 2, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_FURNITURE), \ + new /datum/stack_recipe("Material tram door assembly", /obj/structure/door_assembly/multi_tile/door_assembly_tram, 8, time = 5 SECONDS, crafting_flags = CRAFT_CHECK_DENSITY | CRAFT_ONE_PER_TURF | CRAFT_ON_SOLID_GROUND, category = CAT_DOORS), \ )) /obj/item/stack/sheet/mineral/titanium/get_main_recipes() @@ -473,6 +474,7 @@ GLOBAL_LIST_INIT(metalhydrogen_recipes, list( new /datum/stack_recipe("ancient armor", /obj/item/clothing/suit/armor/elder_atmosian, req_amount = 5, res_amount = 1, crafting_flags = NONE, category = CAT_CLOTHING), new /datum/stack_recipe("ancient helmet", /obj/item/clothing/head/helmet/elder_atmosian, req_amount = 3, res_amount = 1, crafting_flags = NONE, category = CAT_CLOTHING), new /datum/stack_recipe("metallic hydrogen axe", /obj/item/fireaxe/metal_h2_axe, req_amount = 15, res_amount = 1, crafting_flags = NONE, category = CAT_WEAPON_MELEE), + new /datum/stack_recipe("metallic hydrogen bolts", /obj/item/ammo_casing/rebar/hydrogen, req_amount = 1, res_amount = 1, crafting_flags = NONE, category = CAT_WEAPON_AMMO), )) /obj/item/stack/sheet/mineral/metal_hydrogen @@ -491,6 +493,12 @@ GLOBAL_LIST_INIT(metalhydrogen_recipes, list( . = ..() . += GLOB.metalhydrogen_recipes + + +GLOBAL_LIST_INIT(zaukerite_recipes, list( + new /datum/stack_recipe("zaukerite shard", /obj/item/ammo_casing/rebar/zaukerite, req_amount=1, res_amount=1, category = CAT_WEAPON_AMMO), + )) + /obj/item/stack/sheet/mineral/zaukerite name = "zaukerite" icon_state = "zaukerite" @@ -501,3 +509,7 @@ GLOBAL_LIST_INIT(metalhydrogen_recipes, list( mats_per_unit = list(/datum/material/zaukerite = SHEET_MATERIAL_AMOUNT) merge_type = /obj/item/stack/sheet/mineral/zaukerite material_type = /datum/material/zaukerite + +/obj/item/stack/sheet/mineral/zaukerite/get_main_recipes() + . = ..() + . += GLOB.zaukerite_recipes diff --git a/code/game/objects/items/storage/bags.dm b/code/game/objects/items/storage/bags.dm index 9af23545c6f0f..28caa290a9cc1 100644 --- a/code/game/objects/items/storage/bags.dm +++ b/code/game/objects/items/storage/bags.dm @@ -573,4 +573,28 @@ for(var/i in 1 to 40) new /obj/item/ammo_casing/harpoon(src) +/obj/item/storage/bag/rebar_quiver + name = "Rebar Storage Quiver" + icon = 'icons/obj/weapons/bows/quivers.dmi' + icon_state = "rebar_quiver" + worn_icon_state = "rebar_quiver" + inhand_icon_state = "rebar_quiver" + desc = "A oxygen tank cut in half, used for holding sharpened rods for the rebar crossbow." + slot_flags = ITEM_SLOT_BACK|ITEM_SLOT_SUITSTORE + resistance_flags = FLAMMABLE + +/obj/item/storage/bag/rebar_quiver/Initialize(mapload) + . = ..() + atom_storage.max_specific_storage = WEIGHT_CLASS_TINY + atom_storage.max_slots = 10 + atom_storage.max_total_storage = 15 + atom_storage.set_holdable(list( + /obj/item/ammo_casing/rebar, + /obj/item/ammo_casing/rebar/syndie, + /obj/item/ammo_casing/rebar/healium, + /obj/item/ammo_casing/rebar/hydrogen, + /obj/item/ammo_casing/rebar/zaukerite, + /obj/item/ammo_casing/rebar/paperball, + )) + #undef ORE_BAG_BALOON_COOLDOWN diff --git a/code/game/objects/items/storage/uplink_kits.dm b/code/game/objects/items/storage/uplink_kits.dm index 7bd009016148e..3a4ce82d85e51 100644 --- a/code/game/objects/items/storage/uplink_kits.dm +++ b/code/game/objects/items/storage/uplink_kits.dm @@ -341,7 +341,7 @@ /obj/item/storage/box/syndie_kit/rebarxbowsyndie name = "Boxed Rebar Crossbow" - desc = "Now features instruction manual for making ammo." + desc = "A scoped weapon with low armor penetration, but devestating against flesh. Features instruction manual for making specialty ammo." /obj/item/storage/box/syndie_kit/rebarxbowsyndie/PopulateContents() new /obj/item/book/granter/crafting_recipe/dusting/rebarxbowsyndie_ammo(src) diff --git a/code/game/objects/structures/door_assembly.dm b/code/game/objects/structures/door_assembly.dm index 5daf96a01b884..86d8e01f98ebe 100644 --- a/code/game/objects/structures/door_assembly.dm +++ b/code/game/objects/structures/door_assembly.dm @@ -44,6 +44,7 @@ multi_tile = TRUE glass = TRUE nomineral = TRUE + material_amt = 8 /obj/structure/door_assembly/Initialize(mapload) . = ..() diff --git a/code/game/objects/structures/door_assembly_types.dm b/code/game/objects/structures/door_assembly_types.dm index dd06f7e42a9a4..d62fb1bec7676 100644 --- a/code/game/objects/structures/door_assembly_types.dm +++ b/code/game/objects/structures/door_assembly_types.dm @@ -271,6 +271,18 @@ name = "large public airlock assembly" base_name = "large public airlock" +/obj/structure/door_assembly/multi_tile/door_assembly_tram + name = "tram door assembly" + icon = 'icons/obj/doors/airlocks/tram/tram.dmi' + base_name = "tram door" + overlays_file = 'icons/obj/doors/airlocks/tram/tram-overlays.dmi' + glass_type = /obj/machinery/door/airlock/tram + airlock_type = /obj/machinery/door/airlock/tram + glass = FALSE + noglass = TRUE + mineral = "titanium" + material_type = /obj/item/stack/sheet/mineral/titanium + /obj/structure/door_assembly/door_assembly_material/atom_deconstruct(disassembled = TRUE) var/turf/target_turf = get_turf(src) for(var/datum/material/material_datum as anything in custom_materials) diff --git a/code/modules/antagonists/changeling/changeling.dm b/code/modules/antagonists/changeling/changeling.dm index 8d1068baa1368..f8e679352bf78 100644 --- a/code/modules/antagonists/changeling/changeling.dm +++ b/code/modules/antagonists/changeling/changeling.dm @@ -260,6 +260,10 @@ */ /datum/antagonist/changeling/proc/on_life(datum/source, seconds_per_tick, times_fired) SIGNAL_HANDLER + if(isliving(owner.current)) + var/mob/living/living_owner = owner.current + if(living_owner.fire_stacks && living_owner.on_fire) + return // No chemical regen while on fire. var/delta_time = DELTA_WORLD_TIME(SSmobs) diff --git a/code/modules/antagonists/changeling/changeling_power.dm b/code/modules/antagonists/changeling/changeling_power.dm index 23b4f9548c424..d5152772e51c5 100644 --- a/code/modules/antagonists/changeling/changeling_power.dm +++ b/code/modules/antagonists/changeling/changeling_power.dm @@ -81,6 +81,10 @@ the same goes for Remove(). if you override Remove(), call parent or else your p /datum/action/changeling/proc/can_sting(mob/living/user, mob/living/target) if(!can_be_used_by(user)) return FALSE + if(user.fire_stacks && user.on_fire) + user.balloon_alert(user, "on fire!") + to_chat(user, span_boldwarning("WE CANNOT DO THIS WHILE ENGULFED IN FLAMES!!! PUT OUT THE FIRE FIRST!!!")) + return FALSE var/datum/antagonist/changeling/changeling = IS_CHANGELING(user) if(changeling.chem_charges < chemical_cost) user.balloon_alert(user, "needs [chemical_cost] chemicals!") diff --git a/code/modules/antagonists/changeling/powers/mutations.dm b/code/modules/antagonists/changeling/powers/mutations.dm index d82ec1d131897..167c1c697cdc2 100644 --- a/code/modules/antagonists/changeling/powers/mutations.dm +++ b/code/modules/antagonists/changeling/powers/mutations.dm @@ -173,15 +173,24 @@ \***************************************/ /datum/action/changeling/weapon/arm_blade name = "Arm Blade" - desc = "We reform one of our arms into a deadly blade. Costs 20 chemicals." - helptext = "We may retract our armblade in the same manner as we form it. Cannot be used while in lesser form." + desc = "We reform one of our arms into a deadly blade that breaks after a number of hits, improvable by absorbing genomes. Costs 40 chemicals." + helptext = "We may retract our armblade in the same manner as we form it. Organic tissue is not perfect; the armblade will break after it is used too much. The more genomes we absorb, the stronger it is. Cannot be used while in lesser form." button_icon_state = "armblade" - chemical_cost = 20 - dna_cost = 2 + chemical_cost = 30 + dna_cost = 3 req_human = TRUE weapon_type = /obj/item/melee/arm_blade weapon_name_simple = "blade" +/datum/action/changeling/weapon/arm_blade/sting_action(mob/living/carbon/user) + var/datum/antagonist/changeling/changeling = IS_CHANGELING(user) //So we can read the absorbed_count. + if(!changeling) + return + + var/obj/item/melee/arm_blade/blade = ..() + blade.remaining_uses = round(changeling.absorbed_count * 3) + return TRUE + /obj/item/melee/arm_blade name = "arm blade" desc = "A grotesque blade made out of bone and flesh that cleaves through people as a hot knife through butter." @@ -203,8 +212,10 @@ wound_bonus = 10 bare_wound_bonus = 10 armour_penetration = 35 + resistance_flags = FLAMMABLE var/can_drop = FALSE var/fake = FALSE + var/remaining_uses /obj/item/melee/arm_blade/Initialize(mapload,silent,synthetic) . = ..() @@ -250,6 +261,15 @@ span_hear("You hear a metal screeching sound.")) opening.open(BYPASS_DOOR_CHECKS) + if(remaining_uses <= 1) + if(ishuman(loc)) + var/mob/living/carbon/human/changeling = loc + changeling.visible_message(span_warning("With a sickening crunch, [changeling] reforms [changeling.p_their()] [src] into an arm!"), span_notice("We assimilate our armblade into our body."), "You hear organic matter ripping and tearing!") + qdel(src) + else + remaining_uses-- + + /obj/item/melee/arm_blade/dropped(mob/user) ..() if(can_drop) @@ -297,6 +317,7 @@ throw_range = 0 throw_speed = 0 can_hold_up = FALSE + resistance_flags = FLAMMABLE /obj/item/gun/magic/tentacle/Initialize(mapload, silent) . = ..() @@ -493,6 +514,9 @@ S.remaining_uses = round(changeling.absorbed_count * 3) return TRUE +/datum/armor/item_shield/changeling + fire = -100 + /obj/item/shield/changeling name = "shield-like mass" desc = "A mass of tough, boney tissue. You can still see the fingers as a twisted pattern in the shield." @@ -502,6 +526,8 @@ lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi' righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi' block_chance = 50 + armor_type = /datum/armor/item_shield/changeling + resistance_flags = FLAMMABLE var/remaining_uses //Set by the changeling ability. @@ -512,7 +538,7 @@ loc.visible_message(span_warning("The end of [loc.name]\'s hand inflates rapidly, forming a huge shield-like mass!"), span_warning("We inflate our hand into a strong shield."), span_hear("You hear organic matter ripping and tearing!")) /obj/item/shield/changeling/hit_reaction(mob/living/carbon/human/owner, atom/movable/hitby, attack_text = "the attack", final_block_chance = 0, damage = 0, attack_type = MELEE_ATTACK, damage_type = BRUTE) - if(remaining_uses < 1) + if(remaining_uses <= 1) if(ishuman(loc)) var/mob/living/carbon/human/H = loc H.visible_message(span_warning("With a sickening crunch, [H] reforms [H.p_their()] shield into an arm!"), span_notice("We assimilate our shield into our body"), "= world.time) + return + can_move = world.time + move_delay + + // ESCAPE PRISON + if(ismovable(loc) && prob(25)) + var/obj/item/item = pick(loc.contents) + if(istype(loc, /obj/item/storage)) + item.forceMove(loc.drop_location()) //throw stuff out of the inventory till we free ourselves! + playsound(src, SFX_RUSTLE, 30, TRUE) + return + + // MOVE US + if(isturf(loc)) + can_move = world.time + move_delay + try_step_multiz(direction) + SpinAnimation(move_delay, 1, direction == NORTH || direction == EAST) + +/obj/item/mmi/posibrain/sphere/Moved(atom/old_loc, movement_dir, forced, list/old_locs, momentum_change) + . = ..() + if(brainmob && isturf(loc)) + anchored = TRUE //anchor so we dont broom ourselves. + do_sweep(src, brainmob, loc, get_dir(old_loc, loc)) //movement dir doesnt work on objects + anchored = FALSE + +/// Punt the shit across the room +/obj/item/mmi/posibrain/sphere/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return . + throw_at(get_edge_target_turf(src, get_dir(user, src)), 7, 1, user) + user.do_attack_animation(src) + can_move = world.time + move_delay //pweeze stawp + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 6e1f9037018b6..2432888cce65d 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -796,6 +796,9 @@ if(leg_clothes) burning_items |= leg_clothes + for(var/obj/item/burnable_item in held_items) + burning_items |= burnable_item + for(var/obj/item/burning in burning_items) burning.fire_act((stacks * 25 * seconds_per_tick)) //damage taken is reduced to 2% of this value by fire_act() diff --git a/code/modules/mod/mod_types.dm b/code/modules/mod/mod_types.dm index 8843a811756d7..539237fa3e801 100644 --- a/code/modules/mod/mod_types.dm +++ b/code/modules/mod/mod_types.dm @@ -221,6 +221,7 @@ applied_cell = /obj/item/stock_parts/cell/super applied_modules = list( /obj/item/mod/module/storage/syndicate, + /obj/item/mod/module/shock_absorber, /obj/item/mod/module/emp_shield, /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/jetpack, @@ -241,6 +242,7 @@ applied_cell = /obj/item/stock_parts/cell/bluespace applied_modules = list( /obj/item/mod/module/storage/syndicate, + /obj/item/mod/module/shock_absorber, /obj/item/mod/module/emp_shield, /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/jetpack/advanced, @@ -263,6 +265,7 @@ req_access = list(ACCESS_SYNDICATE) applied_modules = list( /obj/item/mod/module/storage/syndicate, + /obj/item/mod/module/shock_absorber, /obj/item/mod/module/emp_shield, /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/jetpack/advanced, @@ -299,6 +302,7 @@ req_access = list(ACCESS_SYNDICATE) applied_modules = list( /obj/item/mod/module/storage/syndicate, + /obj/item/mod/module/shock_absorber, /obj/item/mod/module/emp_shield, /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/jetpack/advanced, @@ -316,6 +320,7 @@ /obj/item/mod/control/pre_equipped/elite/flamethrower applied_modules = list( /obj/item/mod/module/storage/syndicate, + /obj/item/mod/module/shock_absorber, /obj/item/mod/module/emp_shield, /obj/item/mod/module/magnetic_harness, /obj/item/mod/module/thermal_regulator, diff --git a/code/modules/mod/modules/modules_general.dm b/code/modules/mod/modules/modules_general.dm index 87cab74b24f76..3ef6b9558712a 100644 --- a/code/modules/mod/modules/modules_general.dm +++ b/code/modules/mod/modules/modules_general.dm @@ -979,3 +979,29 @@ attempt_insert_storage(product) balloon_alert(mod.wearer, "ammo box dispensed.") playsound(src, 'sound/machines/microwave/microwave-end.ogg', 50, TRUE) + +/obj/item/mod/module/shock_absorber + name = "MOD shock absorption module" + desc = "A module that makes the user resistant to the knockdown inflicted by Stun Batons." + icon_state = "no_baton" + complexity = 1 + use_energy_cost = DEFAULT_CHARGE_DRAIN + incompatible_modules = list(/obj/item/mod/module/shock_absorber) + required_slots = list(ITEM_SLOT_BACK|ITEM_SLOT_BELT) + +/obj/item/mod/module/shock_absorber/on_suit_activation() + . = ..() + ADD_TRAIT(mod.wearer, TRAIT_BATON_RESISTANCE, REF(src)) + RegisterSignal(mod.wearer, COMSIG_MOB_BATONED, PROC_REF(mob_batoned)) + +/obj/item/mod/module/shock_absorber/on_suit_deactivation(deleting) + . = ..() + REMOVE_TRAIT(mod.wearer, TRAIT_BATON_RESISTANCE, REF(src)) + UnregisterSignal(mod.wearer, COMSIG_MOB_BATONED) + +/obj/item/mod/module/shock_absorber/proc/mob_batoned(datum/source) + SIGNAL_HANDLER + drain_power(use_energy_cost) + var/datum/effect_system/lightning_spread/sparks = new /datum/effect_system/lightning_spread + sparks.set_up(number = 5, cardinals_only = TRUE, location = mod.wearer.loc) + sparks.start() diff --git a/code/modules/projectiles/ammunition/ballistic/rifle.dm b/code/modules/projectiles/ammunition/ballistic/rifle.dm index 8e06a0e10b5af..3a7c3fcb59d36 100644 --- a/code/modules/projectiles/ammunition/ballistic/rifle.dm +++ b/code/modules/projectiles/ammunition/ballistic/rifle.dm @@ -51,13 +51,61 @@ projectile_type = /obj/projectile/bullet/shotgun_beanbag/a40mm /obj/item/ammo_casing/rebar - name = "sharpened iron rod" + name = "Sharpened Iron Rod" desc = "A Sharpened Iron rod. It's Pointy!" caliber = CALIBER_REBAR icon_state = "rod_sharp" base_icon_state = "rod_sharp" projectile_type = /obj/projectile/bullet/rebar +/obj/item/ammo_casing/rebar/syndie + name = "Jagged Iron Rod" + desc = "An Iron rod, with notches cut into it. You really dont want this stuck in you." + caliber = CALIBER_REBAR + icon_state = "rod_jagged" + base_icon_state = "rod_jagged" + projectile_type = /obj/projectile/bullet/rebar/syndie + +/obj/item/ammo_casing/rebar/zaukerite + name = "Zaukerite Sliver" + desc = "A sliver of a zaukerite crystal. Due to its irregular, jagged edges, removal of an embedded zaukerite sliver should only be done by trained surgeons." + caliber = CALIBER_REBAR + icon_state = "rod_zaukerite" + base_icon_state = "rod_zaukerite" + projectile_type = /obj/projectile/bullet/rebar/zaukerite + +/obj/item/ammo_casing/rebar/hydrogen + name = "Metallic Hydrogen Bolt" + desc = "An ultra-sharp rod made from pure metallic hydrogen. Armor may as well not exist." + caliber = CALIBER_REBAR + icon_state = "rod_hydrogen" + base_icon_state = "rod_hydrogen" + projectile_type = /obj/projectile/bullet/rebar/hydrogen + +/obj/item/ammo_casing/rebar/healium + name = "Healium Crystal Bolt" + desc = "Who needs a syringe gun, anyway?" + caliber = CALIBER_REBAR + icon_state = "rod_healium" + base_icon_state = "rod_healium" + projectile_type = /obj/projectile/bullet/rebar/healium + +/obj/item/ammo_casing/rebar/supermatter + name = "Supermatter Bolt" + desc = "Wait, how is the bow capable of firing this without dusting?" + caliber = CALIBER_REBAR + icon_state = "rod_supermatter" + base_icon_state = "rod_supermatter" + projectile_type = /obj/projectile/bullet/rebar/supermatter + +/obj/item/ammo_casing/rebar/paperball + name = "Paper Ball" + desc = "Doink!" + caliber = CALIBER_REBAR + icon_state = "paperball" + base_icon_state = "paperball" + projectile_type = /obj/projectile/bullet/paperball + /obj/item/ammo_casing/rebar/Initialize(mapload) . = ..() AddElement(/datum/element/caseless, TRUE) @@ -66,10 +114,3 @@ . = ..() icon_state = "[base_icon_state]" -/obj/item/ammo_casing/rebar/syndie - name = "Jagged iron rod" - desc = "An Iron rod, with notches cut into it. You really dont want this stuck in you." - caliber = CALIBER_REBAR_SYNDIE - icon_state = "rod_jagged" - base_icon_state = "rod_jagged" - projectile_type = /obj/projectile/bullet/rebarsyndie diff --git a/code/modules/projectiles/boxes_magazines/internal/rifle.dm b/code/modules/projectiles/boxes_magazines/internal/rifle.dm index 52d395725a100..8c6abaa0e7798 100644 --- a/code/modules/projectiles/boxes_magazines/internal/rifle.dm +++ b/code/modules/projectiles/boxes_magazines/internal/rifle.dm @@ -54,8 +54,5 @@ /obj/item/ammo_box/magazine/internal/boltaction/rebarxbow/syndie max_ammo = 3 caliber = CALIBER_REBAR_SYNDIE - ammo_type = /obj/item/ammo_casing/rebar/syndie - -/obj/item/ammo_box/magazine/internal/boltaction/rebarxbow/syndie/normal - caliber = CALIBER_REBAR_SYNDIE_NORMAL ammo_type = /obj/item/ammo_casing/rebar + diff --git a/code/modules/projectiles/guns/ballistic/rifle.dm b/code/modules/projectiles/guns/ballistic/rifle.dm index e50d5ce464c89..a8161ddb39612 100644 --- a/code/modules/projectiles/guns/ballistic/rifle.dm +++ b/code/modules/projectiles/guns/ballistic/rifle.dm @@ -173,7 +173,8 @@ /obj/item/gun/ballistic/rifle/rebarxbow name = "Heated Rebar Crossbow" desc = "Made from an inducer, iron rods, and some wire, this crossbow fires sharpened iron rods, made from the plentiful iron rods found stationwide. \ - Only holds one rod in the magazine - you can craft the crossbow with a crowbar to try and force a second rod in, but risks a misfire, or worse..." + Additionally, can fire specialty ammo made from the materials in the atmos crystalizer - zaukerite, metallic hydrogen, and healium crytals all work. \ + Very slow to reload - you can craft the crossbow with a crowbar to try loosen the crossbar, but risks a misfire, or worse..." icon = 'icons/obj/weapons/guns/ballistic.dmi' icon_state = "rebarxbow" inhand_icon_state = "rebarxbow" @@ -194,7 +195,7 @@ weapon_weight = WEAPON_HEAVY initial_caliber = CALIBER_REBAR accepted_magazine_type = /obj/item/ammo_box/magazine/internal/boltaction/rebarxbow/normal - fire_sound = 'sound/items/syringeproj.ogg' + fire_sound = 'sound/items/xbow_lock.ogg' can_be_sawn_off = FALSE tac_reloads = FALSE var/draw_time = 3 SECONDS @@ -234,24 +235,22 @@ /obj/item/gun/ballistic/rifle/rebarxbow/forced name = "Stressed Rebar Crossbow" - desc = "Some idiot decided that they would risk shooting themselves in the face if it meant they could have a bit more ammo in this crossbow. Hopefully, it was worth it." + desc = "Some idiot decided that they would risk shooting themselves in the face if it meant they could have a draw this crossbow a bit faster. Hopefully, it was worth it." // Feel free to add a recipe to allow you to change it back if you would like, I just wasn't sure if you could have two recipes for the same thing. can_misfire = TRUE + draw_time = 1.5 misfire_probability = 25 accepted_magazine_type = /obj/item/ammo_box/magazine/internal/boltaction/rebarxbow/force /obj/item/gun/ballistic/rifle/rebarxbow/syndie name = "Syndicate Rebar Crossbow" desc = "The syndicate liked the bootleg rebar crossbow NT engineers made, so they showed what it could be if properly developed. \ - Holds three shots without a chance of exploding, and features a built in scope. Normally uses special syndicate jagged iron bars, but can be wrenched to shoot inferior normal ones." + Holds three shots without a chance of exploding, and features a built in scope. Compatable with all known crossbow ammunition." icon_state = "rebarxbowsyndie" inhand_icon_state = "rebarxbowsyndie" worn_icon_state = "rebarxbowsyndie" w_class = WEIGHT_CLASS_NORMAL - can_modify_ammo = TRUE - initial_caliber = CALIBER_REBAR_SYNDIE - alternative_caliber = CALIBER_REBAR_SYNDIE_NORMAL - alternative_ammo_misfires = FALSE + initial_caliber = CALIBER_REBAR draw_time = 1 accepted_magazine_type = /obj/item/ammo_box/magazine/internal/boltaction/rebarxbow/syndie diff --git a/code/modules/projectiles/projectile/bullets/rifle.dm b/code/modules/projectiles/projectile/bullets/rifle.dm index d76b2de9d6ace..e38d7f67496ee 100644 --- a/code/modules/projectiles/projectile/bullets/rifle.dm +++ b/code/modules/projectiles/projectile/bullets/rifle.dm @@ -58,20 +58,120 @@ armour_penetration = 10 wound_bonus = -20 bare_wound_bonus = 20 - embedding = list(embed_chance=60, fall_chance=2, jostle_chance=2, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=3, jostle_pain_mult=2, rip_time=10) + embedding = list("embed_chance" = 60, "fall_chance" = 2, "jostle_chance" = 2, "ignore_throwspeed_threshold" = TRUE, "pain_stam_pct" = 0.4, "pain_mult" = 4, "jostle_pain_mult" = 2, "rip_time" = 10) embed_falloff_tile = -5 wound_falloff_tile = -2 - shrapnel_type = /obj/item/stack/rods + shrapnel_type = /obj/item/ammo_casing/rebar -/obj/projectile/bullet/rebarsyndie +/obj/projectile/bullet/rebar/proc/handle_drop(datum/source, obj/item/ammo_casing/rebar/newcasing) + +/obj/projectile/bullet/rebar/syndie name = "rebar" icon_state = "rebar" - damage = 35 + damage = 55 speed = 0.4 dismemberment = 2 //It's a budget sniper rifle. armour_penetration = 20 //A bit better versus armor. Gets past anti laser armor or a vest, but doesnt wound proc on sec armor. wound_bonus = 10 + bare_wound_bonus = 20 + embedding = list("embed_chance" = 80, "fall_chance" = 1, "jostle_chance" = 3, "ignore_throwspeed_threshold" = TRUE, "pain_stam_pct" = 0.4, "pain_mult" = 3, "jostle_pain_mult" = 2, "rip_time" = 14) + embed_falloff_tile = -3 + shrapnel_type = /obj/item/ammo_casing/rebar/syndie + +/obj/projectile/bullet/rebar/zaukerite + name = "zaukerite shard" + icon_state = "rebar_zaukerite" + damage = 60 + speed = 0.6 + dismemberment = 10 + damage_type = TOX + eyeblur = 5 + armour_penetration = 20 // not nearly as good, as its not as sharp. + wound_bonus = 10 + bare_wound_bonus = 40 + embedding = list("embed_chance" =100, "fall_chance" = 0, "jostle_chance" = 5, "ignore_throwspeed_threshold" = TRUE, "pain_stam_pct" = 0.8, "pain_mult" = 6, "jostle_pain_mult" = 2, "rip_time" = 30) + embed_falloff_tile = 0 // very spiky. + shrapnel_type = /obj/item/ammo_casing/rebar/zaukerite + +/obj/projectile/bullet/rebar/hydrogen + name = "metallic hydrogen bolt" + icon_state = "rebar_hydrogen" + damage = 40 + speed = 0.6 + dismemberment = 0 //goes through clean. + damage_type = BRUTE + armour_penetration = 30 //very pointy. + projectile_piercing = PASSMOB //felt this might have been a nice compromise for the lower damage for the difficulty of getting it + wound_bonus = -15 bare_wound_bonus = 10 - embedding = list(embed_chance=80, fall_chance=1, jostle_chance=3, ignore_throwspeed_threshold=TRUE, pain_stam_pct=0.4, pain_mult=3, jostle_pain_mult=2, rip_time=14) + embedding = list("embed_chance" = 50, "fall_chance" = 2, "jostle_chance" = 3, "ignore_throwspeed_threshold" = TRUE, "pain_stam_pct" = 0.6, "pain_mult" = 4, "jostle_pain_mult" = 2, "rip_time" =18) + embed_falloff_tile = -3 + shrapnel_type = /obj/item/ammo_casing/rebar/hydrogen + +/obj/projectile/bullet/rebar/healium + name = "healium bolt" + icon_state = "rebar_healium" + damage = 0 + speed = 0.4 + dismemberment = 0 + damage_type = BRUTE + armour_penetration = 100 + wound_bonus = -100 + bare_wound_bonus = -100 + embedding = list(embed_chance = 0) embed_falloff_tile = -3 - shrapnel_type = /obj/item/stack/rods + shrapnel_type = /obj/item/ammo_casing/rebar/healium + +/obj/projectile/bullet/rebar/healium/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + if(!isliving(target)) + return BULLET_ACT_HIT + var/mob/living/breather = target + breather.SetSleeping(3 SECONDS) + breather.adjustFireLoss(-30, updating_health = TRUE, required_bodytype = BODYTYPE_ORGANIC) + breather.adjustToxLoss(-30, updating_health = TRUE, required_biotype = BODYTYPE_ORGANIC) + breather.adjustBruteLoss(-30, updating_health = TRUE, required_bodytype = BODYTYPE_ORGANIC) + breather.adjustOxyLoss(-30, updating_health = TRUE, required_biotype = BODYTYPE_ORGANIC, required_respiration_type = ALL) + + return BULLET_ACT_HIT + + +/obj/projectile/bullet/rebar/supermatter + name = "supermatter bolt" + icon_state = "rebar_supermatter" + damage = 0 + speed = 0.4 + dismemberment = 0 + damage_type = TOX + armour_penetration = 100 + shrapnel_type = /obj/item/ammo_casing/rebar/supermatter + +/obj/projectile/bullet/rebar/supermatter/on_hit(atom/target, blocked = 0, pierce_hit) + . = ..() + if(isliving(target)) + var/mob/living/victim = target + victim.investigate_log("has been dusted by [src].", INVESTIGATE_DEATHS) + dust_feedback(target) + victim.dust() + + else if(!isturf(target)&& !isliving(target)) + dust_feedback(target) + qdel(target) + + return BULLET_ACT_HIT + + +/obj/projectile/bullet/rebar/supermatter/proc/dust_feedback(atom/target) + playsound(get_turf(src), 'sound/effects/supermatter.ogg', 10, TRUE) + visible_message(span_danger("[target] is hit by [src], turning [target.p_them()] to dust in a brilliant flash of light!")) + +/obj/projectile/bullet/paperball + desc = "Doink!" + damage = 1 // It's a damn toy. + range = 10 + shrapnel_type = null + embedding = null + name = "paper ball" + desc = "doink!" + damage_type = BRUTE + icon_state = "paperball" diff --git a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm index 7e47586e20c3b..680cced458d91 100644 --- a/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/cat2_medicine_reagents.dm @@ -33,13 +33,14 @@ var/need_mob_update = FALSE switch(affected_mob.stat) if(CONSCIOUS) //bad - thou_shall_heal = death_is_coming/50 + thou_shall_heal = max(death_is_coming/20, 3) need_mob_update += affected_mob.adjustOxyLoss(2 * REM * seconds_per_tick, TRUE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) if(SOFT_CRIT) //meh convert - thou_shall_heal = round(death_is_coming/47,0.1) + thou_shall_heal = round(death_is_coming/13,0.1) need_mob_update += affected_mob.adjustOxyLoss(1 * REM * seconds_per_tick, TRUE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + good_kind_of_healing = TRUE else //no convert - thou_shall_heal = round(death_is_coming/45, 0.1) + thou_shall_heal = round(death_is_coming/10, 0.1) good_kind_of_healing = TRUE need_mob_update += affected_mob.adjustBruteLoss(-thou_shall_heal * REM * seconds_per_tick, FALSE, required_bodytype = affected_bodytype) if(need_mob_update) @@ -91,6 +92,12 @@ if(helbent) affected_mob.remove_status_effect(/datum/status_effect/necropolis_curse) +/datum/reagent/medicine/c2/helbital/on_mob_end_metabolize(mob/living/affected_mob) + . = ..() + if(current_cycle >= 50) //greater than 10u in the system + affected_mob.AddComponent(/datum/component/omen, incidents_left = min(round(current_cycle/51), 3)) //no more than 3 bad incidents for dropping more than 10u + to_chat(affected_mob, span_hierophant_warning("You feel a sense of heavy dread and grave misfortune settle in as the substance leaves your body.")) + /datum/reagent/medicine/c2/libital //messes with your liber name = "Libital" description = "A bruise reliever. Does minor liver damage." @@ -124,7 +131,7 @@ /datum/reagent/medicine/c2/probital/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() var/need_mob_update - need_mob_update = affected_mob.adjustBruteLoss(-2.25 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update = affected_mob.adjustBruteLoss(-3 * REM * normalise_creation_purity() * seconds_per_tick, updating_health = FALSE, required_bodytype = affected_bodytype) var/ooo_youaregettingsleepy = 3.5 switch(round(affected_mob.getStaminaLoss())) if(10 to 40) @@ -177,7 +184,7 @@ /datum/reagent/medicine/c2/lenturi/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired) . = ..() var/need_mob_update - need_mob_update = affected_mob.adjustFireLoss(-3 * REM * normalise_creation_purity() * seconds_per_tick, required_bodytype = affected_bodytype) + need_mob_update = affected_mob.adjustFireLoss(-3.75 * REM * normalise_creation_purity() * seconds_per_tick, required_bodytype = affected_bodytype) need_mob_update += affected_mob.adjustOrganLoss(ORGAN_SLOT_STOMACH, 0.4 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) if(need_mob_update) return UPDATE_MOB_HEALTH @@ -218,9 +225,9 @@ . = ..() var/need_mob_update if(affected_mob.getFireLoss() > 50) - need_mob_update = affected_mob.adjustFireLoss(-2 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update = affected_mob.adjustFireLoss(-3 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype) else - need_mob_update = affected_mob.adjustFireLoss(-1.25 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype) + need_mob_update = affected_mob.adjustFireLoss(-2.25 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_bodytype = affected_bodytype) affected_mob.adjust_bodytemperature(rand(-25,-5) * TEMPERATURE_DAMAGE_COEFFICIENT * REM * seconds_per_tick, 50) if(ishuman(affected_mob)) var/mob/living/carbon/human/humi = affected_mob @@ -289,7 +296,7 @@ color = "#FF6464" ph = 5.6 inverse_chem = /datum/reagent/inverse/healing/tirimol - inverse_chem_val = 0.4 + inverse_chem_val = 0.25 chemical_flags = REAGENT_CAN_BE_SYNTHESIZED /// A cooldown for spacing bursts of stamina damage @@ -298,7 +305,7 @@ /datum/reagent/medicine/c2/tirimol/on_mob_life(mob/living/carbon/human/affected_mob, seconds_per_tick, times_fired) . = ..() var/need_mob_update - need_mob_update = affected_mob.adjustOxyLoss(-3 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) + need_mob_update = affected_mob.adjustOxyLoss(-4.5 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_biotype = affected_biotype, required_respiration_type = affected_respiration_type) need_mob_update += affected_mob.adjustStaminaLoss(2 * REM * seconds_per_tick, updating_stamina = FALSE, required_biotype = affected_biotype) if(drowsycd && COOLDOWN_FINISHED(src, drowsycd)) affected_mob.adjust_drowsiness(20 SECONDS) @@ -415,8 +422,8 @@ if(!(methods & INJECT) || !iscarbon(A)) return var/mob/living/carbon/C = A - if(trans_volume >= 0.6) //prevents cheesing with ultralow doses. - C.adjustToxLoss((-1.5 * min(2, trans_volume) * REM) * normalise_creation_purity(), required_biotype = affected_biotype) //This is to promote iv pole use for that chemotherapy feel. + if(trans_volume >= 0.4) //prevents cheesing with ultralow doses. + C.adjustToxLoss((-3 * min(2, trans_volume) * REM) * normalise_creation_purity(), required_biotype = affected_biotype) //This is to promote iv pole use for that chemotherapy feel. var/obj/item/organ/internal/liver/L = C.organs_slot[ORGAN_SLOT_LIVER] if(!L || L.organ_flags & ORGAN_FAILING) return @@ -429,7 +436,7 @@ . = ..() var/need_mob_update need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.8 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - need_mob_update += affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustToxLoss(-2 * REM * seconds_per_tick, updating_health = FALSE, required_biotype = affected_biotype) for(var/datum/reagent/R in affected_mob.reagents.reagent_list) if(issyrinormusc(R)) continue @@ -460,7 +467,7 @@ . = ..() var/need_mob_update need_mob_update = affected_mob.adjustOrganLoss(ORGAN_SLOT_LIVER, 0.1 * REM * seconds_per_tick, required_organ_flag = affected_organ_flags) - need_mob_update += affected_mob.adjustToxLoss(-1 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_biotype = affected_biotype) + need_mob_update += affected_mob.adjustToxLoss(-1.5 * REM * seconds_per_tick * normalise_creation_purity(), updating_health = FALSE, required_biotype = affected_biotype) for(var/datum/reagent/R in affected_mob.reagents.reagent_list) if(issyrinormusc(R)) continue diff --git a/code/modules/reagents/chemistry/recipes/cat2_medicines.dm b/code/modules/reagents/chemistry/recipes/cat2_medicines.dm index 376a805e7d697..28aeb5743faaa 100644 --- a/code/modules/reagents/chemistry/recipes/cat2_medicines.dm +++ b/code/modules/reagents/chemistry/recipes/cat2_medicines.dm @@ -209,11 +209,11 @@ /datum/chemical_reaction/medicine/tirimol results = list(/datum/reagent/medicine/c2/tirimol = 5) required_reagents = list(/datum/reagent/nitrogen = 3, /datum/reagent/acetone = 2) - required_catalysts = list(/datum/reagent/toxin/acid = 1) + required_catalysts = list(/datum/reagent/toxin/acid = 1, /datum/reagent/oxygen = 1) mix_message = "The mixture turns into a tired reddish pink liquid." optimal_temp = 900 overheat_temp = 720 - optimal_ph_min = 2 + optimal_ph_min = 5 optimal_ph_max = 7.1 determin_ph_range = 2 temp_exponent_factor = 4 @@ -225,14 +225,6 @@ reaction_flags = REACTION_PH_VOL_CONSTANT reaction_tags = REACTION_TAG_EASY | REACTION_TAG_HEALING | REACTION_TAG_OXY -/datum/chemical_reaction/medicine/tirimol/reaction_step(datum/reagents/holder, datum/equilibrium/reaction, delta_t, delta_ph, step_reaction_vol) - . = ..() - var/datum/reagent/oxy = holder.has_reagent(/datum/reagent/oxygen) - if(oxy) - holder.remove_reagent(/datum/reagent/oxygen, 0.25) - else - holder.adjust_all_reagents_ph(-0.05*step_reaction_vol)//pH drifts faster - //Sleepytime for chem /datum/chemical_reaction/medicine/tirimol/overheated(datum/reagents/holder, datum/equilibrium/equilibrium, impure = FALSE) var/bonus = impure ? 2 : 1 diff --git a/code/modules/reagents/reagent_containers/cups/bottle.dm b/code/modules/reagents/reagent_containers/cups/bottle.dm index 75bc79c5a6aaa..0b47a89e4b2a0 100644 --- a/code/modules/reagents/reagent_containers/cups/bottle.dm +++ b/code/modules/reagents/reagent_containers/cups/bottle.dm @@ -59,6 +59,11 @@ desc = "A small bottle of multiver, which removes toxins and other chemicals from the bloodstream but causes shortness of breath. All effects scale with the amount of reagents in the patient." list_reagents = list(/datum/reagent/medicine/c2/multiver = 30) +/obj/item/reagent_containers/cup/bottle/calomel + name = "calomel bottle" + desc = "A small bottle of calomel, a toxic drug which quickly removes chemicals from the bloodstream. Does not cause additional harm in heavily-injured people." + list_reagents = list(/datum/reagent/medicine/calomel = 30) + /obj/item/reagent_containers/cup/bottle/phlogiston name = "Phlogiston bottle" desc = "A small bottle of Phlogiston, that will set you on fire if used." diff --git a/code/modules/reagents/reagent_containers/pill.dm b/code/modules/reagents/reagent_containers/pill.dm index 98ba3a13ed2eb..c4c3003d768e6 100644 --- a/code/modules/reagents/reagent_containers/pill.dm +++ b/code/modules/reagents/reagent_containers/pill.dm @@ -162,7 +162,7 @@ name = "mutadone pill" desc = "Used to treat genetic damage." icon_state = "pill20" - list_reagents = list(/datum/reagent/medicine/mutadone = 50) + list_reagents = list(/datum/reagent/medicine/mutadone = 5) rename_with_volume = TRUE /obj/item/reagent_containers/pill/salicylic diff --git a/code/modules/reagents/reagent_containers/syringes.dm b/code/modules/reagents/reagent_containers/syringes.dm index 36424f22cbdf0..83f71ff69b0ab 100644 --- a/code/modules/reagents/reagent_containers/syringes.dm +++ b/code/modules/reagents/reagent_containers/syringes.dm @@ -173,6 +173,11 @@ desc = "Contains multiver. Diluted with granibitaluri." list_reagents = list(/datum/reagent/medicine/c2/multiver = 6, /datum/reagent/medicine/granibitaluri = 9) +/obj/item/reagent_containers/syringe/calomel + name = "syringe (calomel)" + desc = "Contains calomel - a toxic drug for rapidly removing chemicals from the body." + list_reagents = list(/datum/reagent/medicine/calomel = 15) + /obj/item/reagent_containers/syringe/convermol name = "syringe (convermol)" desc = "Contains convermol. Diluted with granibitaluri." diff --git a/code/modules/research/designs/mechfabricator_designs.dm b/code/modules/research/designs/mechfabricator_designs.dm index f4308a8bc5408..0583269f1c6be 100644 --- a/code/modules/research/designs/mechfabricator_designs.dm +++ b/code/modules/research/designs/mechfabricator_designs.dm @@ -2605,3 +2605,21 @@ category = list( RND_CATEGORY_MODSUIT_MODULES + RND_SUBCATEGORY_MODSUIT_MODULES_ENGINEERING ) + +/datum/design/posisphere + name = "Positronic Sphere" + desc = "The latest in Artificial Pesterance." + id = "posisphere" + build_type = MECHFAB + materials = list( + /datum/material/iron = HALF_SHEET_MATERIAL_AMOUNT * 0.85, + /datum/material/glass = HALF_SHEET_MATERIAL_AMOUNT * 0.65, + /datum/material/gold =SMALL_MATERIAL_AMOUNT * 2.5 + ) + construction_time = 7.5 SECONDS + build_path = /obj/item/mmi/posibrain/sphere + category = list( + RND_CATEGORY_MECHFAB_CYBORG + RND_SUBCATEGORY_MECHFAB_CYBORG_CONTROL_INTERFACES + ) + departmental_flags = DEPARTMENT_BITFLAG_SCIENCE + diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index cb1ec6bb1ccc1..a8ce5f274eb14 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -2468,3 +2468,30 @@ research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) hidden = TRUE experimental = TRUE + +/datum/techweb_node/mod_experimental + id = "mod_experimental" + display_name = "Experimental Modular Suits" + description = "Applications of experimentality when creating MODsuits have created these..." + prereq_ids = list("base") + design_ids = list( + "mod_disposal", + "mod_joint_torsion", + "mod_recycler", + "mod_shooting", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE + +/datum/techweb_node/posisphere + id = "positronic_sphere" + display_name = "Experimental Spherical Positronic Brain" + description = "Recent developments on cost-cutting measures have allowed us to cut positronic brain cubes into twice-as-cheap spheres. Unfortunately, it also allows them to move around the lab via rolling maneuvers." + prereq_ids = list("base") + design_ids = list( + "posisphere", + ) + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 2500) + hidden = TRUE + experimental = TRUE diff --git a/code/modules/surgery/advanced/lobotomy.dm b/code/modules/surgery/advanced/lobotomy.dm index 6c322c2d0705e..22cba90753826 100644 --- a/code/modules/surgery/advanced/lobotomy.dm +++ b/code/modules/surgery/advanced/lobotomy.dm @@ -48,7 +48,7 @@ span_notice("[user] begins to perform a lobotomy on [target]'s brain."), span_notice("[user] begins to perform surgery on [target]'s brain."), ) - display_pain(target, "Your head pounds with unimaginable pain!") + display_pain(target, "Your head pounds with unimaginable pain!", mood_event_type = /datum/mood_event/surgery) /datum/surgery_step/lobotomize/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) display_results( @@ -58,7 +58,7 @@ span_notice("[user] successfully lobotomizes [target]!"), span_notice("[user] completes the surgery on [target]'s brain."), ) - display_pain(target, "Your head goes totally numb for a moment, the pain is overwhelming!") + display_pain(target, "Your head goes totally numb for a moment, the pain is overwhelming!", mood_event_type = /datum/mood_event/surgery/success) target.cure_all_traumas(TRAUMA_RESILIENCE_LOBOTOMY) if(target.mind && target.mind.has_antag_datum(/datum/antagonist/brainwashed)) @@ -86,7 +86,7 @@ span_notice("[user] successfully lobotomizes [target]!"), span_notice("[user] completes the surgery on [target]'s brain."), ) - display_pain(target, "The pain in your head only seems to get worse!") + display_pain(target, "The pain in your head only seems to get worse!", mood_event_type = /datum/mood_event/surgery/failure) target_brain.apply_organ_damage(80) switch(rand(1,3)) if(1) diff --git a/code/modules/surgery/amputation.dm b/code/modules/surgery/amputation.dm index c4dc91810c14f..4b4f9aede8347 100644 --- a/code/modules/surgery/amputation.dm +++ b/code/modules/surgery/amputation.dm @@ -47,7 +47,7 @@ span_notice("[user] begins to sever [target]'s [target.parse_zone_with_bodypart(target_zone)]!"), span_notice("[user] begins to sever [target]'s [target.parse_zone_with_bodypart(target_zone)]!"), ) - display_pain(target, "You feel a gruesome pain in your [parse_zone(target_zone)]'s joint!") + display_pain(target, "You feel a gruesome pain in your [parse_zone(target_zone)]'s joint!", mood_event_type = /datum/mood_event/surgery) /datum/surgery_step/sever_limb/success(mob/user, mob/living/carbon/human/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) @@ -58,7 +58,7 @@ span_notice("[user] severs [target]'s [target.parse_zone_with_bodypart(target_zone)]!"), span_notice("[user] severs [target]'s [target.parse_zone_with_bodypart(target_zone)]!"), ) - display_pain(target, "You can no longer feel your severed [target.parse_zone_with_bodypart(target_zone)]!") + display_pain(target, "You can no longer feel your severed [target.parse_zone_with_bodypart(target_zone)]!", mood_event_type = /datum/mood_event/surgery/success) if(HAS_MIND_TRAIT(user, TRAIT_MORBID) && ishuman(user)) var/mob/living/carbon/human/morbid_weirdo = user @@ -68,3 +68,7 @@ var/obj/item/bodypart/target_limb = surgery.operated_bodypart target_limb.drop_limb() return ..() + +/datum/surgery_step/sever_limb/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, fail_prob) + display_pain(target, mood_event_type = /datum/mood_event/surgery/failure) + return ..() diff --git a/code/modules/surgery/burn_dressing.dm b/code/modules/surgery/burn_dressing.dm index cde9b7b29807c..2ad5bf368d3cb 100644 --- a/code/modules/surgery/burn_dressing.dm +++ b/code/modules/surgery/burn_dressing.dm @@ -83,7 +83,7 @@ span_notice("[user] begins to excise infected flesh from [target]'s [target.parse_zone_with_bodypart(user.zone_selected)] with [tool]."), span_notice("[user] begins to excise infected flesh from [target]'s [target.parse_zone_with_bodypart(user.zone_selected)]."), ) - display_pain(target, "The infection in your [target.parse_zone_with_bodypart(user.zone_selected)] stings like hell! It feels like you're being stabbed!") + display_pain(target, "The infection in your [target.parse_zone_with_bodypart(user.zone_selected)] stings like hell! It feels like you're being stabbed!", mood_event_type = /datum/mood_event/surgery) else user.visible_message(span_notice("[user] looks for [target]'s [target.parse_zone_with_bodypart(user.zone_selected)]."), span_notice("You look for [target]'s [target.parse_zone_with_bodypart(user.zone_selected)]...")) @@ -98,6 +98,7 @@ span_notice("[user] successfully excises some of the infected flesh from [target]'s [target.parse_zone_with_bodypart(target_zone)] with [tool]!"), span_notice("[user] successfully excises some of the infected flesh from [target]'s [target.parse_zone_with_bodypart(target_zone)]!"), ) + display_pain(target, mood_event_type = /datum/mood_event/surgery/success) log_combat(user, target, "excised infected flesh in", addition="COMBAT MODE: [uppertext(user.combat_mode)]") surgery.operated_bodypart.receive_damage(brute=3, wound_bonus=CANT_WOUND) burn_wound.infestation -= infestation_removed @@ -117,6 +118,7 @@ span_notice("[user] carves away some of the healthy flesh from [target]'s [target.parse_zone_with_bodypart(target_zone)] with [tool]!"), span_notice("[user] carves away some of the healthy flesh from [target]'s [target.parse_zone_with_bodypart(target_zone)]!"), ) + display_pain(target, mood_event_type = /datum/mood_event/surgery/failure) surgery.operated_bodypart.receive_damage(brute=rand(4,8), sharpness=TRUE) /datum/surgery_step/debride/initiate(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, try_to_fail = FALSE) diff --git a/code/modules/surgery/coronary_bypass.dm b/code/modules/surgery/coronary_bypass.dm index af08987fd9398..19528fe6b5c81 100644 --- a/code/modules/surgery/coronary_bypass.dm +++ b/code/modules/surgery/coronary_bypass.dm @@ -40,7 +40,7 @@ span_notice("[user] begins to make an incision in [target]'s heart."), span_notice("[user] begins to make an incision in [target]'s heart."), ) - display_pain(target, "You feel a horrendous pain in your heart, it's almost enough to make you pass out!") + display_pain(target, "You feel a horrendous pain in your heart, it's almost enough to make you pass out!", mood_event_type = /datum/mood_event/surgery) /datum/surgery_step/incise_heart/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) if(ishuman(target)) @@ -53,6 +53,7 @@ span_notice("Blood pools around the incision in [target_human]'s heart."), span_notice("Blood pools around the incision in [target_human]'s heart."), ) + display_pain(target, mood_event_type = /datum/mood_event/surgery/success) var/obj/item/bodypart/target_bodypart = target_human.get_bodypart(target_zone) target_bodypart.adjustBleedStacks(10) target_human.adjustBruteLoss(10) @@ -68,6 +69,7 @@ span_warning("[user] screws up, causing blood to spurt out of [target_human]'s chest!"), span_warning("[user] screws up, causing blood to spurt out of [target_human]'s chest!"), ) + display_pain(target, mood_event_type = /datum/mood_event/surgery/failure) var/obj/item/bodypart/target_bodypart = target_human.get_bodypart(target_zone) target_bodypart.adjustBleedStacks(10) target_human.adjustOrganLoss(ORGAN_SLOT_HEART, 10) diff --git a/code/modules/surgery/gastrectomy.dm b/code/modules/surgery/gastrectomy.dm index a86805e3e5825..80396b04ab7e5 100644 --- a/code/modules/surgery/gastrectomy.dm +++ b/code/modules/surgery/gastrectomy.dm @@ -42,7 +42,7 @@ span_notice("[user] begins to make an incision in [target]."), span_notice("[user] begins to make an incision in [target]."), ) - display_pain(target, "You feel a horrible stab in your gut!") + display_pain(target, "You feel a horrible stab in your gut!", mood_event_type = /datum/mood_event/surgery) /datum/surgery_step/gastrectomy/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) var/mob/living/carbon/human/target_human = target @@ -57,7 +57,7 @@ span_notice("[user] successfully removes the damaged part of [target]'s stomach."), span_notice("[user] successfully removes the damaged part of [target]'s stomach."), ) - display_pain(target, "The pain in your gut ebbs and fades somewhat.") + display_pain(target, "The pain in your gut ebbs and fades somewhat.", mood_event_type = /datum/mood_event/surgery/success) return ..() /datum/surgery_step/gastrectomy/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery) @@ -70,4 +70,4 @@ span_warning("[user] cuts the wrong part of [target]'s stomach!"), span_warning("[user] cuts the wrong part of [target]'s stomach!"), ) - display_pain(target, "Your stomach throbs with pain; it's not getting any better!") + display_pain(target, "Your stomach throbs with pain; it's not getting any better!", mood_event_type = /datum/mood_event/surgery/failure) diff --git a/code/modules/surgery/hepatectomy.dm b/code/modules/surgery/hepatectomy.dm index 934e6589e9df5..a79499627c506 100644 --- a/code/modules/surgery/hepatectomy.dm +++ b/code/modules/surgery/hepatectomy.dm @@ -41,7 +41,7 @@ span_notice("[user] begins to make an incision in [target]."), span_notice("[user] begins to make an incision in [target]."), ) - display_pain(target, "Your abdomen burns in horrific stabbing pain!") + display_pain(target, "Your abdomen burns in horrific stabbing pain!", mood_event_type = /datum/mood_event/surgery) /datum/surgery_step/hepatectomy/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) var/mob/living/carbon/human/human_target = target @@ -56,7 +56,7 @@ span_notice("[user] successfully removes the damaged part of [target]'s liver."), span_notice("[user] successfully removes the damaged part of [target]'s liver."), ) - display_pain(target, "The pain receeds slightly.") + display_pain(target, "The pain receeds slightly.", mood_event_type = /datum/mood_event/surgery/success) return ..() /datum/surgery_step/hepatectomy/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery) @@ -69,4 +69,4 @@ span_warning("[user] cuts the wrong part of [target]'s liver!"), span_warning("[user] cuts the wrong part of [target]'s liver!"), ) - display_pain(target, "You feel a sharp stab inside your abdomen!") + display_pain(target, "You feel a sharp stab inside your abdomen!", mood_event_type = /datum/mood_event/surgery/failure) diff --git a/code/modules/surgery/lipoplasty.dm b/code/modules/surgery/lipoplasty.dm index 0e5bfb97785e8..870c53aeed7ac 100644 --- a/code/modules/surgery/lipoplasty.dm +++ b/code/modules/surgery/lipoplasty.dm @@ -38,7 +38,7 @@ span_notice("[user] begins to cut away [target]'s excess fat."), span_notice("[user] begins to cut [target]'s [target_zone] with [tool]."), ) - display_pain(target, "You feel a stabbing in your [target_zone]!") + display_pain(target, "You feel a stabbing in your [target_zone]!", mood_event_type = /datum/mood_event/surgery) /datum/surgery_step/cut_fat/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results) display_results( @@ -48,9 +48,13 @@ span_notice("[user] cuts [target]'s excess fat loose!"), span_notice("[user] finishes the cut on [target]'s [target_zone]."), ) - display_pain(target, "The fat in your [target_zone] comes loose, dangling and hurting like hell!") + display_pain(target, "The fat in your [target_zone] comes loose, dangling and hurting like hell!", mood_event_type = /datum/mood_event/surgery/success) return TRUE +/datum/surgery_step/cut_fat/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, fail_prob) + display_pain(target, mood_event_type = /datum/mood_event/surgery/failure) + return ..() + //remove fat /datum/surgery_step/remove_fat name = "remove loose fat (retractor)" diff --git a/code/modules/surgery/lobectomy.dm b/code/modules/surgery/lobectomy.dm index 83f9279818b8d..07c96e7125a6b 100644 --- a/code/modules/surgery/lobectomy.dm +++ b/code/modules/surgery/lobectomy.dm @@ -39,7 +39,7 @@ span_notice("[user] begins to make an incision in [target]."), span_notice("[user] begins to make an incision in [target]."), ) - display_pain(target, "You feel a stabbing pain in your chest!") + display_pain(target, "You feel a stabbing pain in your chest!", mood_event_type = /datum/mood_event/surgery) /datum/surgery_step/lobectomy/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) if(ishuman(target)) @@ -54,7 +54,7 @@ span_notice("Successfully removes a piece of [human_target]'s lungs."), "", ) - display_pain(target, "Your chest hurts like hell, but breathing becomes slightly easier.") + display_pain(target, "Your chest hurts like hell, but breathing becomes slightly easier.", mood_event_type = /datum/mood_event/surgery/success) return ..() /datum/surgery_step/lobectomy/failure(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) @@ -67,7 +67,7 @@ span_warning("[user] screws up!"), span_warning("[user] screws up!"), ) - display_pain(target, "You feel a sharp stab in your chest; the wind is knocked out of you and it hurts to catch your breath!") + display_pain(target, "You feel a sharp stab in your chest; the wind is knocked out of you and it hurts to catch your breath!", mood_event_type = /datum/mood_event/surgery/failure) human_target.losebreath += 4 human_target.adjustOrganLoss(ORGAN_SLOT_LUNGS, 10) return FALSE diff --git a/code/modules/surgery/organic_steps.dm b/code/modules/surgery/organic_steps.dm index a307d00dbba65..299bedfc5b331 100644 --- a/code/modules/surgery/organic_steps.dm +++ b/code/modules/surgery/organic_steps.dm @@ -20,7 +20,7 @@ span_notice("[user] begins to make an incision in [target]'s [target.parse_zone_with_bodypart(target_zone)]."), span_notice("[user] begins to make an incision in [target]'s [target.parse_zone_with_bodypart(target_zone)]."), ) - display_pain(target, "You feel a stabbing in your [target.parse_zone_with_bodypart(target_zone)].") + display_pain(target, "You feel a stabbing in your [target.parse_zone_with_bodypart(target_zone)].", mood_event_type = /datum/mood_event/surgery) /datum/surgery_step/incise/tool_check(mob/user, obj/item/tool) if(implement_type == /obj/item && !tool.get_sharpness()) @@ -39,11 +39,16 @@ span_notice("Blood pools around the incision in [human_target]'s [target.parse_zone_with_bodypart(target_zone)]."), span_notice("Blood pools around the incision in [human_target]'s [target.parse_zone_with_bodypart(target_zone)]."), ) + display_pain(target, mood_event_type = /datum/mood_event/surgery/success) var/obj/item/bodypart/target_bodypart = target.get_bodypart(target_zone) if(target_bodypart) target_bodypart.adjustBleedStacks(10) return ..() +/datum/surgery_step/incise/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, fail_prob) + display_pain(target, mood_event_type = /datum/mood_event/surgery/failure) + return ..() + /datum/surgery_step/incise/nobleed/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery) display_results( user, @@ -52,7 +57,7 @@ span_notice("[user] begins to carefully make an incision in [target]'s [target.parse_zone_with_bodypart(target_zone)]."), span_notice("[user] begins to carefully make an incision in [target]'s [target.parse_zone_with_bodypart(target_zone)]."), ) - display_pain(target, "You feel a careful stabbing in your [target.parse_zone_with_bodypart(target_zone)].") + display_pain(target, "You feel a careful stabbing in your [target.parse_zone_with_bodypart(target_zone)].", mood_event_type = /datum/mood_event/surgery) //clamp bleeders /datum/surgery_step/clamp_bleeders @@ -177,7 +182,7 @@ span_notice("[user] begins to saw through the bone in [target]'s [target.parse_zone_with_bodypart(target_zone)]."), span_notice("[user] begins to saw through the bone in [target]'s [target.parse_zone_with_bodypart(target_zone)]."), ) - display_pain(target, "You feel a horrid ache spread through the inside of your [target.parse_zone_with_bodypart(target_zone)]!") + display_pain(target, "You feel a horrid ache spread through the inside of your [target.parse_zone_with_bodypart(target_zone)]!", mood_event_type = /datum/mood_event/surgery) /datum/surgery_step/saw/tool_check(mob/user, obj/item/tool) if(implement_type == /obj/item && !(tool.get_sharpness() && (tool.force >= 10))) @@ -193,7 +198,11 @@ span_notice("[user] saws [target]'s [target.parse_zone_with_bodypart(target_zone)] open!"), span_notice("[user] saws [target]'s [target.parse_zone_with_bodypart(target_zone)] open!"), ) - display_pain(target, "It feels like something just broke in your [target.parse_zone_with_bodypart(target_zone)]!") + display_pain(target, "It feels like something just broke in your [target.parse_zone_with_bodypart(target_zone)]!", mood_event_type = /datum/mood_event/surgery/success) + return ..() + +/datum/surgery_step/saw/failure(mob/user, mob/living/target, target_zone, obj/item/tool, datum/surgery/surgery, fail_prob) + display_pain(target, mood_event_type = /datum/mood_event/surgery/failure) return ..() //drill bone diff --git a/code/modules/surgery/plastic_surgery.dm b/code/modules/surgery/plastic_surgery.dm index 90357f7b2e497..ab0d502039d53 100644 --- a/code/modules/surgery/plastic_surgery.dm +++ b/code/modules/surgery/plastic_surgery.dm @@ -70,7 +70,7 @@ span_notice("[user] begins to alter [target]'s appearance."), span_notice("[user] begins to make an incision in [target]'s face."), ) - display_pain(target, "You feel slicing pain across your face!") + display_pain(target, "You feel slicing pain across your face!", mood_event_type = /datum/mood_event/surgery) /datum/surgery_step/reshape_face/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) if(HAS_TRAIT_FROM(target, TRAIT_DISFIGURED, TRAIT_GENERIC)) @@ -82,7 +82,7 @@ span_notice("[user] successfully restores [target]'s appearance!"), span_notice("[user] finishes the operation on [target]'s face."), ) - display_pain(target, "The pain fades, your face feels normal again!") + display_pain(target, "The pain fades, your face feels normal again!", mood_event_type = /datum/mood_event/surgery/success) else var/list/names = list() if(!isabductor(user)) @@ -112,7 +112,7 @@ span_notice("[user] alters [oldname]'s appearance completely, [target.p_they()] is now [newname]!"), span_notice("[user] finishes the operation on [target]'s face."), ) - display_pain(target, "The pain fades, your face feels new and unfamiliar!") + display_pain(target, "The pain fades, your face feels new and unfamiliar!", mood_event_type = /datum/mood_event/surgery/failure) if(ishuman(target)) var/mob/living/carbon/human/human_target = target human_target.sec_hud_set_ID() diff --git a/code/modules/surgery/repair_puncture.dm b/code/modules/surgery/repair_puncture.dm index 31a61a8827986..601d27269eded 100644 --- a/code/modules/surgery/repair_puncture.dm +++ b/code/modules/surgery/repair_puncture.dm @@ -65,7 +65,7 @@ span_notice("[user] begins to realign the torn blood vessels in [target]'s [target.parse_zone_with_bodypart(user.zone_selected)] with [tool]."), span_notice("[user] begins to realign the torn blood vessels in [target]'s [target.parse_zone_with_bodypart(user.zone_selected)]."), ) - display_pain(target, "You feel a horrible stabbing pain in your [target.parse_zone_with_bodypart(user.zone_selected)]!") + display_pain(target, "You feel a horrible stabbing pain in your [target.parse_zone_with_bodypart(user.zone_selected)]!", mood_event_type = /datum/mood_event/surgery) /datum/surgery_step/repair_innards/success(mob/living/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery, default_display_results = FALSE) var/datum/wound/pierce/bleed/pierce_wound = surgery.operated_wound @@ -80,6 +80,7 @@ span_notice("[user] successfully realigns some of the blood vessels in [target]'s [target.parse_zone_with_bodypart(target_zone)] with [tool]!"), span_notice("[user] successfully realigns some of the blood vessels in [target]'s [target.parse_zone_with_bodypart(target_zone)]!"), ) + display_pain(target, mood_event_type = /datum/mood_event/surgery/success) log_combat(user, target, "excised infected flesh in", addition="COMBAT MODE: [uppertext(user.combat_mode)]") surgery.operated_bodypart.receive_damage(brute=3, wound_bonus=CANT_WOUND) pierce_wound.adjust_blood_flow(-0.25) @@ -94,6 +95,7 @@ span_notice("[user] jerks apart some of the blood vessels in [target]'s [target.parse_zone_with_bodypart(target_zone)] with [tool]!"), span_notice("[user] jerk apart some of the blood vessels in [target]'s [target.parse_zone_with_bodypart(target_zone)]!"), ) + display_pain(target, mood_event_type = /datum/mood_event/surgery/failure) surgery.operated_bodypart.receive_damage(brute=rand(4,8), sharpness=SHARP_EDGED, wound_bonus = 10) ///// Sealing the vessels back together diff --git a/code/modules/surgery/surgery_step.dm b/code/modules/surgery/surgery_step.dm index 8c9782163bd00..87bc8625c7455 100644 --- a/code/modules/surgery/surgery_step.dm +++ b/code/modules/surgery/surgery_step.dm @@ -262,12 +262,19 @@ * * target - Who the message will be sent to * * pain_message - The message to be displayed * * mechanical_surgery - Boolean flag that represents if a surgery step is done on a mechanical limb (therefore does not force scream) + * * mood_event_type - What type of mood event the step applies if they're still conscious (ie "THEY'RE CUTTING ME OPEN!!" when being sliced open with a scalpel/saw/ect) */ -/datum/surgery_step/proc/display_pain(mob/living/target, pain_message, mechanical_surgery = FALSE) +/datum/surgery_step/proc/display_pain(mob/living/target, pain_message, mechanical_surgery = FALSE, datum/mood_event/mood_event_type) if(target.stat < UNCONSCIOUS) if(HAS_TRAIT(target, TRAIT_ANALGESIA)) + if(!pain_message) + return to_chat(target, span_notice("You feel a dull, numb sensation as your body is surgically operated on.")) else + if(mood_event_type) + target.add_mood_event("surgery", mood_event_type) + if(!pain_message) + return to_chat(target, span_userdanger(pain_message)) if(prob(30) && !mechanical_surgery) target.emote("scream") diff --git a/code/modules/transport/tram/tram_controller.dm b/code/modules/transport/tram/tram_controller.dm index 6662cb2db9de2..a7b8a7c6a24a2 100644 --- a/code/modules/transport/tram/tram_controller.dm +++ b/code/modules/transport/tram/tram_controller.dm @@ -10,7 +10,10 @@ var/controller_active = FALSE ///whether all required parts of the tram are considered operational var/controller_operational = TRUE + ///the controller cabinet located on the tram var/obj/machinery/transport/tram_controller/paired_cabinet + ///the home controller located in telecoms + var/obj/machinery/transport/tram_controller/tcomms/home_controller ///if we're travelling, what direction are we going var/travel_direction = NONE ///if we're travelling, how far do we have to go @@ -50,16 +53,27 @@ ///how many times we moved while costing less than 0.5 * SStransport.max_time milliseconds per movement var/recovery_clear_count = 0 + ///if the tram's next stop will be the tram malfunction event sequence + var/malf_active = FALSE + + ///fluff information of the tram, such as ongoing kill count and age var/datum/tram_mfg_info/tram_registration + ///previous trams that have been destroyed var/list/tram_history /datum/tram_mfg_info + ///serial number of this tram (what round ID it first appeared in) var/serial_number + ///is it the active tram for the map var/active = TRUE + ///date the tram was created var/mfg_date + ///what map the tram is used on var/install_location + ///lifetime distance the tram has travelled var/distance_travelled = 0 + ///lifetime number of players hit by the tram var/collisions = 0 /** @@ -245,6 +259,9 @@ playsound(paired_cabinet, 'sound/machines/synth_yes.ogg', 40, vary = FALSE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) paired_cabinet.say("Controller reset.") + if(malf_active) + addtimer(CALLBACK(src, PROC_REF(announce_malf_event)), 1 SECONDS) + SEND_SIGNAL(src, COMSIG_TRAM_TRAVEL, idle_platform, destination_platform) for(var/obj/structure/transport/linear/tram/transport_module as anything in transport_modules) //only thing everyone needs to know is the new location. @@ -279,11 +296,7 @@ return PROCESS_KILL if(!travel_remaining) - if(!controller_operational) - degraded_stop() - return PROCESS_KILL - - if((controller_status & COMM_ERROR) && prob(5)) // malfunctioning tram has a small chance to e-stop + if(!controller_operational || malf_active) degraded_stop() else normal_stop() @@ -324,6 +337,9 @@ scheduled_move = world.time + speed_limiter +/** + * Tram stops normally, performs post-trip actions and updates the tram registration. + */ /datum/transport_controller/linear/tram/proc/normal_stop() cycle_doors(CYCLE_OPEN) log_transport("TC: [specific_transport_id] trip completed. Info: nav_pos ([nav_beacon.x], [nav_beacon.y], [nav_beacon.z]) idle_pos ([destination_platform.x], [destination_platform.y], [destination_platform.z]).") @@ -341,6 +357,9 @@ current_load = 0 speed_limiter = initial(speed_limiter) +/** + * Tram comes to an in-station degraded stop, throwing the players. Caused by power loss or tram malfunction event. + */ /datum/transport_controller/linear/tram/proc/degraded_stop() log_transport("TC: [specific_transport_id] trip completed with a degraded status. Info: [TC_TS_STATUS] nav_pos ([nav_beacon.x], [nav_beacon.y], [nav_beacon.z]) idle_pos ([destination_platform.x], [destination_platform.y], [destination_platform.z]).") addtimer(CALLBACK(src, PROC_REF(unlock_controls)), 4 SECONDS) @@ -350,6 +369,13 @@ paired_cabinet.say("Controller reset.") log_transport("TC: [specific_transport_id] position data successfully reset. ") speed_limiter = initial(speed_limiter) + if(malf_active) + set_status_code(SYSTEM_FAULT, TRUE) + addtimer(CALLBACK(src, PROC_REF(cycle_doors), CYCLE_OPEN), 2 SECONDS) + malf_active = FALSE + throw_chance = initial(throw_chance) + playsound(paired_cabinet, 'sound/machines/buzz-sigh.ogg', 60, vary = FALSE, extrarange = SHORT_RANGE_SOUND_EXTRARANGE) + paired_cabinet.say("Controller error. Please contact your engineering department.") idle_platform = destination_platform tram_registration.distance_travelled += (travel_trip_length - travel_remaining) travel_trip_length = 0 @@ -360,6 +386,9 @@ for(var/obj/structure/transport/linear/tram/module in transport_modules) module.estop_throw(throw_direction) +/** + * Tram comes to an emergency stop without completing its trip. Caused by emergency stop button or some catastrophic tram failure. + */ /datum/transport_controller/linear/tram/proc/halt_and_catch_fire() if(controller_status & SYSTEM_FAULT) if(!isnull(paired_cabinet)) @@ -382,6 +411,9 @@ current_speed = 0 current_load = 0 +/** + * Performs a reset of the tram's position data by finding a predetermined reference landmark, then driving to it. + */ /datum/transport_controller/linear/tram/proc/reset_position() if(idle_platform) if(get_turf(idle_platform) == get_turf(nav_beacon)) @@ -528,20 +560,36 @@ set_status_code(SYSTEM_FAULT, FALSE) reset_position() +/datum/transport_controller/linear/tram/proc/set_home_controller(obj/machinery/transport/tram_controller/tcomms/tcomms_unit) + home_controller = tcomms_unit + RegisterSignal(tcomms_unit, COMSIG_MACHINERY_POWER_LOST, PROC_REF(home_power_lost)) + RegisterSignal(tcomms_unit, COMSIG_MACHINERY_POWER_RESTORED, PROC_REF(home_power_restored)) + RegisterSignal(tcomms_unit, COMSIG_QDELETING, PROC_REF(on_home_qdel)) + log_transport("TC: [specific_transport_id] is now paired with home controller [tcomms_unit].") + if(controller_status & COMM_ERROR) + set_status_code(COMM_ERROR, FALSE) + /datum/transport_controller/linear/tram/proc/on_cabinet_qdel() paired_cabinet = null log_transport("TC: [specific_transport_id] received QDEL from controller cabinet.") set_status_code(SYSTEM_FAULT, TRUE) - send_transport_active_signal() + +/datum/transport_controller/linear/tram/proc/on_home_qdel() + home_controller = null + log_transport("TC: [specific_transport_id] received QDEL from controller cabinet.") + set_status_code(COMM_ERROR, TRUE) + +/datum/transport_controller/linear/tram/proc/home_power_lost() + set_status_code(COMM_ERROR, TRUE) + +/datum/transport_controller/linear/tram/proc/home_power_restored() + set_status_code(COMM_ERROR, FALSE) /** - * Tram malfunction random event. Set comm error, increase tram lethality. + * Tram malfunction random event. Set comm error, requiring engineering or AI intervention. */ /datum/transport_controller/linear/tram/proc/start_malf_event() - set_status_code(COMM_ERROR, TRUE) - SEND_TRANSPORT_SIGNAL(COMSIG_COMMS_STATUS, src, FALSE) - paired_cabinet.generate_repair_signals() - collision_lethality *= 1.25 + malf_active = TRUE throw_chance *= 1.25 log_transport("TC: [specific_transport_id] starting Tram Malfunction event.") @@ -552,15 +600,15 @@ * automagically reset it remotely. */ /datum/transport_controller/linear/tram/proc/end_malf_event() - if(!(controller_status & COMM_ERROR)) + if(!(malf_active)) return - set_status_code(COMM_ERROR, FALSE) - paired_cabinet.clear_repair_signals() - collision_lethality = initial(collision_lethality) + malf_active = FALSE throw_chance = initial(throw_chance) - SEND_TRANSPORT_SIGNAL(COMSIG_COMMS_STATUS, src, TRUE) log_transport("TC: [specific_transport_id] ending Tram Malfunction event.") +/datum/transport_controller/linear/tram/proc/announce_malf_event() + priority_announce("Our automated control system has lost contact with the tram's onboard computer. Please stand by, engineering has been dispatched to the tram to perform a reset.", "[command_name()] Engineering Division") + /datum/transport_controller/linear/tram/proc/register_collision(points = 1) tram_registration.collisions += points SEND_TRANSPORT_SIGNAL(COMSIG_TRAM_COLLISION, SSpersistence.tram_hits_this_round) @@ -689,11 +737,13 @@ name = "tram controller" desc = "Makes the tram go, or something. Holds the tram's electronics, controls, and maintenance panel. A sticker above the card reader says 'Engineering access only.'" icon = 'icons/obj/tram/tram_controllers.dmi' - icon_state = "controller-panel" + icon_state = "tram-controller" + base_icon_state = "tram" anchored = TRUE density = FALSE armor_type = /datum/armor/transport_module resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF + interaction_flags_machine = parent_type::interaction_flags_machine | INTERACT_MACHINE_OFFLINE max_integrity = 750 integrity_failure = 0.25 layer = SIGN_LAYER @@ -701,6 +751,8 @@ idle_power_usage = BASE_MACHINE_IDLE_CONSUMPTION * 0.25 power_channel = AREA_USAGE_ENVIRON var/datum/transport_controller/linear/tram/controller_datum + /// If this machine has a cover installed + var/has_cover = TRUE /// If the cover is open var/cover_open = FALSE /// If the cover is locked @@ -733,14 +785,13 @@ ..() /obj/machinery/transport/tram_controller/add_context(atom/source, list/context, obj/item/held_item, mob/user) - if(held_item?.tool_behaviour == TOOL_SCREWDRIVER) + if(held_item?.tool_behaviour == TOOL_SCREWDRIVER && has_cover) context[SCREENTIP_CONTEXT_RMB] = panel_open ? "close panel" : "open panel" - if(!held_item) + if(!held_item && has_cover) context[SCREENTIP_CONTEXT_LMB] = cover_open ? "access controls" : "open cabinet" context[SCREENTIP_CONTEXT_RMB] = cover_open ? "close cabinet" : "toggle lock" - if(panel_open) if(held_item?.tool_behaviour == TOOL_WRENCH) context[SCREENTIP_CONTEXT_RMB] = "unscrew cabinet" @@ -760,14 +811,15 @@ /obj/machinery/transport/tram_controller/examine(mob/user) . = ..() - . += span_notice("The door appears to be [cover_locked ? "locked. Swipe an ID card to unlock" : "unlocked. Swipe an ID card to lock"].") - if(panel_open) - . += span_notice("It is secured to the tram wall with [EXAMINE_HINT("bolts.")]") - . += span_notice("The maintenance panel can be closed with a [EXAMINE_HINT("screwdriver.")]") - else - . += span_notice("The maintenance panel can be opened with a [EXAMINE_HINT("screwdriver.")]") + if(has_cover) + . += span_notice("The door appears to be [cover_locked ? "locked. Swipe an ID card to unlock" : "unlocked. Swipe an ID card to lock"].") + if(panel_open) + . += span_notice("It is secured to the tram wall with [EXAMINE_HINT("bolts.")]") + . += span_notice("The maintenance panel can be closed with a [EXAMINE_HINT("screwdriver.")]") + else + . += span_notice("The maintenance panel can be opened with a [EXAMINE_HINT("screwdriver.")]") - if(cover_open) + if(cover_open || !has_cover) . += span_notice("The [EXAMINE_HINT("yellow reset button")] resets the tram controller if a problem occurs or needs to be restarted.") . += span_notice("The [EXAMINE_HINT("red stop button")] immediately stops the tram, requiring a reset afterwards.") . += span_notice("The cabinet can be closed with a [EXAMINE_HINT("Right-click.")]") @@ -779,16 +831,17 @@ if(user.combat_mode || cover_open) return ..() - var/obj/item/card/id/id_card = user.get_id_in_hand() - if(!isnull(id_card)) - try_toggle_lock(user, id_card) - return + if(has_cover) + var/obj/item/card/id/id_card = user.get_id_in_hand() + if(!isnull(id_card)) + try_toggle_lock(user, id_card) + return return ..() /obj/machinery/transport/tram_controller/attack_hand(mob/living/user, params) . = ..() - if(cover_open) + if(cover_open || !has_cover) return if(cover_locked) @@ -804,6 +857,8 @@ /obj/machinery/transport/tram_controller/attack_hand_secondary(mob/living/user, params) . = ..() + if(!has_cover) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN if(!cover_open) var/obj/item/card/id/id_card = user.get_idcard(TRUE) @@ -843,6 +898,9 @@ /obj/machinery/transport/tram_controller/wrench_act_secondary(mob/living/user, obj/item/tool) . = ..() + if(!has_cover) + return + if(panel_open && cover_open) balloon_alert(user, "unsecuring...") tool.play_tool_sound(src) @@ -878,53 +936,55 @@ /obj/machinery/transport/tram_controller/update_overlays() . = ..() - if(!cover_open) - . += mutable_appearance(icon, "controller-closed") - if(cover_locked) - . += mutable_appearance(icon, "controller-locked") + if(has_cover) + if(!cover_open) + . += mutable_appearance(icon, "[base_icon_state]-closed") + if(cover_locked) + . += mutable_appearance(icon, "[base_icon_state]-locked") - else - var/mutable_appearance/controller_door = mutable_appearance(icon, "controller-open") - controller_door.pixel_w = -3 - . += controller_door + else + var/mutable_appearance/controller_door = mutable_appearance(icon, "[base_icon_state]-open") + controller_door.pixel_w = -3 + . += controller_door if(machine_stat & NOPOWER) - . += mutable_appearance(icon, "estop") - . += emissive_appearance(icon, "estop", src, alpha = src.alpha) + . += mutable_appearance(icon, "[base_icon_state]-estop") + . += emissive_appearance(icon, "[base_icon_state]-estop", src, alpha = src.alpha) return - . += mutable_appearance(icon, "power") - . += emissive_appearance(icon, "power", src, alpha = src.alpha) + . += mutable_appearance(icon, "[base_icon_state]-power") + . += emissive_appearance(icon, "[base_icon_state]-power", src, alpha = src.alpha) if(!controller_datum) - . += mutable_appearance(icon, "fatal") - . += emissive_appearance(icon, "fatal", src, alpha = src.alpha) + . += mutable_appearance(icon, "[base_icon_state]-fatal") + . += emissive_appearance(icon, "[base_icon_state]-fatal", src, alpha = src.alpha) return if(controller_datum.controller_status & EMERGENCY_STOP) - . += mutable_appearance(icon, "estop") - . += emissive_appearance(icon, "estop", src, alpha = src.alpha) + . += mutable_appearance(icon, "[base_icon_state]-estop") + . += emissive_appearance(icon, "[base_icon_state]-estop", src, alpha = src.alpha) + return + + if(controller_datum.controller_status & SYSTEM_FAULT || controller_datum.malf_active) + . += mutable_appearance(icon, "[base_icon_state]-fault") + . += emissive_appearance(icon, "[base_icon_state]-fault", src, alpha = src.alpha) return if(!(controller_datum.controller_status & DOORS_READY)) - . += mutable_appearance(icon, "doors") - . += emissive_appearance(icon, "doors", src, alpha = src.alpha) + . += mutable_appearance(icon, "[base_icon_state]-doors") + . += emissive_appearance(icon, "[base_icon_state]-doors", src, alpha = src.alpha) if(controller_datum.controller_active) - . += mutable_appearance(icon, "active") - . += emissive_appearance(icon, "active", src, alpha = src.alpha) + . += mutable_appearance(icon, "[base_icon_state]-active") + . += emissive_appearance(icon, "[base_icon_state]-active", src, alpha = src.alpha) - if(controller_datum.controller_status & SYSTEM_FAULT) - . += mutable_appearance(icon, "fault") - . += emissive_appearance(icon, "fault", src, alpha = src.alpha) - - else if(controller_datum.controller_status & COMM_ERROR) - . += mutable_appearance(icon, "comms") - . += emissive_appearance(icon, "comms", src, alpha = src.alpha) + if(controller_datum.controller_status & COMM_ERROR) + . += mutable_appearance(icon, "[base_icon_state]-comms") + . += emissive_appearance(icon, "[base_icon_state]-comms", src, alpha = src.alpha) else - . += mutable_appearance(icon, "normal") - . += emissive_appearance(icon, "normal", src, alpha = src.alpha) + . += mutable_appearance(icon, "[base_icon_state]-normal") + . += emissive_appearance(icon, "[base_icon_state]-normal", src, alpha = src.alpha) /** * Find the controller associated with the transport module the cabinet is sitting on. @@ -972,24 +1032,12 @@ balloon_alert(user, "access controller shorted") return TRUE -/** - * Check if the tram was malfunctioning due to the random event, and if so end the event on repair. - */ -/obj/machinery/transport/tram_controller/try_fix_machine(obj/machinery/transport/machine, mob/living/user, obj/item/tool) - . = ..() - - if(. == FALSE) - return - - if(!controller_datum) - return +/obj/machinery/transport/tram_controller/ui_status(mob/user, datum/ui_state/state) + if(HAS_SILICON_ACCESS(user) && (controller_datum.controller_status & SYSTEM_FAULT || controller_datum.controller_status & COMM_ERROR || !is_operational)) + to_chat(user, span_warning("An error code flashes: Communications fault! The [src] is not responding to remote inputs!")) + return UI_CLOSE - var/datum/round_event/tram_malfunction/malfunction_event = locate(/datum/round_event/tram_malfunction) in SSevents.running - if(malfunction_event) - malfunction_event.end() - - if(controller_datum.controller_status & COMM_ERROR) - controller_datum.set_status_code(COMM_ERROR, FALSE) + return ..() /obj/machinery/transport/tram_controller/ui_interact(mob/user, datum/tgui/ui) . = ..() @@ -997,7 +1045,7 @@ if(!cover_open && !HAS_SILICON_ACCESS(user) && !isobserver(user)) return - if(!is_operational) + if(machine_stat & BROKEN) return ui = SStgui.try_update_ui(user, src, ui) @@ -1043,6 +1091,10 @@ if(!COOLDOWN_FINISHED(src, manual_command_cooldown)) return + if(machine_stat & NOPOWER) + visible_message(span_warning("The button doesn't appear to do anything, the [src]'s power failure status is flashing!"), vision_distance = COMBAT_MESSAGE_RANGE) + return + switch(action) if("dispatch") @@ -1078,11 +1130,53 @@ COOLDOWN_START(src, manual_command_cooldown, 2 SECONDS) + +/// Controller that sits in the telecoms room +/obj/machinery/transport/tram_controller/tcomms + name = "tram central controller" + desc = "This semi-conductor is half of the brains controlling the tram and its auxillary equipment." + icon_state = "home-controller" + base_icon_state = "home" + density = TRUE + layer = BELOW_OBJ_LAYER + power_channel = AREA_USAGE_EQUIP + cover_open = TRUE + has_cover = FALSE + +/// Handles the machine being affected by an EMP, causing signal failure. +/obj/machinery/transport/tram_controller/tcomms/emp_act(severity) + . = ..() + if(. & EMP_PROTECT_SELF) + return + if(prob(100/severity) && !(machine_stat & EMPED)) + set_machine_stat(machine_stat | EMPED) + controller_datum.set_status_code(COMM_ERROR, TRUE) + var/duration = (300 SECONDS)/severity + addtimer(CALLBACK(src, PROC_REF(de_emp)), rand(duration - 2 SECONDS, duration + 2 SECONDS)) + +/// Handles the machine stopping being affected by an EMP. +/obj/machinery/transport/tram_controller/tcomms/proc/de_emp() + set_machine_stat(machine_stat & ~EMPED) + controller_datum.set_status_code(COMM_ERROR, FALSE) + +/obj/machinery/transport/tram_controller/tcomms/find_controller() + link_tram() + return + +/obj/machinery/transport/tram_controller/tcomms/link_tram() + . = ..() + var/datum/transport_controller/linear/tram/tram = transport_ref?.resolve() + controller_datum = tram + if(!controller_datum) + return + controller_datum.set_home_controller(src) + RegisterSignal(SStransport, COMSIG_TRANSPORT_ACTIVE, PROC_REF(sync_controller)) + /obj/item/wallframe/tram/controller name = "tram controller cabinet" desc = "A box that contains the equipment to control a tram. Just secure to the tram wall." icon = 'icons/obj/tram/tram_controllers.dmi' - icon_state = "controller-panel" + icon_state = "tram-controller" custom_materials = list(/datum/material/titanium = SHEET_MATERIAL_AMOUNT * 4, /datum/material/iron = SHEET_MATERIAL_AMOUNT * 2, /datum/material/glass = SHEET_MATERIAL_AMOUNT * 2) result_path = /obj/machinery/transport/tram_controller pixel_shift = 32 diff --git a/code/modules/transport/tram/tram_doors.dm b/code/modules/transport/tram/tram_doors.dm index 644f45def4aa5..653b5cbabb527 100644 --- a/code/modules/transport/tram/tram_doors.dm +++ b/code/modules/transport/tram/tram_doors.dm @@ -1,7 +1,7 @@ -#define TRAM_DOOR_WARNING_TIME (1.4 SECONDS) -#define TRAM_DOOR_CYCLE_TIME (0.4 SECONDS) +#define TRAM_DOOR_WARNING_TIME (0.9 SECONDS) +#define TRAM_DOOR_CYCLE_TIME (0.6 SECONDS) #define TRAM_DOOR_CRUSH_TIME (0.7 SECONDS) -#define TRAM_DOOR_RECYCLE_TIME (3 SECONDS) +#define TRAM_DOOR_RECYCLE_TIME (2.7 SECONDS) /obj/machinery/door/airlock/tram name = "tram door" @@ -9,7 +9,7 @@ overlays_file = 'icons/obj/doors/airlocks/tram/tram-overlays.dmi' multi_tile = TRUE opacity = FALSE - assemblytype = null + assemblytype = /obj/structure/door_assembly/multi_tile/door_assembly_tram airlock_material = "glass" air_tight = TRUE req_access = list(ACCESS_TCOMMS) @@ -55,7 +55,7 @@ update_freelook_sight() flags_1 &= ~PREVENT_CLICK_UNDER_1 air_update_turf(TRUE, FALSE) - sleep(TRAM_DOOR_CYCLE_TIME) + sleep(TRAM_DOOR_WARNING_TIME) layer = OPEN_DOOR_LAYER update_icon(ALL, AIRLOCK_OPEN, TRUE) operating = FALSE @@ -64,7 +64,7 @@ /obj/machinery/door/airlock/tram/close(forced = DEFAULT_DOOR_CHECKS, force_crush = FALSE) retry_counter++ - if(retry_counter >= 4 || force_crush || forced == BYPASS_DOOR_CHECKS) + if(retry_counter >= 3 || force_crush || forced == BYPASS_DOOR_CHECKS) try_to_close(forced = BYPASS_DOOR_CHECKS) return @@ -116,7 +116,7 @@ air_update_turf(TRUE, TRUE) crush() crushing_in_progress = FALSE - sleep(TRAM_DOOR_CYCLE_TIME) + sleep(TRAM_DOOR_WARNING_TIME) update_icon(ALL, AIRLOCK_CLOSED, 1) operating = FALSE retry_counter = 0 @@ -163,7 +163,7 @@ if(airlock_state == AIRLOCK_CLOSED) return - if(retry_counter < 3) + if(retry_counter < 2) close() return @@ -205,6 +205,9 @@ * Tram doors can be opened with hands when unpowered */ /obj/machinery/door/airlock/tram/try_safety_unlock(mob/user) + if(DOING_INTERACTION_WITH_TARGET(user, src)) + return + if(!hasPower() && density) balloon_alert(user, "pulling emergency exit...") if(do_after(user, 4 SECONDS, target = src)) @@ -215,10 +218,20 @@ * If you pry (bump) the doors open midtravel, open quickly so you can jump out and make a daring escape. */ /obj/machinery/door/airlock/tram/bumpopen(mob/user, forced = BYPASS_DOOR_CHECKS) + if(DOING_INTERACTION_WITH_TARGET(user, src)) + return + if(operating || !density) return + + if(!hasPower()) + try_safety_unlock(user) + return + var/datum/transport_controller/linear/tram/tram_part = transport_ref?.resolve() add_fingerprint(user) + if(!tram_part.controller_active) + return if((tram_part.travel_remaining < DEFAULT_TRAM_LENGTH || tram_part.travel_remaining > tram_part.travel_trip_length - DEFAULT_TRAM_LENGTH) && tram_part.controller_active) return // we're already animating, don't reset that open(forced = BYPASS_DOOR_CHECKS) diff --git a/code/modules/transport/tram/tram_machinery.dm b/code/modules/transport/tram/tram_machinery.dm index 99375bfbaf578..a60a1d658663c 100644 --- a/code/modules/transport/tram/tram_machinery.dm +++ b/code/modules/transport/tram/tram_machinery.dm @@ -91,6 +91,17 @@ /// The ID of the tram we're linked to var/specific_transport_id = TRAMSTATION_LINE_1 +/// We allow borgs to use the button locally, but not the AI remotely +/obj/machinery/button/transport/tram/attack_ai(mob/user) + if(isAI(user) || panel_open) + return + if(HAS_SILICON_ACCESS(user) && !issilicon(user)) //admins and remote controls can use it at a distance + return attack_hand(user) + if(in_range(user, src)) + return attack_hand(user) + else + to_chat(user, span_warning("You are too far away to activate the button!")) + /obj/machinery/button/transport/tram/setup_device() var/obj/item/assembly/control/transport/call_button/tram_device = device tram_device.id = id diff --git a/code/modules/uplink/uplink_items/job.dm b/code/modules/uplink/uplink_items/job.dm index df4f235f50cca..40e0092d434dc 100644 --- a/code/modules/uplink/uplink_items/job.dm +++ b/code/modules/uplink/uplink_items/job.dm @@ -151,7 +151,7 @@ desc = "A much more proffessional version of the engineer's bootleg rebar crossbow. 3 shot mag, quicker loading, and better ammo. Owners manual included." item = /obj/item/storage/box/syndie_kit/rebarxbowsyndie cost = 10 - restricted_roles = list(JOB_STATION_ENGINEER, JOB_CHIEF_ENGINEER) + restricted_roles = list(JOB_STATION_ENGINEER, JOB_CHIEF_ENGINEER, JOB_ATMOSPHERIC_TECHNICIAN) /datum/uplink_item/role_restricted/magillitis_serum name = "Magillitis Serum Autoinjector" diff --git a/code/modules/uplink/uplink_items/suits.dm b/code/modules/uplink/uplink_items/suits.dm index 8e7212744822a..5d89f80506178 100644 --- a/code/modules/uplink/uplink_items/suits.dm +++ b/code/modules/uplink/uplink_items/suits.dm @@ -64,6 +64,12 @@ item = /obj/item/mod/module/noslip cost = 2 +/datum/uplink_item/suits/shock_absorber + name = "MODsuit Shock-Absorber Module" + desc = "A MODsuit module preventing the user from getting knocked down by batons." + item = /obj/item/mod/module/shock_absorber + cost = 2 + /datum/uplink_item/suits/modsuit/elite_traitor name = "Elite Syndicate MODsuit" desc = "An upgraded, elite version of the Syndicate MODsuit. It features fireproofing, and also \ diff --git a/code/modules/vending/medical.dm b/code/modules/vending/medical.dm index 71171e5783773..2209f550fce28 100644 --- a/code/modules/vending/medical.dm +++ b/code/modules/vending/medical.dm @@ -83,6 +83,7 @@ /obj/item/reagent_containers/pill/insulin = 5, /obj/item/reagent_containers/cup/bottle/multiver = 2, /obj/item/reagent_containers/cup/bottle/syriniver = 2, + /obj/item/reagent_containers/cup/bottle/calomel = 2, /obj/item/reagent_containers/cup/bottle/epinephrine = 3, /obj/item/reagent_containers/cup/bottle/morphine = 4, /obj/item/reagent_containers/cup/bottle/potass_iodide = 1, diff --git a/html/changelogs/AutoChangeLog-pr-83404.yml b/html/changelogs/AutoChangeLog-pr-83404.yml deleted file mode 100644 index 91fab2e77bd2c..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83404.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "DATA-xPUNGED" -delete-after: True -changes: - - rscadd: "NT reports indicate that the Syndicate have increased listening activities on Icemoon, crew is advised to watch out for possible communication interference." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83462.yml b/html/changelogs/AutoChangeLog-pr-83462.yml deleted file mode 100644 index f6f0fffb68450..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83462.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "TheBoondock" -delete-after: True -changes: - - sound: "added operating sounds for wrench, wirecutter and crowbar" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83510.yml b/html/changelogs/AutoChangeLog-pr-83510.yml new file mode 100644 index 0000000000000..ef3af4284ec95 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-83510.yml @@ -0,0 +1,6 @@ +author: "EnterTheJake" +delete-after: True +changes: + - rscadd: "adds the MOD shock-absorption module, into the game." + - rscadd: "The MOD shock-absorption module into the the uplinks, costs 4 TC." + - balance: "Nukie modsuits come with the shock_absorption module preinstalled." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83578.yml b/html/changelogs/AutoChangeLog-pr-83578.yml deleted file mode 100644 index 8af4ed75b545a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83578.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "tmyqlfpir" -delete-after: True -changes: - - rscadd: "Added new circuit camera components" - - qol: "Circuit drones can now recharge at recharge stations" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83591.yml b/html/changelogs/AutoChangeLog-pr-83591.yml deleted file mode 100644 index 5e509afdadbae..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83591.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Rhials" -delete-after: True -changes: - - rscadd: "Adds some more station-trait dependent pulsar star reports. Keep an eye on that roundstart command report!" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83609.yml b/html/changelogs/AutoChangeLog-pr-83609.yml deleted file mode 100644 index d563f3d137196..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83609.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Wayland-Smithy" -delete-after: True -changes: - - bugfix: "Fixed Silicons not being able to (un)lock Air Alarms." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83621.yml b/html/changelogs/AutoChangeLog-pr-83621.yml deleted file mode 100644 index 7e333a147b8d3..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83621.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Goat" -delete-after: True -changes: - - bugfix: "mobs no longer move during cutscenes" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83630.yml b/html/changelogs/AutoChangeLog-pr-83630.yml deleted file mode 100644 index b3008451a4046..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83630.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Watermelon914" -delete-after: True -changes: - - spellcheck: "Intern announcer no longer has a weird space before the introduction message." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83636.yml b/html/changelogs/AutoChangeLog-pr-83636.yml deleted file mode 100644 index 546c515074ae7..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83636.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Jackraxxus" -delete-after: True -changes: - - admin: "The auto-mute system yells at you harder when you send a bunch of identical messages." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83657.yml b/html/changelogs/AutoChangeLog-pr-83657.yml deleted file mode 100644 index cbc585c801079..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83657.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Time-Green" -delete-after: True -changes: - - bugfix: "admins can force rulesets on background checks station trait (fucking lame)" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83661.yml b/html/changelogs/AutoChangeLog-pr-83661.yml deleted file mode 100644 index 3689d68f7ca9a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83661.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "Ben10Omintrix" -delete-after: True -changes: - - bugfix: "lobstrosities will no longer be able to fish out multiple necropolis chests" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83683.yml b/html/changelogs/AutoChangeLog-pr-83683.yml deleted file mode 100644 index 70044676f939d..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83683.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "zxaber" -delete-after: True -changes: - - qol: "Plexagon Access Management now tells you that you need an ID Trim before applying a Template, rather than silently failing." \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83724.yml b/html/changelogs/AutoChangeLog-pr-83724.yml deleted file mode 100644 index 96842a58a77fd..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83724.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "grungussuss" -delete-after: True -changes: - - spellcheck: "all instances of reactive armor are now spelt the same" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83733.yml b/html/changelogs/AutoChangeLog-pr-83733.yml deleted file mode 100644 index 33a893563f8da..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83733.yml +++ /dev/null @@ -1,4 +0,0 @@ -author: "thegrb93" -delete-after: True -changes: - - bugfix: "Fixes admin borg panel upgrade functions" \ No newline at end of file diff --git a/html/changelogs/AutoChangeLog-pr-83740.yml b/html/changelogs/AutoChangeLog-pr-83740.yml deleted file mode 100644 index 8e3c56845250a..0000000000000 --- a/html/changelogs/AutoChangeLog-pr-83740.yml +++ /dev/null @@ -1,5 +0,0 @@ -author: "00-Steven" -delete-after: True -changes: - - bugfix: "Latejoiners with heterochromatic eyes no longer have the wrong fingerprint in the security records." - - bugfix: "Latejoiners actually have their quirks visible in the medical records." \ No newline at end of file diff --git a/html/changelogs/archive/2024-06.yml b/html/changelogs/archive/2024-06.yml index 60046e053bd8e..20dd1cfea33cb 100644 --- a/html/changelogs/archive/2024-06.yml +++ b/html/changelogs/archive/2024-06.yml @@ -374,3 +374,143 @@ zxaber: - bugfix: Fixed borg chargers (especially unpowered ones) constantly draining a borg's cell. +2024-06-09: + 00-Steven: + - bugfix: Latejoiners with heterochromatic eyes no longer have the wrong fingerprint + in the security records. + - bugfix: Latejoiners actually have their quirks visible in the medical records. + Ben10Omintrix: + - bugfix: lobstrosities will no longer be able to fish out multiple necropolis chests + DATA-xPUNGED: + - rscadd: NT reports indicate that the Syndicate have increased listening activities + on Icemoon, crew is advised to watch out for possible communication interference. + DustanHache: + - bugfix: Lobstrosities are no longer pre-cooked through bluespace shenanigans. + Goat: + - bugfix: mobs no longer move during cutscenes + Jackraxxus: + - admin: The auto-mute system yells at you harder when you send a bunch of identical + messages. + Majkl-J: + - bugfix: The orbit menu clicks are accurate again + - bugfix: Fixes several service and item-handling borg modules not functioning + Melbert: + - balance: Coders are now locked to the coderbus + Rhials: + - rscadd: Adds some more station-trait dependent pulsar star reports. Keep an eye + on that roundstart command report! + ShizCalev: + - bugfix: Basic bots are now in the proper faction and will no longer be targeted + by turrets. + - bugfix: The spooky element will now apply the spooked mood event when someone + is spooked. + - bugfix: Fixed spookers getting a popup message when spooking mobs not actively + controlled by a player. + - bugfix: Seeing heretical stuff while having the heresy phobia will now apply the + heresy mood event. + - bugfix: Seeing skeletons while having the skeleton phobia will now apply the spooked + (by skeletons) mood event. + - bugfix: Getting surgically cut open while conscious will now give you the "THEY'RE + CUTTING ME OPEN!!" surgical mood event. + TheBoondock: + - sound: added operating sounds for wrench, wirecutter and crowbar + Thlumyn: + - bugfix: add general engineering access to birdshot engineering entrance + Time-Green: + - bugfix: admins can force rulesets on background checks station trait (fucking + lame) + Watermelon914: + - spellcheck: Intern announcer no longer has a weird space before the introduction + message. + Wayland-Smithy: + - bugfix: Fixed Silicons not being able to (un)lock Air Alarms. + Zenitheevee: + - bugfix: fish with the Anxiety gene wont die when in the same loc as any 3 items + carlarctg: + - qol: Adds a chat message for fishing in a chasm with a normal and rescue hook, + to clarify that only rescue hooks can drag up corpses. + grungussuss: + - spellcheck: all instances of reactive armor are now spelt the same + improvedname: + - balance: Roundstart mutadone pills now have less chems in them from 50 to 5 + krookodilehunter: + - spellcheck: fixes bad raptor grammar + mc-oofert: + - code_imp: stacking machine consoles check in area instead of a tiny view range + on init + thegrb93: + - bugfix: Fixes admin borg panel upgrade functions + tmyqlfpir: + - rscadd: Added new circuit camera components + - qol: Circuit drones can now recharge at recharge stations + zxaber: + - qol: Plexagon Access Management now tells you that you need an ID Trim before + applying a Template, rather than silently failing. +2024-06-10: + EuSouAFazer: + - qol: The ERT's ship has better mapping now. + Higgin: + - bugfix: energy bolas now work on prone targets and don't leave behind a fake item + when they whiff. + - balance: buffed healing values of helbital, probital, lenturi, hercuri, syriniver, + musiver, and tirimol for their respective damage types. + - balance: Tirimol now uses oxygen as a catalyst rather than consuming it over time + making it easier to make without babysitting. Tirimol now requires much more + careful management of impurity in order to make Super Melatonin. + - rscadd: medical chem vendors now sell bottles of calomel, a potent full-range + chemical purger. + Iamgoofball: + - balance: Changelings now do not like fire, as is tradition. + - balance: If they are on fire, they no longer generate chemicals until they put + the fire out. + - balance: If they are on fire, they no longer can use any changeling powers until + they put the fire out. + - balance: All changeling equippable items like armblades, shields, armor, spacesuits, + etc. are now flammable and super-duper vulnerable to flames. + - balance: The Armblade now costs 30 chemicals to equip, and has a DNA cost of 3, + compared to the previous 20 chemicals and 2 DNA cost. + - rscadd: The Armblade now shatters after enough uses in exactly the same way as + the Shield; extract genomes with Absorb to maximize your Armblade's efficiency. + for its' chemical cost. + - bugfix: Fixes items you're holding not catching on fire alongside the rest of + you when you light on fire. + - bugfix: Fixes the Changeling Shield having one more hit than it was supposed to. + IsaacExists: + - bugfix: You may no longer submit, or obtain, a spy bounty for the contractor baton. + LT3: + - rscadd: Telecoms now has a central tram controller + - rscadd: Tram controller is now included in communications blackout event + - qol: Tram malfunction event only stops tram once, requiring engineering to reset + (no tools required) + - qol: Tram malfunction event no longer sends a Central Command announcement when + fixed + - rscdel: Tram doors no longer force crush you during tram malfunction event + - rscdel: Silicons can no longer control the tram when communication is lost + - bugfix: Tram doors can now be constructed and assemblies built + - bugfix: Emergency opening tram doors no longer spam balloon alerts + - bugfix: Tram doors open faster on arrival + - bugfix: Tram doors correctly force close on attempt 3 + NewyearnewmeUwu: + - bugfix: Fixes certain quirks being erased by slimeperson cloning. + Time-Green: + - rscadd: Adds a positronic sphere to bepis tech and roboticist mail goodies. It + can now wreack havoc across the robotics lab while whining for a DURAND body, + but you can also punt it! + WebcomicArtist: + - rscadd: Added zaukerite (high damage/embed, low AP) and metallic hydrogen (High + AP and piercing, but low embed) crossbow ammo for the rebar crossbows + - rscadd: Added healium crystal ammo for the crossbow as well, which heals whomever + you shoot it at. + - rscadd: Added admin-only supermatter crossbow bolts that dust you, because why + the hell not. + - rscadd: Added non-harmful paper balls. Can be shot from a crossbow, or thrown + at co-workers. + - rscadd: Added a quiver made from cutting an o2 tank in half, to hold it all. + - image: added sprites for all the above. + - balance: Traitor Engineer Crossbow ammo now does 55 damage instead of 45, to make + it compete with revolver. + - balance: Stressed Rebar Crossbow now has a shorter delay required to rack it, + but can shoot you in the face on misfire. + - bugfix: fixed rebar crossbow shots not dropping items on hitting walls + - bugfix: fixed traitor crossbow having worse wound chance than the base one + - sound: added new crossbow firing sound effect diff --git a/icons/mob/clothing/back.dmi b/icons/mob/clothing/back.dmi index 4fc02eaa2c0fc..52be2d07923e5 100644 Binary files a/icons/mob/clothing/back.dmi and b/icons/mob/clothing/back.dmi differ diff --git a/icons/mob/inhands/items_lefthand.dmi b/icons/mob/inhands/items_lefthand.dmi index a2347dc667abc..967968b339ba7 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 bb2a425194bd2..beb3c84860d64 100644 Binary files a/icons/mob/inhands/items_righthand.dmi and b/icons/mob/inhands/items_righthand.dmi differ diff --git a/icons/obj/clothing/modsuit/mod_modules.dmi b/icons/obj/clothing/modsuit/mod_modules.dmi index eb4b0c536ce3c..8b4b549eda2ae 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/devices/assemblies.dmi b/icons/obj/devices/assemblies.dmi index c1b0fd05f137c..95c9227ab3aa7 100644 Binary files a/icons/obj/devices/assemblies.dmi and b/icons/obj/devices/assemblies.dmi differ diff --git a/icons/obj/tram/tram_controllers.dmi b/icons/obj/tram/tram_controllers.dmi index aea1f691af241..251320af6b9d8 100644 Binary files a/icons/obj/tram/tram_controllers.dmi and b/icons/obj/tram/tram_controllers.dmi differ diff --git a/icons/obj/tram/tram_display.dmi b/icons/obj/tram/tram_display.dmi index e28beef468fef..4f64a5c8345cb 100644 Binary files a/icons/obj/tram/tram_display.dmi and b/icons/obj/tram/tram_display.dmi differ diff --git a/icons/obj/weapons/bows/quivers.dmi b/icons/obj/weapons/bows/quivers.dmi index 74a7b4bc8bb52..615f96ee6af6d 100644 Binary files a/icons/obj/weapons/bows/quivers.dmi and b/icons/obj/weapons/bows/quivers.dmi differ diff --git a/icons/obj/weapons/guns/ammo.dmi b/icons/obj/weapons/guns/ammo.dmi index 62fb2e4511451..7554749a7e4be 100644 Binary files a/icons/obj/weapons/guns/ammo.dmi and b/icons/obj/weapons/guns/ammo.dmi differ diff --git a/icons/obj/weapons/guns/projectiles.dmi b/icons/obj/weapons/guns/projectiles.dmi index 120a4c12cd3d9..98a2e59dbc9c3 100644 Binary files a/icons/obj/weapons/guns/projectiles.dmi and b/icons/obj/weapons/guns/projectiles.dmi differ diff --git a/sound/items/xbow_lock.ogg b/sound/items/xbow_lock.ogg new file mode 100644 index 0000000000000..d465a95ca056f Binary files /dev/null and b/sound/items/xbow_lock.ogg differ diff --git a/tgstation.dme b/tgstation.dme index f14d18829832e..352885b35305d 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -2117,7 +2117,6 @@ #include "code\game\machinery\doors\passworddoor.dm" #include "code\game\machinery\doors\poddoor.dm" #include "code\game\machinery\doors\shutters.dm" -#include "code\game\machinery\doors\unpowered.dm" #include "code\game\machinery\doors\windowdoor.dm" #include "code\game\machinery\embedded_controller\access_controller.dm" #include "code\game\machinery\embedded_controller\airlock_controller.dm" diff --git a/tgui/packages/tgui/styles/interfaces/Orbit.scss b/tgui/packages/tgui/styles/interfaces/Orbit.scss index 32a1dd59b70dd..3bed71d3f0cd7 100644 --- a/tgui/packages/tgui/styles/interfaces/Orbit.scss +++ b/tgui/packages/tgui/styles/interfaces/Orbit.scss @@ -1,6 +1,8 @@ .JobIcon { + height: 20px; background: black; padding: 1px 1px 0 1px; + overflow: hidden; } .OrbitItem__selected {