diff --git a/_maps/map_files/Deltastation/DeltaStation2.dmm b/_maps/map_files/Deltastation/DeltaStation2.dmm index e43a172ce5..5a2a8aeef6 100644 --- a/_maps/map_files/Deltastation/DeltaStation2.dmm +++ b/_maps/map_files/Deltastation/DeltaStation2.dmm @@ -54013,22 +54013,16 @@ /turf/closed/wall, /area/medical/surgery) "dsN" = ( -/obj/item/clothing/gloves/color/latex, -/obj/item/clothing/suit/apron/surgical, -/obj/item/clothing/mask/surgical, -/obj/item/surgical_drapes, -/obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, /obj/effect/turf_decal/tile/blue{ dir = 1 }, +/obj/structure/closet/secure_closet/medical2, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsO" = ( -/obj/item/retractor, -/obj/item/hemostat, /obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -54040,14 +54034,16 @@ /obj/effect/turf_decal/tile/blue{ dir = 4 }, +/obj/item/clothing/gloves/color/latex{ + step_y = 10 + }, +/obj/item/clothing/suit/apron/surgical, +/obj/item/clothing/mask/surgical{ + step_y = -6 + }, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsP" = ( -/obj/item/circular_saw, -/obj/item/surgicaldrill{ - pixel_y = 5 - }, -/obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ dir = 1 }, @@ -54061,11 +54057,10 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/limbgrower, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsQ" = ( -/obj/item/scalpel, -/obj/item/cautery, /obj/structure/table/reinforced, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -54079,6 +54074,13 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/item/clothing/gloves/color/latex{ + step_y = 10 + }, +/obj/item/clothing/suit/apron/surgical, +/obj/item/clothing/mask/surgical{ + step_y = -6 + }, /turf/open/floor/plasteel/white, /area/medical/surgery) "dsR" = ( @@ -55236,9 +55238,6 @@ /turf/open/floor/plasteel/white, /area/medical/surgery) "dvF" = ( -/obj/machinery/computer/operating{ - dir = 4 - }, /obj/structure/cable/white{ icon_state = "4-8" }, @@ -55255,10 +55254,11 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/table/reinforced, +/obj/item/storage/backpack/duffelbag/med/surgery, /turf/open/floor/plasteel, /area/medical/surgery) "dvG" = ( -/obj/structure/table/optable, /obj/effect/decal/cleanable/blood/old, /obj/structure/cable/white{ icon_state = "2-8" @@ -55279,17 +55279,19 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/structure/table/reinforced, +/obj/item/reagent_containers/spray/cleaner, /turf/open/floor/plasteel, /area/medical/surgery) "dvH" = ( -/obj/machinery/holopad, /obj/structure/cable/white{ icon_state = "4-8" }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, -/obj/effect/turf_decal/bot, +/obj/structure/table/reinforced, +/obj/item/storage/backpack/duffelbag/med/surgery, /turf/open/floor/plasteel, /area/medical/surgery) "dvI" = ( @@ -55963,21 +55965,21 @@ /turf/open/floor/plasteel/white, /area/medical/surgery) "dxm" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, /turf/open/floor/plasteel/white, /area/medical/surgery) "dxn" = ( /obj/structure/cable/white{ icon_state = "1-2" }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 8 - }, -/turf/open/floor/plasteel/white, +/obj/machinery/holopad, +/obj/effect/turf_decal/bot, +/turf/open/floor/plasteel, /area/medical/surgery) "dxo" = ( /obj/effect/turf_decal/tile/blue, @@ -56576,7 +56578,6 @@ /turf/open/floor/plasteel/white, /area/medical/surgery) "dyG" = ( -/obj/structure/closet/secure_closet/medical2, /obj/structure/sign/poster/official/cleanliness{ pixel_x = -32 }, @@ -56590,25 +56591,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/turf/open/floor/plasteel/dark, -/area/medical/surgery) -"dyH" = ( +/obj/machinery/computer/operating{ + dir = 1 + }, /obj/machinery/status_display/ai{ pixel_y = -32 }, -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 1 - }, -/obj/effect/turf_decal/tile/neutral, -/obj/effect/turf_decal/tile/neutral{ - dir = 4 - }, -/obj/effect/turf_decal/tile/neutral{ - dir = 8 - }, /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyI" = ( @@ -56634,12 +56622,10 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, +/obj/structure/closet/crate/freezer/blood, /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyJ" = ( -/obj/machinery/status_display/evac{ - pixel_y = -32 - }, /obj/effect/turf_decal/tile/neutral{ dir = 1 }, @@ -56650,7 +56636,7 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/structure/closet/crate/freezer/blood, +/obj/structure/table/optable, /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyK" = ( @@ -56669,7 +56655,12 @@ /obj/effect/turf_decal/tile/neutral{ dir = 8 }, -/obj/machinery/limbgrower, +/obj/machinery/computer/operating{ + dir = 1 + }, +/obj/machinery/status_display/evac{ + pixel_y = -32 + }, /turf/open/floor/plasteel/dark, /area/medical/surgery) "dyL" = ( @@ -177188,7 +177179,7 @@ dsO dtR dvF dxm -dyH +dyJ dma cPy cPy diff --git a/code/__DEFINES/loadout.dm b/code/__DEFINES/loadout.dm index 792708b5bb..182e58c1f7 100644 --- a/code/__DEFINES/loadout.dm +++ b/code/__DEFINES/loadout.dm @@ -7,6 +7,7 @@ //backpack #define LOADOUT_CATEGORY_BACKPACK "In backpack" #define LOADOUT_SUBCATEGORY_BACKPACK_GENERAL "General" //basically anything that there's not enough of to have its own subcategory +#define LOADOUT_SUBCATEGORY_BACKPACK_ACCESSORIES "Accessories" //maybe one day someone will make loadouts have accessory compatibility #define LOADOUT_SUBCATEGORY_BACKPACK_TOYS "Toys" //neck #define LOADOUT_CATEGORY_NECK "Neck" diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index 36f427a1bb..cd4e609e7a 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -289,7 +289,8 @@ // MINOR TWEAKS/MISC #define AGE_MIN 18 // youngest a character can be // CITADEL EDIT - 17 --> 18 -#define AGE_MAX 85 // oldest a character can be +#define AGE_MAX 85 // oldest a character can be randomly generated +#define AGE_MAX_INPUT 85 // oldest a character's age can be manually set #define WIZARD_AGE_MIN 30 // youngest a wizard can be #define APPRENTICE_AGE_MIN 29 // youngest an apprentice can be #define SHOES_SLOWDOWN 0 // How much shoes slow you down by default. Negative values speed you up diff --git a/code/__HELPERS/weakref.dm b/code/__HELPERS/weakref.dm new file mode 100644 index 0000000000..0b007332ef --- /dev/null +++ b/code/__HELPERS/weakref.dm @@ -0,0 +1,2 @@ +/// Checks if potential_weakref is a weakref of thing. +#define IS_WEAKREF_OF(thing, potential_weakref) (istype(thing, /datum) && !isnull(potential_weakref) && thing.weak_reference == potential_weakref) diff --git a/code/_globalvars/lists/loadout_categories.dm b/code/_globalvars/lists/loadout_categories.dm index 4a61a94dc7..5dd7220676 100644 --- a/code/_globalvars/lists/loadout_categories.dm +++ b/code/_globalvars/lists/loadout_categories.dm @@ -1,5 +1,5 @@ GLOBAL_LIST_INIT(loadout_categories, list( - LOADOUT_CATEGORY_BACKPACK = list(LOADOUT_SUBCATEGORY_BACKPACK_GENERAL, LOADOUT_SUBCATEGORY_BACKPACK_TOYS), + LOADOUT_CATEGORY_BACKPACK = list(LOADOUT_SUBCATEGORY_BACKPACK_GENERAL, LOADOUT_SUBCATEGORY_BACKPACK_ACCESSORIES, LOADOUT_SUBCATEGORY_BACKPACK_TOYS), LOADOUT_CATEGORY_NECK = list(LOADOUT_SUBCATEGORY_NECK_GENERAL, LOADOUT_SUBCATEGORY_NECK_TIE, LOADOUT_SUBCATEGORY_NECK_SCARVES), LOADOUT_CATEGORY_MASK = LOADOUT_SUBCATEGORIES_NONE, LOADOUT_CATEGORY_HANDS = LOADOUT_SUBCATEGORIES_NONE, diff --git a/code/controllers/subsystem/throwing.dm b/code/controllers/subsystem/throwing.dm index 2ff1e284d0..47efc967ac 100644 --- a/code/controllers/subsystem/throwing.dm +++ b/code/controllers/subsystem/throwing.dm @@ -87,6 +87,7 @@ SUBSYSTEM_DEF(throwing) if(HAS_TRAIT_FROM(thrownthing, TRAIT_SPOOKY_THROW, "revenant")) REMOVE_TRAIT(thrownthing, TRAIT_SPOOKY_THROW, "revenant") SSthrowing.processing -= thrownthing + SSthrowing.currentrun -= thrownthing thrownthing.throwing = null thrownthing = null target = null diff --git a/code/datums/action.dm b/code/datums/action.dm index 304aa47baa..b34cafc03f 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -43,8 +43,7 @@ if(owner) Remove(owner) target = null - qdel(button) - button = null + QDEL_NULL(button) return ..() /datum/action/proc/Grant(mob/M) diff --git a/code/datums/wounds/_scars.dm b/code/datums/wounds/_scars.dm index 3fb6546edb..0edcf65b42 100644 --- a/code/datums/wounds/_scars.dm +++ b/code/datums/wounds/_scars.dm @@ -28,6 +28,8 @@ LAZYREMOVE(limb.scars, src) if(victim) LAZYREMOVE(victim.all_scars, src) + limb = null + victim = null . = ..() /** @@ -45,6 +47,8 @@ qdel(src) return limb = BP + RegisterSignal(limb, COMSIG_PARENT_QDELETING, .proc/limb_gone) + severity = W.severity if(limb.owner) victim = limb.owner @@ -84,6 +88,7 @@ return limb = BP + RegisterSignal(limb, COMSIG_PARENT_QDELETING, .proc/limb_gone) src.severity = severity LAZYADD(limb.scars, src) if(BP.owner) @@ -102,6 +107,10 @@ visibility = 7 return TRUE +/datum/scar/proc/limb_gone() + SIGNAL_HANDLER + qdel(src) + /// What will show up in examine_more() if this scar is visible /datum/scar/proc/get_examine_description(mob/viewer) if(!victim || !is_visible(viewer)) diff --git a/code/datums/wounds/_wounds.dm b/code/datums/wounds/_wounds.dm index 6cab8818ee..a2c4a70380 100644 --- a/code/datums/wounds/_wounds.dm +++ b/code/datums/wounds/_wounds.dm @@ -73,8 +73,6 @@ /// What status effect we assign on application var/status_effect_type - /// The status effect we're linked to - var/datum/status_effect/linked_status_effect /// If we're operating on this wound and it gets healed, we'll nix the surgery too var/datum/surgery/attached_surgery /// if you're a lazy git and just throw them in cryo, the wound will go away after accumulating severity * 25 power @@ -127,12 +125,13 @@ return victim = L.owner + RegisterSignal(victim, COMSIG_PARENT_QDELETING, .proc/null_victim) limb = L LAZYADD(victim.all_wounds, src) LAZYADD(limb.wounds, src) limb.update_wounds() if(status_effect_type) - linked_status_effect = victim.apply_status_effect(status_effect_type, src) + victim.apply_status_effect(status_effect_type, src) SEND_SIGNAL(victim, COMSIG_CARBON_GAIN_WOUND, src, limb) victim.emote("pain") if(!victim.alerts["wound"]) // only one alert is shared between all of the wounds @@ -161,6 +160,14 @@ wound_injury(old_wound) second_wind() +/datum/wound/proc/null_victim() + SIGNAL_HANDLER + victim = null + +/datum/wound/proc/source_died() + SIGNAL_HANDLER + qdel(src) + /// Remove the wound from whatever it's afflicting, and cleans up whateverstatus effects it had or modifiers it had on interaction times. ignore_limb is used for detachments where we only want to forget the victim /datum/wound/proc/remove_wound(ignore_limb, replaced = FALSE) //TODO: have better way to tell if we're getting removed without replacement (full heal) scar stuff diff --git a/code/game/area/areas.dm b/code/game/area/areas.dm index 24b49a3af7..2c34c67c58 100644 --- a/code/game/area/areas.dm +++ b/code/game/area/areas.dm @@ -15,7 +15,10 @@ var/area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA | CULT_PERMITTED - var/fire = null + ///Do we have an active fire alarm? + var/fire = FALSE + ///How many fire alarm sources do we have? + var/triggered_firealarms = 0 ///Whether there is an atmos alarm in this area var/atmosalm = FALSE var/poweralm = FALSE @@ -443,7 +446,18 @@ GLOBAL_LIST_EMPTY(teleportlocs) START_PROCESSING(SSobj, src) /area/proc/firereset(obj/source) - if (fire) + var/should_reset_alarms = fire + if(source) + if(istype(source, /obj/machinery/firealarm)) + var/obj/machinery/firealarm/alarm = source + if(alarm.triggered) + alarm.triggered = FALSE + triggered_firealarms -= 1 + if(triggered_firealarms > 0) + should_reset_alarms = FALSE + should_reset_alarms = should_reset_alarms & power_environ //No resetting if there's no power + + if (should_reset_alarms) // if there's a source, make sure there's no fire alarms left set_fire_alarm_effects(FALSE) ModifyFiredoors(TRUE) @@ -463,6 +477,18 @@ GLOBAL_LIST_EMPTY(teleportlocs) STOP_PROCESSING(SSobj, src) +///Get rid of any dangling camera refs +/area/proc/clear_camera(obj/machinery/camera/cam) + LAZYREMOVE(cameras, cam) + for (var/mob/living/silicon/aiPlayer as anything in GLOB.silicon_mobs) + aiPlayer.freeCamera(src, cam) + for (var/obj/machinery/computer/station_alert/comp as anything in GLOB.alert_consoles) + comp.freeCamera(src, cam) + for (var/mob/living/simple_animal/drone/drone_on as anything in GLOB.drones_list) + drone_on.freeCamera(src, cam) + for(var/datum/computer_file/program/alarm_monitor/monitor as anything in GLOB.alarmdisplay) + monitor.freeCamera(src, cam) + /area/process() if(firedoors_last_closed_on + 100 < world.time) //every 10 seconds ModifyFiredoors(FALSE) diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index bace332ef2..1e41b726df 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -117,11 +117,16 @@ . = ..() + //We add ourselves to this list, best to clear it out + // LAZYCLEARLIST(area_sensitive_contents) + for(var/movable_content in contents) qdel(movable_content) moveToNullspace() + vis_contents.Cut() + /atom/movable/proc/update_emissive_block() if(blocks_emissive != EMISSIVE_BLOCK_GENERIC) return diff --git a/code/game/machinery/Beacon.dm b/code/game/machinery/Beacon.dm index d708af7d7a..c720668a5b 100644 --- a/code/game/machinery/Beacon.dm +++ b/code/game/machinery/Beacon.dm @@ -38,7 +38,7 @@ icon_state = "[state]" /obj/machinery/bluespace_beacon/process() - if(!Beacon) + if(QDELETED(Beacon)) //Don't move it out of nullspace BACK INTO THE GAME for the love of god var/turf/T = loc Beacon = new(T) Beacon.invisibility = INVISIBILITY_MAXIMUM diff --git a/code/game/machinery/camera/camera.dm b/code/game/machinery/camera/camera.dm index 9a23cc86fb..6e794b8072 100644 --- a/code/game/machinery/camera/camera.dm +++ b/code/game/machinery/camera/camera.dm @@ -81,15 +81,15 @@ if(can_use()) toggle_cam(null, 0) //kick anyone viewing out and remove from the camera chunks GLOB.cameranet.cameras -= src + cancelCameraAlarm() if(isarea(myarea)) - LAZYREMOVE(myarea.cameras, src) + myarea.clear_camera(src) QDEL_NULL(assembly) if(bug) - bug.bugged_cameras -= src.c_tag + bug.bugged_cameras -= c_tag if(bug.current == src) bug.current = null bug = null - cancelCameraAlarm() return ..() /obj/machinery/camera/emp_act(severity) diff --git a/code/game/machinery/computer/station_alert.dm b/code/game/machinery/computer/station_alert.dm index 0671100623..df84d5a26a 100644 --- a/code/game/machinery/computer/station_alert.dm +++ b/code/game/machinery/computer/station_alert.dm @@ -33,31 +33,46 @@ return data -/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/A, O, obj/source) +/obj/machinery/computer/station_alert/proc/triggerAlarm(class, area/home, cameras, obj/source) if(source.z != z) return if(stat & (BROKEN)) return - var/list/L = alarms[class] - for(var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] if (!(source in sources)) sources += source - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if(O && islist(O)) - CL = O - if (CL.len == 1) - C = CL[1] - else if(O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C ? C : O), list(source)) - return 1 + return TRUE + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) + return TRUE + +/obj/machinery/computer/station_alert/proc/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null /obj/machinery/computer/station_alert/proc/cancelAlarm(class, area/A, obj/origin) if(stat & (BROKEN)) diff --git a/code/game/machinery/embedded_controller/embedded_controller_base.dm b/code/game/machinery/embedded_controller/embedded_controller_base.dm index 4526a75f32..0a0a4e08f3 100644 --- a/code/game/machinery/embedded_controller/embedded_controller_base.dm +++ b/code/game/machinery/embedded_controller/embedded_controller_base.dm @@ -3,6 +3,10 @@ var/state var/obj/machinery/embedded_controller/master +/datum/computer/file/embedded_program/Destroy() + master = null + . = ..() + /datum/computer/file/embedded_program/proc/post_signal(datum/signal/signal, comm_line) if(master) master.post_signal(signal, comm_line) @@ -25,6 +29,11 @@ var/on = TRUE +/obj/machinery/embedded_controller/Destroy() + if(program) + QDEL_NULL(program) + . = ..() + /obj/machinery/embedded_controller/ui_interact(mob/user) . = ..() user.set_machine(src) diff --git a/code/game/machinery/firealarm.dm b/code/game/machinery/firealarm.dm index cca67030ed..a0da29b2d3 100644 --- a/code/game/machinery/firealarm.dm +++ b/code/game/machinery/firealarm.dm @@ -33,8 +33,10 @@ var/detecting = 1 var/buildstage = 2 // 2 = complete, 1 = no wires, 0 = circuit gone - var/last_alarm = 0 + COOLDOWN_DECLARE(last_alarm) var/area/myarea = null + //Has this firealarm been triggered by its enviroment? + var/triggered = FALSE /obj/machinery/firealarm/Initialize(mapload, dir, building) . = ..() @@ -50,6 +52,7 @@ LAZYADD(myarea.firealarms, src) /obj/machinery/firealarm/Destroy() + myarea.firereset(src) LAZYREMOVE(myarea.firealarms, src) return ..() @@ -102,7 +105,7 @@ . += mutable_appearance(icon, "fire_on") . += emissive_appearance(icon, "fire_on") - if(!panel_open && detecting) //It just looks horrible with the panel open + if(!panel_open && detecting && triggered) //It just looks horrible with the panel open . += "fire_detected" . += mutable_appearance(icon, "fire_detected") . += emissive_appearance(icon, "fire_detected") //Pain @@ -129,14 +132,14 @@ return TRUE /obj/machinery/firealarm/temperature_expose(datum/gas_mixture/air, temperature, volume) - if((temperature > T0C + 200 || temperature < BODYTEMP_COLD_DAMAGE_LIMIT) && (last_alarm+FIREALARM_COOLDOWN < world.time) && !(obj_flags & EMAGGED) && detecting && !stat) + if((temperature > T0C + 200 || temperature < BODYTEMP_COLD_DAMAGE_LIMIT) && COOLDOWN_FINISHED(src, last_alarm) && !(obj_flags & EMAGGED) && detecting && !stat) alarm() - ..() + return ..() /obj/machinery/firealarm/proc/alarm(mob/user) - if(!is_operational() || (last_alarm+FIREALARM_COOLDOWN > world.time)) + if(!is_operational() || !COOLDOWN_FINISHED(src, last_alarm)) return - last_alarm = world.time + COOLDOWN_START(src, last_alarm, FIREALARM_COOLDOWN) var/area/A = get_base_area(src) A.firealert(src) playsound(loc, 'goon/sound/machinery/FireAlarm.ogg', 75) @@ -147,7 +150,7 @@ if(!is_operational()) return var/area/A = get_base_area(src) - A.firereset(src) + A.firereset() if(user) log_game("[user] reset a fire alarm at [COORD(src)]") diff --git a/code/game/machinery/mechlaunchpad.dm b/code/game/machinery/mechlaunchpad.dm index a2ac2efb3f..c6872edda0 100644 --- a/code/game/machinery/mechlaunchpad.dm +++ b/code/game/machinery/mechlaunchpad.dm @@ -24,6 +24,7 @@ connected_console = null for(var/obj/machinery/computer/mechpad/console in consoles) console.mechpads -= src + GLOB.mechpad_list -= src return ..() /obj/machinery/mechpad/screwdriver_act(mob/user, obj/item/tool) diff --git a/code/game/objects/effects/decals/cleanable/gibs.dm b/code/game/objects/effects/decals/cleanable/gibs.dm index f57daac309..a17b4d7d50 100644 --- a/code/game/objects/effects/decals/cleanable/gibs.dm +++ b/code/game/objects/effects/decals/cleanable/gibs.dm @@ -11,6 +11,7 @@ var/body_colors = "#e3ba84" //a default color just in case. var/gibs_reagent_id = /datum/reagent/liquidgibs var/gibs_bloodtype = "A+" + turf_loc_check = FALSE /obj/effect/decal/cleanable/blood/gibs/Initialize(mapload, list/datum/disease/diseases, list/blood_data) . = ..() @@ -22,6 +23,9 @@ add_blood_DNA(list("Non-human DNA" = gibs_bloodtype), diseases) update_icon() +/obj/effect/decal/cleanable/blood/gibs/replace_decal(obj/effect/decal/cleanable/C) + return FALSE //Never fail to place us + /obj/effect/decal/cleanable/blood/gibs/update_icon() add_atom_colour(blood_DNA_to_color(), FIXED_COLOUR_PRIORITY) cut_overlays() diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index e16de56465..078839bcd1 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -725,6 +725,26 @@ def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high) needs_anchored = FALSE +/obj/item/circuitboard/machine/chem_dispenser/fullupgrade + build_path = /obj/machinery/chem_dispenser/fullupgrade + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + +/obj/item/circuitboard/machine/chem_dispenser/mutagensaltpeter + build_path = /obj/machinery/chem_dispenser/mutagensaltpeter + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + /obj/item/circuitboard/machine/chem_dispenser/apothecary name = "Apotechary Chem Dispenser (Machine Board)" build_path = /obj/machinery/chem_dispenser/apothecary @@ -740,7 +760,13 @@ name = "Reagent Synthesizer (Abductor Machine Board)" icon_state = "abductor_mod" build_path = /obj/machinery/chem_dispenser/abductor - def_components = list(/obj/item/stock_parts/cell = /obj/item/stock_parts/cell/high) + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) needs_anchored = FALSE /obj/item/circuitboard/machine/chem_heater @@ -1175,11 +1201,31 @@ icon_state = "service" build_path = /obj/machinery/chem_dispenser/drinks +/obj/item/circuitboard/machine/chem_dispenser/drinks/fullupgrade + build_path = /obj/machinery/chem_dispenser/drinks/fullupgrade + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + /obj/item/circuitboard/machine/chem_dispenser/drinks/beer name = "Booze Dispenser (Machine Board)" icon_state = "service" build_path = /obj/machinery/chem_dispenser/drinks/beer +/obj/item/circuitboard/machine/chem_dispenser/drinks/beer/fullupgrade + build_path = /obj/machinery/chem_dispenser/drinks/beer/fullupgrade + req_components = list( + /obj/item/stock_parts/matter_bin/bluespace = 2, + /obj/item/stock_parts/capacitor/quadratic = 2, + /obj/item/stock_parts/manipulator/femto = 2, + /obj/item/stack/sheet/glass = 1, + /obj/item/stock_parts/cell/bluespace = 1, + ) + /obj/item/circuitboard/machine/chem_master/condi name = "CondiMaster 3000 (Machine Board)" icon_state = "service" diff --git a/code/game/objects/items/devices/beacon.dm b/code/game/objects/items/devices/beacon.dm index 86aa787c3e..cf59551bb8 100644 --- a/code/game/objects/items/devices/beacon.dm +++ b/code/game/objects/items/devices/beacon.dm @@ -17,7 +17,7 @@ icon_state = "beacon-off" /obj/item/beacon/Destroy() - GLOB.teleportbeacons.Remove(src) + GLOB.teleportbeacons -= src return ..() /obj/item/beacon/attack_self(mob/user) @@ -27,7 +27,7 @@ GLOB.teleportbeacons += src else icon_state = "beacon-off" - GLOB.teleportbeacons.Remove(src) + GLOB.teleportbeacons -= src to_chat(user, "You [enabled ? "enable" : "disable"] the beacon.") return diff --git a/code/game/objects/items/devices/taperecorder.dm b/code/game/objects/items/devices/taperecorder.dm index 958877d42d..98f19a2f6e 100644 --- a/code/game/objects/items/devices/taperecorder.dm +++ b/code/game/objects/items/devices/taperecorder.dm @@ -28,6 +28,10 @@ mytape = new starting_tape_type(src) update_icon() +/obj/item/taperecorder/Destroy() + // QDEL_NULL(soundloop) + QDEL_NULL(mytape) + return ..() /obj/item/taperecorder/examine(mob/user) . = ..() diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index 46db798c84..650fdf040b 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -139,7 +139,7 @@ /obj/structure/closet/crate/freezer/Destroy() recursive_organ_check(src) - ..() + return ..() /obj/structure/closet/crate/freezer/Initialize(mapload) . = ..() diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index dc44ac728f..b6be7f1fe1 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -137,6 +137,8 @@ GLOBAL_LIST_EMPTY(station_turfs) requires_activation = FALSE ..() + vis_contents.Cut() + /turf/on_attack_hand(mob/user) user.Move_Pulled(src) diff --git a/code/modules/atmospherics/gasmixtures/reactions.dm b/code/modules/atmospherics/gasmixtures/reactions.dm index b39a181a38..f60e853aed 100644 --- a/code/modules/atmospherics/gasmixtures/reactions.dm +++ b/code/modules/atmospherics/gasmixtures/reactions.dm @@ -760,6 +760,8 @@ /datum/gas_reaction/hagedorn/react(datum/gas_mixture/air, datum/holder) var/initial_energy = air.thermal_energy() + if(air.get_moles(GAS_QCD)) + return for(var/g in air.get_gases()) air.set_moles(g, 0) var/amount = initial_energy / (air.return_temperature() * GLOB.gas_data.specific_heats[GAS_QCD]) diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index 66b8277273..90407264ad 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -238,6 +238,8 @@ SSradio.remove_object(src, frequency) qdel(wires) wires = null + var/area/ourarea = get_area(src) + ourarea.atmosalert(FALSE, src) return ..() /obj/machinery/airalarm/examine(mob/user) diff --git a/code/modules/cargo/console.dm b/code/modules/cargo/console.dm index 390f02d419..e7854d47cf 100644 --- a/code/modules/cargo/console.dm +++ b/code/modules/cargo/console.dm @@ -40,7 +40,7 @@ /obj/machinery/computer/cargo/Destroy() QDEL_NULL(radio) - ..() + return ..() /obj/machinery/computer/cargo/proc/get_export_categories() . = EXPORT_CARGO diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 622f789870..98ee55bc17 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -1746,9 +1746,9 @@ GLOBAL_LIST_EMPTY(preferences_datums) to_chat(user, "Invalid name. Your name should be at least 2 and at most [MAX_NAME_LEN] characters long. It may only contain the characters A-Z, a-z, -, ' and .") if("age") - var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX])", "Character Preference") as num|null + var/new_age = input(user, "Choose your character's age:\n([AGE_MIN]-[AGE_MAX_INPUT])", "Character Preference") as num|null if(new_age) - age = max(min( round(text2num(new_age)), AGE_MAX),AGE_MIN) + age = max(min( round(text2num(new_age)), AGE_MAX_INPUT),AGE_MIN) if("security_records") var/rec = stripped_multiline_input(usr, "Set your security record note section. This should be IC!", "Security Records", html_decode(security_records), MAX_FLAVOR_LEN, TRUE) diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm index 714025e6e2..3f95e699dc 100644 --- a/code/modules/client/preferences_savefile.dm +++ b/code/modules/client/preferences_savefile.dm @@ -905,7 +905,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car shirt_color = sanitize_hexcolor(shirt_color, 6, FALSE, initial(shirt_color)) socks = sanitize_inlist(socks, GLOB.socks_list) socks_color = sanitize_hexcolor(socks_color, 6, FALSE, initial(socks_color)) - age = sanitize_integer(age, AGE_MIN, AGE_MAX, initial(age)) + age = sanitize_integer(age, AGE_MIN, AGE_MAX_INPUT, initial(age)) hair_color = sanitize_hexcolor(hair_color, 6, FALSE) facial_hair_color = sanitize_hexcolor(facial_hair_color, 6, FALSE) grad_style = sanitize_inlist(grad_style, GLOB.hair_gradients_list, "None") diff --git a/code/modules/clothing/gloves/tacklers.dm b/code/modules/clothing/gloves/tacklers.dm index 754a72ff0c..b99eca1a61 100644 --- a/code/modules/clothing/gloves/tacklers.dm +++ b/code/modules/clothing/gloves/tacklers.dm @@ -25,6 +25,10 @@ /// See: [/datum/component/tackler/var/skill_mod] var/skill_mod = 1 +/obj/item/clothing/gloves/tackler/Destroy() + tackler = null + return ..() + /obj/item/clothing/gloves/tackler/equipped(mob/user, slot) . = ..() if(!ishuman(user)) @@ -34,12 +38,12 @@ var/mob/living/carbon/human/H = user tackler = H.AddComponent(/datum/component/tackler, stamina_cost=tackle_stam_cost, base_knockdown = base_knockdown, range = tackle_range, speed = tackle_speed, skill_mod = skill_mod, min_distance = min_distance) else - qdel(tackler) // Only wearing it! + QDEL_NULL(tackler) // Only wearing it! /obj/item/clothing/gloves/tackler/dropped(mob/user) . = ..() if(tackler) - qdel(tackler) + QDEL_NULL(tackler) /obj/item/clothing/gloves/tackler/dolphin name = "dolphin gloves" diff --git a/code/modules/clothing/under/accessories.dm b/code/modules/clothing/under/accessories.dm index 4d967be1eb..6d477a0590 100644 --- a/code/modules/clothing/under/accessories.dm +++ b/code/modules/clothing/under/accessories.dm @@ -65,7 +65,7 @@ /obj/item/clothing/accessory/proc/on_uniform_dropped(obj/item/clothing/under/U, user) return -/obj/item/clothing/accessory/AltClick(mob/user) +/obj/item/clothing/accessory/CtrlClick(mob/user) . = ..() if(istype(user) && user.canUseTopic(src, BE_CLOSE, ismonkey(user))) if(initial(above_suit)) @@ -77,7 +77,7 @@ . = ..() . += "\The [src] can be attached to a uniform. Alt-click to remove it once attached." if(initial(above_suit)) - . += "\The [src] can be worn above or below your suit. Alt-click to toggle." + . += "\The [src] can be worn above or below your suit. Ctrl-click to toggle." ////////////// //Waistcoats// @@ -557,3 +557,18 @@ obj_flags = UNIQUE_RENAME custom_materials = list(/datum/material/iron=100) resistance_flags = FIRE_PROOF + + +/obj/item/clothing/accessory/pride + name = "pride pin" + desc = "A Nanotrasen Diversity & Inclusion Center-sponsored holographic pin to show off your pride of sexuality or gender identity, reminding the crew of their unwavering commitment to equity, diversity, and inclusion!" + icon_state = "pride" + above_suit = TRUE + obj_flags = UNIQUE_RENAME + unique_reskin = list("Rainbow Pride" = "pride", + "Bisexual Pride" = "pride_bi", + "Pansexual Pride" = "pride_pan", + "Asexual Pride" = "pride_ace", + "Non-binary Pride" = "pride_enby", + "Transgender Pride" = "pride_trans", + ) diff --git a/code/modules/lighting/lighting_source.dm b/code/modules/lighting/lighting_source.dm index 324e6c1e99..0a378fadc2 100644 --- a/code/modules/lighting/lighting_source.dm +++ b/code/modules/lighting/lighting_source.dm @@ -63,6 +63,10 @@ if (needs_update) GLOB.lighting_update_lights -= src + top_atom = null + source_atom = null + source_turf = null + pixel_turf = null . = ..() // Yes this doesn't align correctly on anything other than 4 width tabs. diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm index 6598dd6a54..a5ea6e1c89 100644 --- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm +++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm @@ -17,10 +17,6 @@ Doesn't work on other aliens/AI.*/ action_icon_state = "spell_default" action_background_icon_state = "bg_alien" -/obj/effect/proc_holder/alien/Initialize(mapload) - . = ..() - action = new(src) - /obj/effect/proc_holder/alien/Trigger(mob/living/carbon/user, skip_cost_check = FALSE) if(!istype(user)) return TRUE diff --git a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm index 4712fe4475..9ecf25a3a6 100644 --- a/code/modules/mob/living/carbon/human/species_types/jellypeople.dm +++ b/code/modules/mob/living/carbon/human/species_types/jellypeople.dm @@ -423,7 +423,7 @@ coldmod = 3 heatmod = 1 burnmod = 1 - + balance_point_values = TRUE allowed_limb_ids = list(SPECIES_SLIME,SPECIES_STARGAZER,SPECIES_SLIME_LUMI) ///////////////////////////////////LUMINESCENTS////////////////////////////////////////// diff --git a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm index 5fb816867f..3b7ca3fa0a 100644 --- a/code/modules/mob/living/carbon/human/species_types/plasmamen.dm +++ b/code/modules/mob/living/carbon/human/species_types/plasmamen.dm @@ -26,6 +26,7 @@ wings_icons = SPECIES_WINGS_SKELETAL ass_image = 'icons/ass/assplasma.png' + balance_point_values = TRUE blacklisted_quirks = list(/datum/quirk/paper_skin) /datum/species/plasmaman/spec_life(mob/living/carbon/human/H) diff --git a/code/modules/mob/living/carbon/human/species_types/skeletons.dm b/code/modules/mob/living/carbon/human/species_types/skeletons.dm index 9c52a6a9d1..0cd39f8128 100644 --- a/code/modules/mob/living/carbon/human/species_types/skeletons.dm +++ b/code/modules/mob/living/carbon/human/species_types/skeletons.dm @@ -17,6 +17,7 @@ species_category = SPECIES_CATEGORY_SKELETON //they have their own category that's disassociated from undead, paired with plasmapeople wings_icons = SPECIES_WINGS_SKELETAL + balance_point_values = TRUE blacklisted_quirks = list(/datum/quirk/paper_skin) /datum/species/skeleton/New() @@ -36,6 +37,7 @@ id = SPECIES_SKELETON_SPACE limbs_id = SPECIES_SKELETON blacklisted = 1 + balance_point_values = FALSE inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT, TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER) /datum/species/skeleton/space/check_roundstart_eligible() diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm index 5ba5f2431d..08098b818f 100644 --- a/code/modules/mob/living/silicon/ai/ai.dm +++ b/code/modules/mob/living/silicon/ai/ai.dm @@ -511,43 +511,61 @@ call_bot_cooldown = 0 -/mob/living/silicon/ai/triggerAlarm(class, area/A, O, obj/alarmsource) - if(alarmsource.z != z) +/mob/living/silicon/ai/triggerAlarm(class, area/home, cameras, obj/source) + if(source.z != z) return - var/list/L = alarms[class] - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] - if (!(alarmsource in sources)) - sources += alarmsource - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if (O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if (O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C) ? C : O, list(alarmsource)) - if (O) - if (C && C.can_use()) - queueAlarm("--- [class] alarm detected in [A.name]! ([C.c_tag])", class) - else if (CL && CL.len) + if (!(source in sources)) + sources += source + return TRUE + + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) + + if (cameras) + if (cam?.can_use()) + queueAlarm("--- [class] alarm detected in [home.name]! ([cam.c_tag])", class) + else if (our_cams?.len) var/foo = 0 var/dat2 = "" - for (var/obj/machinery/camera/I in CL) + for (var/obj/machinery/camera/I in our_cams) dat2 += text("[][]", (!foo) ? "" : " | ", I.c_tag) //I'm not fixing this shit... foo = 1 - queueAlarm(text ("--- [] alarm detected in []! ([])", class, A.name, dat2), class) + queueAlarm(text ("--- [] alarm detected in []! ([])", class, home.name, dat2), class) else - queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class) + queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, home.name), class) else - queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, A.name), class) - if (viewalerts) ai_alerts() + queueAlarm(text("--- [] alarm detected in []! (No Camera)", class, home.name), class) + if (viewalerts) + ai_alerts() return 1 +/mob/living/silicon/ai/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null + /mob/living/silicon/ai/cancelAlarm(class, area/A, obj/origin) var/list/L = alarms[class] var/cleared = 0 diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 2392ee03e0..232c5b4195 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -262,31 +262,47 @@ /mob/living/silicon/robot/restrained(ignore_grab) . = 0 -/mob/living/silicon/robot/triggerAlarm(class, area/A, O, obj/alarmsource) - if(alarmsource.z != z) +/mob/living/silicon/robot/triggerAlarm(class, area/home, cameras, obj/source) + if(source.z != z) return if(stat == DEAD) return 1 - var/list/L = alarms[class] - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] - if (!(alarmsource in sources)) - sources += alarmsource + if (!(source in sources)) + sources += source return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if (O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if (O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C) ? C : O, list(alarmsource)) - queueAlarm(text("--- [class] alarm detected in [A.name]!"), class) + + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) + queueAlarm(text("--- [class] alarm detected in [home.name]!"), class) return TRUE +/mob/living/silicon/robot/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null + /mob/living/silicon/robot/cancelAlarm(class, area/A, obj/origin) var/list/L = alarms[class] var/cleared = 0 diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 76bfcf6eba..467b61dc21 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -87,6 +87,9 @@ /mob/living/silicon/proc/cancelAlarm() return +/mob/living/silicon/proc/freeCamera() + return + /mob/living/silicon/proc/triggerAlarm() return diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 203ac5f846..1320c13085 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -194,9 +194,9 @@ GLOB.bots_list -= src if(paicard) ejectpai() - qdel(Radio) - qdel(access_card) - qdel(bot_core) + QDEL_NULL(Radio) + QDEL_NULL(access_card) + QDEL_NULL(bot_core) return ..() /mob/living/simple_animal/bot/bee_friendly() diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index d35f12b0f6..6b524f6114 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -231,20 +231,26 @@ adjustBruteLoss(heavy_emp_damage) to_chat(src, "HeAV% DA%^MMA+G TO I/O CIR!%UUT!") -/mob/living/simple_animal/drone/proc/triggerAlarm(class, area/A, O, obj/alarmsource) - if(alarmsource.z != z) +/mob/living/simple_animal/drone/proc/triggerAlarm(class, area/home, cameras, obj/source) + if(source.z != z) return - if(stat != DEAD) - var/list/L = src.alarms[class] - for (var/I in L) - if (I == A.name) - var/list/alarm = L[I] - var/list/sources = alarm[2] - if (!(alarmsource in sources)) - sources += alarmsource - return - L[A.name] = list(A, list(alarmsource)) - to_chat(src, "--- [class] alarm detected in [A.name]!") + if(stat == DEAD) + return + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] + var/list/sources = alarm[3] + if (!(source in sources)) + sources += source + return TRUE + + our_sort[home.name] = list(home, list(source)) + to_chat(src, "--- [class] alarm detected in [home.name]!") + +///This isn't currently needed since drones do jack shit with cameras. I hate this code so much +/mob/living/simple_animal/drone/proc/freeCamera(area/home, obj/machinery/camera/cam) + return /mob/living/simple_animal/drone/proc/cancelAlarm(class, area/A, obj/origin) if(stat != DEAD) diff --git a/code/modules/mob/mob_lists.dm b/code/modules/mob/mob_lists.dm index 14f519ec30..bd47d511e1 100644 --- a/code/modules/mob/mob_lists.dm +++ b/code/modules/mob/mob_lists.dm @@ -10,6 +10,8 @@ ///Adds the mob reference to the list of all mobs alive. If mob is cliented, it adds it to the list of all living player-mobs. /mob/proc/add_to_alive_mob_list() + if(QDELETED(src)) + return GLOB.alive_mob_list |= src if(client) add_to_current_living_players() @@ -23,6 +25,8 @@ ///Adds the mob reference to the list of all the dead mobs. If mob is cliented, it adds it to the list of all dead player-mobs. /mob/proc/add_to_dead_mob_list() + if(QDELETED(src)) + return GLOB.dead_mob_list |= src if(client) add_to_current_dead_players() diff --git a/code/modules/modular_computers/file_system/programs/alarm.dm b/code/modules/modular_computers/file_system/programs/alarm.dm index 646d9892ba..80c0c4dfa8 100644 --- a/code/modules/modular_computers/file_system/programs/alarm.dm +++ b/code/modules/modular_computers/file_system/programs/alarm.dm @@ -36,35 +36,49 @@ return data -/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/A, O, obj/source) +/datum/computer_file/program/alarm_monitor/proc/triggerAlarm(class, area/home, cameras, obj/source) if(is_station_level(source.z)) - if(!(A.type in GLOB.the_station_areas)) + if(!(home.type in GLOB.the_station_areas)) return - else if(!is_mining_level(source.z) || istype(A, /area/ruin)) + else if(!is_mining_level(source.z) || istype(home, /area/ruin)) return - var/list/L = alarms[class] - for(var/I in L) - if (I == A.name) - var/list/alarm = L[I] + var/list/our_sort = alarms[class] + for(var/areaname in our_sort) + if (areaname == home.name) + var/list/alarm = our_sort[areaname] var/list/sources = alarm[3] if (!(source in sources)) sources += source - return 1 - var/obj/machinery/camera/C = null - var/list/CL = null - if(O && istype(O, /list)) - CL = O - if (CL.len == 1) - C = CL[1] - else if(O && istype(O, /obj/machinery/camera)) - C = O - L[A.name] = list(A, (C ? C : O), list(source)) + return TRUE + + var/obj/machinery/camera/cam = null + var/list/our_cams = null + if(cameras && islist(cameras)) + our_cams = cameras + if (our_cams.len == 1) + cam = our_cams[1] + else if(cameras && istype(cameras, /obj/machinery/camera)) + cam = cameras + our_sort[home.name] = list(home, (cam ? cam : cameras), list(source)) update_alarm_display() + return TRUE - return 1 - +/datum/computer_file/program/alarm_monitor/proc/freeCamera(area/home, obj/machinery/camera/cam) + for(var/class in alarms) + var/our_area = alarms[class][home.name] + if(!our_area) + continue + var/cams = our_area[2] //Get the cameras + if(!cams) + continue + if(islist(cams)) + cams -= cam + if(length(cams) == 1) + our_area[2] = cams[1] + else + our_area[2] = null /datum/computer_file/program/alarm_monitor/proc/cancelAlarm(class, area/A, obj/origin) var/list/L = alarms[class] diff --git a/code/modules/paperwork/ticketmachine.dm b/code/modules/paperwork/ticketmachine.dm index ff1a1fd563..9683601670 100644 --- a/code/modules/paperwork/ticketmachine.dm +++ b/code/modules/paperwork/ticketmachine.dm @@ -82,15 +82,15 @@ if(M.buffer && !istype(M.buffer, /obj/machinery/ticket_machine)) return var/obj/item/assembly/control/ticket_machine/controller = device - controller.linked = M.buffer + controller.linked = WEAKREF(M.buffer) id = null controller.id = null - to_chat(user, "You've linked [src] to [controller.linked].") + to_chat(user, "You've linked [src] to [M.buffer].") /obj/item/assembly/control/ticket_machine name = "ticket machine controller" desc = "A remote controller for the HoP's ticket machine." - var/obj/machinery/ticket_machine/linked //To whom are we linked? + var/datum/weakref/linked //To whom are we linked? /obj/item/assembly/control/ticket_machine/Initialize(mapload) ..() @@ -102,7 +102,7 @@ /obj/item/assembly/control/ticket_machine/proc/find_machine() //Locate the one to which we're linked for(var/obj/machinery/ticket_machine/ticketsplease in GLOB.machines) if(ticketsplease.id == id) - linked = ticketsplease + linked = WEAKREF(ticketsplease) if(linked) return TRUE else @@ -113,8 +113,11 @@ return if(!linked) return + var/obj/machinery/ticket_machine/machine = linked.resolve() + if(!machine) + return cooldown = TRUE - linked.increment() + machine.increment() addtimer(VARSET_CALLBACK(src, cooldown, FALSE), 10) /obj/machinery/ticket_machine/update_icon() diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 84a0ef96c1..5e7872b92e 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -300,7 +300,7 @@ area.power_equip = FALSE area.power_environ = FALSE area.power_change() - area.poweralert(TRUE, src) + area.poweralert(FALSE, src) if(occupier) malfvacate(1) qdel(wires) diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index fd5516a48a..081b93866e 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -500,7 +500,7 @@ drop_light_tube() new /obj/item/stack/cable_coil(loc, 1, "red") transfer_fingerprints_to(newlight) - if(cell) + if(!QDELETED(cell)) newlight.cell = cell cell.forceMove(newlight) cell = null diff --git a/code/modules/power/reactor/rbmk.dm b/code/modules/power/reactor/rbmk.dm index 609ec72984..cea10c6116 100644 --- a/code/modules/power/reactor/rbmk.dm +++ b/code/modules/power/reactor/rbmk.dm @@ -342,7 +342,7 @@ The reactor CHEWS through moderator. It does not do this slowly. Be very careful playsound(src, pick('sound/machines/fryer/deep_fryer_1.ogg', 'sound/machines/fryer/deep_fryer_2.ogg'), 100, TRUE) var/obj/item/reagent_containers/food/grilled_item = I if(prob(80)) - return //To give the illusion that it's actually cooking omegalul. + continue //To give the illusion that it's actually cooking omegalul. switch(power) if(20 to 39) grilled_item.name = "grilled [initial(grilled_item.name)]" diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index 2e8f301e13..1a64045ed0 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -628,19 +628,11 @@ desc = "Contains a large reservoir of soft drinks. This model has had its safeties shorted out." obj_flags = CAN_BE_HIT | EMAGGED flags_1 = NODECONSTRUCT_1 + circuit = /obj/item/circuitboard/machine/chem_dispenser/drinks/fullupgrade /obj/machinery/chem_dispenser/drinks/fullupgrade/Initialize(mapload) . = ..() dispensable_reagents |= emagged_reagents //adds emagged reagents - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser/drinks(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() /obj/machinery/chem_dispenser/drinks/beer name = "booze dispenser" @@ -688,19 +680,11 @@ desc = "Contains a large reservoir of the good stuff. This model has had its safeties shorted out." obj_flags = CAN_BE_HIT | EMAGGED flags_1 = NODECONSTRUCT_1 + circuit = /obj/item/circuitboard/machine/chem_dispenser/drinks/beer/fullupgrade /obj/machinery/chem_dispenser/drinks/beer/fullupgrade/Initialize(mapload) . = ..() dispensable_reagents |= emagged_reagents //adds emagged reagents - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser/drinks/beer(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() /obj/machinery/chem_dispenser/mutagen name = "mutagen dispenser" @@ -716,6 +700,7 @@ desc = "Creates and dispenses chemicals useful for botany." flags_1 = NODECONSTRUCT_1 canStore = FALSE + circuit = /obj/item/circuitboard/machine/chem_dispenser/mutagensaltpeter dispensable_reagents = list( /datum/reagent/toxin/mutagen, @@ -736,35 +721,15 @@ upgrade_reagents2 = null upgrade_reagents3 = null -/obj/machinery/chem_dispenser/mutagensaltpeter/Initialize(mapload) - . = ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() - /obj/machinery/chem_dispenser/fullupgrade //fully ugpraded stock parts, emagged desc = "Creates and dispenses chemicals. This model has had its safeties shorted out." obj_flags = CAN_BE_HIT | EMAGGED flags_1 = NODECONSTRUCT_1 + circuit = /obj/item/circuitboard/machine/chem_dispenser/fullupgrade /obj/machinery/chem_dispenser/fullupgrade/Initialize(mapload) . = ..() dispensable_reagents |= emagged_reagents //adds emagged reagents - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() /obj/machinery/chem_dispenser/abductor name = "reagent synthesizer" @@ -818,18 +783,6 @@ /datum/reagent/medicine/morphine ) -/obj/machinery/chem_dispenser/abductor/Initialize(mapload) - . = ..() - component_parts = list() - component_parts += new /obj/item/circuitboard/machine/chem_dispenser(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/matter_bin/bluespace(null) - component_parts += new /obj/item/stock_parts/capacitor/quadratic(null) - component_parts += new /obj/item/stock_parts/manipulator/femto(null) - component_parts += new /obj/item/stack/sheet/glass(null) - component_parts += new /obj/item/stock_parts/cell/bluespace(null) - RefreshParts() - ///An unique, less efficient model found in the medbay apothecary room. /obj/machinery/chem_dispenser/apothecary name = "apothecary chem dispenser" diff --git a/code/modules/recycling/disposal/pipe.dm b/code/modules/recycling/disposal/pipe.dm index 2fbea18ac2..6c85bfc3ee 100644 --- a/code/modules/recycling/disposal/pipe.dm +++ b/code/modules/recycling/disposal/pipe.dm @@ -54,7 +54,7 @@ if(H) H.active = FALSE expel(H, get_turf(src), 0) - QDEL_NULL(stored) + stored = null //The qdel is handled in expel() return ..() // returns the direction of the next pipe object, given the entrance dir diff --git a/code/modules/spells/spell.dm b/code/modules/spells/spell.dm index b740cca114..4be592b919 100644 --- a/code/modules/spells/spell.dm +++ b/code/modules/spells/spell.dm @@ -35,6 +35,7 @@ GLOBAL_LIST_INIT(spells, typesof(/obj/effect/proc_holder/spell)) //needed for the badmin verb for now /obj/effect/proc_holder/Destroy() + QDEL_NULL(action) if(ranged_ability_user) remove_ranged_ability() return ..() diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index 2d8150d087..c4ab435ee0 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -9,7 +9,7 @@ icon_state = "" layer = BELOW_MOB_LAYER //so it isn't hidden behind objects when on the floor var/mob/living/carbon/owner = null - var/mob/living/carbon/original_owner = null + var/datum/weakref/original_owner = null var/status = BODYPART_ORGANIC var/needs_processing = FALSE @@ -639,8 +639,8 @@ if(source) C = source if(!original_owner) - original_owner = source - else if(original_owner && owner != original_owner) //Foreign limb + original_owner = WEAKREF(source) + else if(original_owner && !IS_WEAKREF_OF(owner, original_owner)) //Foreign limb no_update = TRUE else C = owner diff --git a/code/modules/vehicles/mecha/_mecha.dm b/code/modules/vehicles/mecha/_mecha.dm index 3823bfa1dd..f4ffda302e 100644 --- a/code/modules/vehicles/mecha/_mecha.dm +++ b/code/modules/vehicles/mecha/_mecha.dm @@ -167,6 +167,7 @@ hud_possible = list (DIAG_STAT_HUD, DIAG_BATT_HUD, DIAG_MECH_HUD, DIAG_TRACK_HUD) /obj/item/radio/mech //this has to go somewhere + subspace_transmission = TRUE /obj/vehicle/sealed/mecha/Initialize(mapload) . = ..() @@ -196,41 +197,40 @@ update_icon() /obj/vehicle/sealed/mecha/Destroy() - if(obj_integrity > 0) //no explody if we have hp remaining! - explode_on_death = FALSE - for(var/M in occupants) - var/mob/living/occupant = M - if(isAI(occupant)) - occupant.gib() //No wreck, no AI to recover - else - occupant.forceMove(loc) - occupant.SetSleeping(destruction_sleep_duration) + for(var/ejectee in occupants) + mob_exit(ejectee, TRUE, TRUE) if(LAZYLEN(equipment)) - for(var/E in equipment) - var/obj/item/mecha_parts/mecha_equipment/equip = E + for(var/obj/item/mecha_parts/mecha_equipment/equip as anything in equipment) equip.detach(loc) qdel(equip) - if(cell) - QDEL_NULL(cell) - if(scanmod) - QDEL_NULL(scanmod) - if(capacitor) - QDEL_NULL(capacitor) - if(internal_tank) - QDEL_NULL(internal_tank) + radio = null + STOP_PROCESSING(SSobj, src) - GLOB.poi_list.Remove(src) LAZYCLEARLIST(equipment) - if(loc) - loc.assume_air(cabin_air) - air_update_turf() - else - qdel(cabin_air) - cabin_air = null + + QDEL_NULL(cell) + QDEL_NULL(scanmod) + QDEL_NULL(capacitor) + QDEL_NULL(internal_tank) + QDEL_NULL(cabin_air) QDEL_NULL(spark_system) QDEL_NULL(smoke_system) + GLOB.poi_list -= src GLOB.mechas_list -= src //global mech list + for(var/datum/atom_hud/data/diagnostic/diag_hud in GLOB.huds) + diag_hud.remove_from_hud(src) //YEET + return ..() + +/obj/vehicle/sealed/mecha/obj_destruction() + loc.assume_air(cabin_air) + air_update_turf(FALSE, FALSE) + for(var/mob/living/occupant as anything in occupants) + if(isAI(occupant)) + occupant.gib() //No wreck, no AI to recover + continue + mob_exit(occupant, FALSE, TRUE) + occupant.SetSleeping(destruction_sleep_duration) return ..() /obj/vehicle/sealed/mecha/update_icon() diff --git a/code/modules/vending/clothesmate.dm b/code/modules/vending/clothesmate.dm index 5551152b85..3e889328a4 100644 --- a/code/modules/vending/clothesmate.dm +++ b/code/modules/vending/clothesmate.dm @@ -11,6 +11,7 @@ /obj/item/clothing/head/beret/black = 3, /obj/item/clothing/head/beret/purple = 3, /obj/item/clothing/head/beret/blue = 3, + /obj/item/clothing/accessory/pride = 25, /obj/item/clothing/glasses/monocle = 3, /obj/item/clothing/suit/jacket = 4, /obj/item/clothing/suit/jacket/flannel = 4, diff --git a/icons/mob/clothing/accessories.dmi b/icons/mob/clothing/accessories.dmi index f801c483f1..5c212f3f45 100644 Binary files a/icons/mob/clothing/accessories.dmi and b/icons/mob/clothing/accessories.dmi differ diff --git a/icons/obj/clothing/accessories.dmi b/icons/obj/clothing/accessories.dmi index f633f030c3..b92d65092e 100644 Binary files a/icons/obj/clothing/accessories.dmi and b/icons/obj/clothing/accessories.dmi differ diff --git a/modular_citadel/code/modules/client/loadout/__donator.dm b/modular_citadel/code/modules/client/loadout/__donator.dm index 931324bf8f..4c09236872 100644 --- a/modular_citadel/code/modules/client/loadout/__donator.dm +++ b/modular_citadel/code/modules/client/loadout/__donator.dm @@ -330,7 +330,7 @@ name = "Lucky Jackboots" slot = ITEM_SLOT_BACKPACK path = /obj/item/clothing/shoes/lucky - ckeywhitelist = list("donaldtrumpthecommunist") + ckeywhitelist = list("spiralwithin") /datum/gear/donator/raiqbawks name = "Miami Boombox" diff --git a/modular_citadel/code/modules/client/loadout/backpack.dm b/modular_citadel/code/modules/client/loadout/backpack.dm index 0573a1a22a..5879426041 100644 --- a/modular_citadel/code/modules/client/loadout/backpack.dm +++ b/modular_citadel/code/modules/client/loadout/backpack.dm @@ -172,12 +172,21 @@ path = /obj/item/storage/fancy/ringbox/diamond cost = 5 -/datum/gear/backpack/necklace//this is here because loadout doesn't support proper accessories +/datum/gear/backpack/necklace //this is here because loadout doesn't support proper accessories name = "A renameable necklace" path = /obj/item/clothing/accessory/necklace + subcategory = LOADOUT_SUBCATEGORY_BACKPACK_ACCESSORIES /datum/gear/backpack/polymaidapron //this is ALSO here because loadout doesn't support proper accessories name = "Polychromic maid apron" path = /obj/item/clothing/accessory/maidapron/polychromic loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION | LOADOUT_CAN_COLOR_POLYCHROMIC loadout_initial_colors = list("#333333", "#FFFFFF") + subcategory = LOADOUT_SUBCATEGORY_BACKPACK_ACCESSORIES + +/datum/gear/backpack/pridepin //what the two comments above said + name = "Pride pin" + path = /obj/item/clothing/accessory/pride + loadout_flags = LOADOUT_CAN_NAME | LOADOUT_CAN_DESCRIPTION + subcategory = LOADOUT_SUBCATEGORY_BACKPACK_ACCESSORIES + cost = 0 diff --git a/tgstation.dme b/tgstation.dme index 24d15d2289..13fa372d59 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -227,6 +227,7 @@ #include "code\__HELPERS\vector.dm" #include "code\__HELPERS\verbs.dm" #include "code\__HELPERS\view.dm" +#include "code\__HELPERS\weakref.dm" #include "code\__HELPERS\yelling.dm" #include "code\__HELPERS\matrices\color_matrix.dm" #include "code\__HELPERS\matrices\transform_matrix.dm"