From ccfc08b7a8a555db89ec2dd60def908298401a14 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:15:50 -0400 Subject: [PATCH 01/31] Fix attack_hand-related runtimes --- code/_onclick/other_mobs.dm | 4 ++-- code/game/objects/items/devices/transfer_valve.dm | 2 +- code/modules/assembly/bomb.dm | 4 ++-- .../ninja/suit/ninja_equipment_actions/energy_net_nets.dm | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index 073f50d8c5..d9d552301e 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -35,7 +35,7 @@ SEND_SIGNAL(src, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, A) return . | A.attack_hand(src, intent, .) -/atom/proc/attack_hand(mob/user, act_intent = user.a_intent, attackchain_flags) +/atom/proc/attack_hand(mob/user, act_intent = user?.a_intent, attackchain_flags) //SHOULD_NOT_SLEEP(TRUE) if(!(interaction_flags_atom & INTERACT_ATOM_NO_FINGERPRINT_ATTACK_HAND)) add_fingerprint(user) @@ -54,7 +54,7 @@ else if(attack_hand_is_action) user.DelayNextAction() -/atom/proc/on_attack_hand(mob/user, act_intent = user.a_intent, unarmed_attack_flags) +/atom/proc/on_attack_hand(mob/user, act_intent = user?.a_intent, unarmed_attack_flags) //Return a non FALSE value to cancel whatever called this from propagating, if it respects it. /atom/proc/_try_interact(mob/user) diff --git a/code/game/objects/items/devices/transfer_valve.dm b/code/game/objects/items/devices/transfer_valve.dm index 7aafd729ea..ccaadacd26 100644 --- a/code/game/objects/items/devices/transfer_valve.dm +++ b/code/game/objects/items/devices/transfer_valve.dm @@ -110,7 +110,7 @@ if(.) return if(attached_device) - attached_device.attack_hand() + attached_device.attack_hand(user) //These keep attached devices synced up, for example a TTV with a mouse trap being found in a bag so it's triggered, or moving the TTV with an infrared beam sensor to update the beam's direction. diff --git a/code/modules/assembly/bomb.dm b/code/modules/assembly/bomb.dm index 8c025e2ab4..bc05d1095a 100644 --- a/code/modules/assembly/bomb.dm +++ b/code/modules/assembly/bomb.dm @@ -91,12 +91,12 @@ if(bombassembly) bombassembly.on_found(finder) -/obj/item/onetankbomb/on_attack_hand() //also for mousetraps +/obj/item/onetankbomb/on_attack_hand(mob/user) //also for mousetraps . = ..() if(.) return if(bombassembly) - bombassembly.attack_hand() + bombassembly.attack_hand(user) /obj/item/onetankbomb/Move() . = ..() diff --git a/code/modules/ninja/suit/ninja_equipment_actions/energy_net_nets.dm b/code/modules/ninja/suit/ninja_equipment_actions/energy_net_nets.dm index bc0828242e..22b07ac783 100644 --- a/code/modules/ninja/suit/ninja_equipment_actions/energy_net_nets.dm +++ b/code/modules/ninja/suit/ninja_equipment_actions/energy_net_nets.dm @@ -37,7 +37,7 @@ return ..() /obj/structure/energy_net/attack_paw(mob/user) - return attack_hand() + return attack_hand(user) /obj/structure/energy_net/user_buckle_mob(mob/living/M, mob/user, check_loc = TRUE) return//We only want our target to be buckled From affb6c435efdfd9a5929493716a82c5ecc7e4cd9 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:16:43 -0400 Subject: [PATCH 02/31] Fix runtime from missing jobs in jobs.txt --- code/controllers/subsystem/job.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index 549da9a086..b3ae905d0b 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -560,7 +560,8 @@ SUBSYSTEM_DEF(job) var/jobstext = file2text("[global.config.directory]/jobs.txt") for(var/datum/job/J in occupations) var/regex/jobs = new("[J.title]=(-1|\\d+),(-1|\\d+)") - jobs.Find(jobstext) + if(!jobs.Find(jobstext)) + continue J.total_positions = text2num(jobs.group[1]) J.spawn_positions = text2num(jobs.group[2]) From 0911076eb3650fb968b6063d9cc8d91d2b6be01f Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:17:39 -0400 Subject: [PATCH 03/31] Fix cosmetic glow quirk runtime --- .../code/datums/traits/trait_actions.dm | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/modular_splurt/code/datums/traits/trait_actions.dm b/modular_splurt/code/datums/traits/trait_actions.dm index 251d300b22..7b86b1ca2f 100644 --- a/modular_splurt/code/datums/traits/trait_actions.dm +++ b/modular_splurt/code/datums/traits/trait_actions.dm @@ -1507,7 +1507,8 @@ var/mob/living/carbon/human/action_mob = owner // Add outline effect - action_mob.add_filter("rad_fiend_glow", 1, list("type" = "outline", "color" = glow_color+"30", "size" = glow_range)) + if(glow_color && glow_range) + action_mob.add_filter("rad_fiend_glow", 1, list("type" = "outline", "color" = glow_color+"30", "size" = glow_range)) /datum/action/cosglow/update_glow/Remove() . = ..() @@ -1532,16 +1533,19 @@ glow_color = (input_color ? input_color : glow_color) // Ask user for range input - var/input_range = input(action_mob, "How much do you glow? Value may range between 1 to 2.", "Select Glow Range", glow_range) as num|null + var/input_range = input(action_mob, "How much do you glow? Value may range between 0 to 4. 0 disables glow.", "Select Glow Range", glow_range) as num|null // Check if range input was given - // Reset to stored color when not given input - // Input is clamped in the 1-4 range - glow_range = (input_range ? clamp(input_range, 0, 4) : glow_range) //More customisable, so you know when you're looking at someone with Radfiend (doom) or a normal player. + // Disable glow if input is 0. + // Reset to stored range when input is null. + // Input is clamped in the 0-4 range + glow_range = isnull(input_range) ? glow_range : clamp(input_range, 0, 4) //More customisable, so you know when you're looking at someone with Radfiend (doom) or a normal player. // Update outline effect - action_mob.remove_filter("rad_fiend_glow") - action_mob.add_filter("rad_fiend_glow", 1, list("type" = "outline", "color" = glow_color+"30", "size" = glow_range)) + if(glow_range && glow_color) + action_mob.add_filter("rad_fiend_glow", 1, list("type" = "outline", "color" = glow_color+"30", "size" = glow_range)) + else + action_mob.remove_filter("rad_fiend_glow") // // Quirk: Rad Fiend From e7c21fa3a7554afa05cf6849a7e122b02d325bc6 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:17:54 -0400 Subject: [PATCH 04/31] Fix runtimes from null thrower in living/hitby() --- code/modules/mob/living/living_defense.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index cd46072921..8e49d541c4 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -109,7 +109,7 @@ /mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) if(!isitem(AM)) // Filled with made up numbers for non-items. - if(mob_run_block(AM, 30, "\the [AM.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum.thrower, throwingdatum.thrower.zone_selected, list())) + if(mob_run_block(AM, 30, "\the [AM.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum.thrower, throwingdatum.thrower?.zone_selected, list())) hitpush = FALSE skipcatch = TRUE blocked = TRUE @@ -121,7 +121,7 @@ if(thrown_item.thrownby == WEAKREF(src)) //No throwing stuff at yourself to trigger hit reactions return ..() - if(mob_run_block(AM, thrown_item.throwforce, "\the [thrown_item.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum.thrower, throwingdatum.thrower.zone_selected, list())) + if(mob_run_block(AM, thrown_item.throwforce, "\the [thrown_item.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum.thrower, throwingdatum.thrower?.zone_selected, list())) hitpush = FALSE skipcatch = TRUE blocked = TRUE From 551c6754be1f570c7c8e82b77c68737f503adc9d Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:18:41 -0400 Subject: [PATCH 05/31] Fix runtimes from silicons trying to wag their tails or toggle their wings --- code/modules/mob/living/carbon/human/emote.dm | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/mob/living/carbon/human/emote.dm b/code/modules/mob/living/carbon/human/emote.dm index 7be24f08d6..3b8b1724bb 100644 --- a/code/modules/mob/living/carbon/human/emote.dm +++ b/code/modules/mob/living/carbon/human/emote.dm @@ -100,7 +100,7 @@ H.dna.species.stop_wagging_tail(H) /datum/emote/living/carbon/human/wag/can_run_emote(mob/user, status_check = TRUE) - if(!..()) + if(!..() || !ishuman(user)) return FALSE var/mob/living/carbon/human/H = user return H.dna && H.dna.species && H.dna.species.can_wag_tail(user) @@ -122,7 +122,7 @@ . = ..() if(.) var/mob/living/carbon/human/H = user - if(findtext(select_message_type(user), "open")) + if(H.dna.species.mutant_bodyparts["wings"]) H.OpenWings() else H.CloseWings() @@ -136,7 +136,7 @@ . = "closes " + message /datum/emote/living/carbon/human/wing/can_run_emote(mob/user, status_check = TRUE) - if(!..()) + if(!..() || !ishuman(user)) return FALSE var/mob/living/carbon/human/H = user if(H.dna && H.dna.species && (H.dna.features["wings"] != "None")) From 9e400bf781600ae43ca1e5b5a9ab700cefb43e66 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:45:28 -0400 Subject: [PATCH 06/31] Fix runtime from RPED on circuitless machine --- code/game/machinery/_machinery.dm | 78 ++++++++++++++++--------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/code/game/machinery/_machinery.dm b/code/game/machinery/_machinery.dm index c19c59448f..727927dcfc 100644 --- a/code/game/machinery/_machinery.dm +++ b/code/game/machinery/_machinery.dm @@ -553,44 +553,46 @@ Class Procs: if((flags_1 & NODECONSTRUCT_1) && !W.works_from_distance) return FALSE var/shouldplaysound = 0 - if(component_parts) - if(panel_open || W.works_from_distance) - var/obj/item/circuitboard/machine/CB = locate(/obj/item/circuitboard/machine) in component_parts - var/P - if(W.works_from_distance) - to_chat(user, display_parts(user)) - for(var/obj/item/A in component_parts) - for(var/D in CB.req_components) - if(ispath(A.type, D)) - P = D - break - for(var/obj/item/B in W.contents) - if(istype(B, P) && istype(A, P)) - if(B.get_part_rating() > A.get_part_rating()) - if(istype(B,/obj/item/stack)) //conveniently this will mean A is also a stack and I will kill the first person to prove me wrong - var/obj/item/stack/SA = A - var/obj/item/stack/SB = B - var/used_amt = SA.get_amount() - if(!SB.use(used_amt)) - continue //if we don't have the exact amount to replace we don't - var/obj/item/stack/SN = new SB.merge_type(null,used_amt) - component_parts += SN - else - if(SEND_SIGNAL(W, COMSIG_TRY_STORAGE_TAKE, B, src)) - component_parts += B - B.moveToNullspace() - SEND_SIGNAL(W, COMSIG_TRY_STORAGE_INSERT, A, null, null, TRUE) - component_parts -= A - to_chat(user, "[capitalize(A.name)] replaced with [B.name].") - shouldplaysound = 1 //Only play the sound when parts are actually replaced! - break - RefreshParts() - else - to_chat(user, display_parts(user)) - if(shouldplaysound) - W.play_rped_sound() - return TRUE - return FALSE + if(!component_parts) + return FALSE + if(!panel_open && !W.works_from_distance) + to_chat(user, display_parts(user)) + return FALSE + var/obj/item/circuitboard/machine/machine_board = locate(/obj/item/circuitboard/machine) in component_parts + if(!machine_board) + return FALSE + var/P + if(W.works_from_distance) + to_chat(user, display_parts(user)) + for(var/obj/item/A in component_parts) + for(var/D in machine_board.req_components) + if(istype(A, D)) + P = D + break + for(var/obj/item/B in W.contents) + if(istype(B, P) && istype(A, P)) + if(B.get_part_rating() > A.get_part_rating()) + if(istype(B,/obj/item/stack)) //conveniently this will mean A is also a stack and I will kill the first person to prove me wrong + var/obj/item/stack/SA = A + var/obj/item/stack/SB = B + var/used_amt = SA.get_amount() + if(!SB.use(used_amt)) + continue //if we don't have the exact amount to replace we don't + var/obj/item/stack/SN = new SB.merge_type(null,used_amt) + component_parts += SN + else + if(SEND_SIGNAL(W, COMSIG_TRY_STORAGE_TAKE, B, src)) + component_parts += B + B.moveToNullspace() + SEND_SIGNAL(W, COMSIG_TRY_STORAGE_INSERT, A, null, null, TRUE) + component_parts -= A + to_chat(user, "[capitalize(A.name)] replaced with [B.name].") + shouldplaysound = 1 //Only play the sound when parts are actually replaced! + break + RefreshParts() + if(shouldplaysound) + W.play_rped_sound() + return TRUE /obj/machinery/proc/display_parts(mob/user) . = list() From f0ff970b7947b087767d4018fe6f14f6bc1f6fab Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:46:09 -0400 Subject: [PATCH 07/31] Fix runtime from mobs escaping off other mobs' heads --- code/datums/elements/mob_holder.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/datums/elements/mob_holder.dm b/code/datums/elements/mob_holder.dm index 341e6ca6a0..84b28fe545 100644 --- a/code/datums/elements/mob_holder.dm +++ b/code/datums/elements/mob_holder.dm @@ -183,9 +183,9 @@ return TRUE /obj/item/clothing/head/mob_holder/relaymove(mob/living/user, direction) - container_resist() + container_resist(user) -/obj/item/clothing/head/mob_holder/container_resist() +/obj/item/clothing/head/mob_holder/container_resist(mob/living/user) if(isliving(loc)) var/mob/living/L = loc L.visible_message("[held_mob] escapes from [L]!", "[held_mob] escapes your grip!") From df8035fc9c01f5f492aaeb3bda9fc279e1da2aa2 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:46:33 -0400 Subject: [PATCH 08/31] Fix runtime from putting credit holochips into IDs --- code/game/objects/items/credit_holochip.dm | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/code/game/objects/items/credit_holochip.dm b/code/game/objects/items/credit_holochip.dm index b7f7f5f2d1..f548a24d43 100644 --- a/code/game/objects/items/credit_holochip.dm +++ b/code/game/objects/items/credit_holochip.dm @@ -84,13 +84,18 @@ var/obj/item/card/id/ID = I if(!ID.registered_account) to_chat(user, "[ID] doesn't have a linked account to deposit into!") - return - for(var/obj/item/holochip/money in src.loc.contents) + return STOP_ATTACK_PROC_CHAIN + var/atom/old_loc = loc // The following code can qdel src, which nulls its loc. + if(!old_loc) + ID.attackby(src, user) + return STOP_ATTACK_PROC_CHAIN + for(var/obj/item/holochip/money in old_loc.contents) ID.attackby(money, user) - for(var/obj/item/stack/spacecash/money in src.loc.contents) + for(var/obj/item/stack/spacecash/money in old_loc.contents) ID.attackby(money, user) - for(var/obj/item/coin/money in src.loc.contents) + for(var/obj/item/coin/money in old_loc.contents) ID.attackby(money, user) + return STOP_ATTACK_PROC_CHAIN /obj/item/holochip/AltClick(mob/user) if(!istype(user) || !user.canUseTopic(src, BE_CLOSE, ismonkey(user))) From a8f3a0b49d7664150e10b53e4bb749c644860ba1 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:46:59 -0400 Subject: [PATCH 09/31] Fix runtimes from null throwingdatum in living/hitby() --- code/modules/mob/living/living_defense.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 8e49d541c4..00cf418e0c 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -109,7 +109,7 @@ /mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) if(!isitem(AM)) // Filled with made up numbers for non-items. - if(mob_run_block(AM, 30, "\the [AM.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum.thrower, throwingdatum.thrower?.zone_selected, list())) + if(mob_run_block(AM, 30, "\the [AM.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum?.thrower, throwingdatum?.thrower?.zone_selected, list())) hitpush = FALSE skipcatch = TRUE blocked = TRUE @@ -121,7 +121,7 @@ if(thrown_item.thrownby == WEAKREF(src)) //No throwing stuff at yourself to trigger hit reactions return ..() - if(mob_run_block(AM, thrown_item.throwforce, "\the [thrown_item.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum.thrower, throwingdatum.thrower?.zone_selected, list())) + if(mob_run_block(AM, thrown_item.throwforce, "\the [thrown_item.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum?.thrower, throwingdatum?.thrower?.zone_selected, list())) hitpush = FALSE skipcatch = TRUE blocked = TRUE From 026af381f9afaf9e52c4aca09ace8b04481f37c5 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:47:27 -0400 Subject: [PATCH 10/31] Fix runtime from update_icon() being called on a qdeleted lewd decl --- code/modules/reagents/chemistry/reagents/other_reagents.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 730dba995c..08c06dff76 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -2568,6 +2568,8 @@ /obj/effect/decal/cleanable/semen/update_icon() . = ..() + if(QDELETED(src) || !reagents) + return add_atom_colour(mix_color_from_reagents(reagents.reagent_list), FIXED_COLOUR_PRIORITY) /datum/reagent/consumable/semen/femcum From 45ced4d9260a9db66d05d0a0ac8e8381cd5ec678 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:47:51 -0400 Subject: [PATCH 11/31] Fix ashwalkers not being remade with the proper gender --- code/modules/ruins/objects_and_mobs/ash_walker_den.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm index d961b4b2bd..48bfa1739a 100644 --- a/code/modules/ruins/objects_and_mobs/ash_walker_den.dm +++ b/code/modules/ruins/objects_and_mobs/ash_walker_den.dm @@ -62,7 +62,7 @@ deadmind = H.get_ghost(FALSE, TRUE) to_chat(deadmind, "Your body has been returned to the nest. You are being remade anew, and will awaken shortly.
Your memories will remain intact in your new body, as your soul is being salvaged") SEND_SOUND(deadmind, sound('sound/magic/enter_blood.ogg',volume=100)) - addtimer(CALLBACK(src, .proc/remake_walker, H.mind, H.real_name), 20 SECONDS) + addtimer(CALLBACK(src, .proc/remake_walker, H.mind, H.real_name, H.gender), 20 SECONDS) // SPLURT edit, adds H.gender as an argument. new /obj/effect/gibspawner/generic(get_turf(H)) qdel(H) return From 122147e46989f768a37a6f9f74a12ed91fe1be86 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 23:53:53 -0400 Subject: [PATCH 12/31] Fix runtime from null vehicle occupants list --- code/modules/vehicles/_vehicle.dm | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/code/modules/vehicles/_vehicle.dm b/code/modules/vehicles/_vehicle.dm index 4925cf40e7..c00357245a 100644 --- a/code/modules/vehicles/_vehicle.dm +++ b/code/modules/vehicles/_vehicle.dm @@ -20,18 +20,14 @@ var/emulate_door_bumps = TRUE //when bumping a door try to make occupants bump them to open them. var/default_driver_move = TRUE //handle driver movement instead of letting something else do it like riding datums. var/enclosed = FALSE // is the rider protected from bullets? assume no - var/list/autogrant_actions_passenger //plain list of typepaths - var/list/autogrant_actions_controller //assoc list "[bitflag]" = list(typepaths) - var/list/mob/occupant_actions //assoc list mob = list(type = action datum assigned to mob) + var/list/autogrant_actions_passenger = list() //plain list of typepaths + var/list/autogrant_actions_controller = list() //assoc list "[bitflag]" = list(typepaths) + var/list/mob/occupant_actions = list() //assoc list mob = list(type = action datum assigned to mob) var/obj/vehicle/trailer var/mouse_pointer //do we have a special mouse /obj/vehicle/Initialize(mapload) . = ..() - occupants = list() - autogrant_actions_passenger = list() - autogrant_actions_controller = list() - occupant_actions = list() generate_actions() /obj/vehicle/examine(mob/user) @@ -79,7 +75,7 @@ return is_occupant(M) && occupants[M] & VEHICLE_CONTROL_DRIVE /obj/vehicle/proc/is_occupant(mob/M) - return !isnull(occupants[M]) + return !isnull(occupants?[M]) /obj/vehicle/proc/add_occupant(mob/M, control_flags) if(!istype(M) || is_occupant(M)) From d65232554d56f3ecfee630e81e8d3926261fa1a1 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sun, 31 Mar 2024 00:03:30 -0400 Subject: [PATCH 13/31] Fix runtiming from bumping disconnected micros --- modular_splurt/code/modules/resize/resizing.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modular_splurt/code/modules/resize/resizing.dm b/modular_splurt/code/modules/resize/resizing.dm index 9554d1db85..470987941f 100644 --- a/modular_splurt/code/modules/resize/resizing.dm +++ b/modular_splurt/code/modules/resize/resizing.dm @@ -1,7 +1,8 @@ /mob/living/handle_micro_bump_other(mob/living/target) - // If the target is not in combat mode, if the target has the preference off, stop the interaction. - if(target.a_intent != INTENT_HARM && SEND_SIGNAL(target, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE) && target.client.prefs.stomppref == FALSE) + // If the target is not in combat mode, if the target is a player mob with the preference off, stop the interaction. + var/datum/preferences/target_prefs = target.client?.prefs || GLOB.preferences_datums[target.ckey] + if(target.a_intent != INTENT_HARM && SEND_SIGNAL(target, COMSIG_COMBAT_MODE_CHECK, COMBAT_MODE_INACTIVE) && (target.ckey && !target_prefs?.stomppref)) return FALSE // Do the rest of the function normally. From f3df171cb03dcb19cf2e8982b093ef150ccc324d Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sun, 31 Mar 2024 00:03:53 -0400 Subject: [PATCH 14/31] Slightly optimise micro bumping --- modular_sand/code/modules/resize/resizing.dm | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/modular_sand/code/modules/resize/resizing.dm b/modular_sand/code/modules/resize/resizing.dm index 913fcbb294..a5eb27adb8 100644 --- a/modular_sand/code/modules/resize/resizing.dm +++ b/modular_sand/code/modules/resize/resizing.dm @@ -7,10 +7,8 @@ return FALSE //Micro is on a table. - var/turf/steppyspot = target.loc - for(var/thing in steppyspot.contents) - if(istype(thing, /obj/structure/table)) - return TRUE + if(locate(/obj/structure/table) in target.loc) + return TRUE //Both small. if(get_size(user) <= RESIZE_A_TINYMICRO && get_size(target) <= RESIZE_A_TINYMICRO) @@ -48,10 +46,8 @@ return FALSE //If on a table, don't - var/turf/steppyspot = target.loc - for(var/thing in steppyspot.contents) - if(istype(thing, /obj/structure/table)) - return TRUE + if(locate(/obj/structure/table) in target.loc) + return TRUE //Both small if(get_size(user) <= RESIZE_A_TINYMICRO && get_size(target) <= RESIZE_A_TINYMICRO) From 0f21ae0c972a832db4eaa11265073e8a3761905f Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sun, 31 Mar 2024 00:06:26 -0400 Subject: [PATCH 15/31] Fix lewd decals runtiming when qdeleted after spawn --- .../effects/decals/cleanable/lewd_decals.dm | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm b/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm index d975353e4d..cbc76835e1 100644 --- a/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm +++ b/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm @@ -10,15 +10,17 @@ /obj/effect/decal/cleanable/semendrip/replace_decal(obj/effect/decal/cleanable/semendrip/C) . = ..() - reagents.trans_to(src, C.reagents.total_volume) + if(!. || QDELETED(src)) + return FALSE + reagents.trans_to(C, reagents.total_volume) transfer_blood_dna(C.blood_DNA) var/obj/effect/decal/cleanable/semen/S = (locate(/obj/effect/decal/cleanable/semen) in C.loc) - if(S) - C.reagents.trans_to(S, C.reagents.total_volume) - C.transfer_blood_dna(S.blood_DNA) - C.update_icon() - return - if(C.reagents.total_volume >= 10) + if(S) // Merge ourselves into this decal. + reagents.trans_to(S, C.reagents.total_volume) + transfer_blood_dna(S.blood_DNA) + update_icon() + return TRUE + if(C.reagents.total_volume >= 10) // Turn the drip into a puddle. S = new(C.loc) C.reagents.trans_to(S, C.reagents.total_volume) C.transfer_blood_dna(S.blood_DNA) From a627a617c6cb11bc05735c0d13e5b65f2427432d Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sun, 31 Mar 2024 00:06:34 -0400 Subject: [PATCH 16/31] Fix lewd decals not merging properly --- .../objects/effects/decals/cleanable/lewd_decals.dm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm b/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm index cbc76835e1..9c3ca35400 100644 --- a/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm +++ b/modular_sand/code/game/objects/effects/decals/cleanable/lewd_decals.dm @@ -12,14 +12,14 @@ . = ..() if(!. || QDELETED(src)) return FALSE - reagents.trans_to(C, reagents.total_volume) - transfer_blood_dna(C.blood_DNA) var/obj/effect/decal/cleanable/semen/S = (locate(/obj/effect/decal/cleanable/semen) in C.loc) - if(S) // Merge ourselves into this decal. - reagents.trans_to(S, C.reagents.total_volume) - transfer_blood_dna(S.blood_DNA) + if(S) // Merge ourselves into this puddle. + reagents.trans_to(S, reagents.total_volume) + S.transfer_blood_dna(blood_DNA) update_icon() return TRUE + reagents.trans_to(C, reagents.total_volume) + C.transfer_blood_dna(blood_DNA) if(C.reagents.total_volume >= 10) // Turn the drip into a puddle. S = new(C.loc) C.reagents.trans_to(S, C.reagents.total_volume) From b9915c080355c3f6e0997c26d490cef05a582756 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sun, 31 Mar 2024 00:09:17 -0400 Subject: [PATCH 17/31] Fix runtime from certain research table activities --- modular_splurt/code/game/machinery/research_table.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_splurt/code/game/machinery/research_table.dm b/modular_splurt/code/game/machinery/research_table.dm index 50888edf76..9215f1999e 100644 --- a/modular_splurt/code/game/machinery/research_table.dm +++ b/modular_splurt/code/game/machinery/research_table.dm @@ -139,7 +139,7 @@ for(var/obj/item/organ/genital/genital in buckled_mob.internal_organs) if(istype(genital, /obj/item/organ/genital/breasts)) var/obj/item/organ/genital/breasts/breasts = genital - points_awarded += breasts.fluid_rate + GLOB.breast_values[breasts.size] + points_awarded += breasts.fluid_rate + breasts.size continue points_awarded += genital.fluid_rate + genital.size points_awarded *= tier From 54c68141009ed94cbff555a7a018010fafeb46a4 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sun, 31 Mar 2024 00:20:06 -0400 Subject: [PATCH 18/31] Fix runtime from qdeleted mobs in handle_organs --- code/modules/mob/living/carbon/life.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/living/carbon/life.dm b/code/modules/mob/living/carbon/life.dm index 1cd2486ab4..ff65691541 100644 --- a/code/modules/mob/living/carbon/life.dm +++ b/code/modules/mob/living/carbon/life.dm @@ -401,7 +401,7 @@ var/obj/item/organ/O = V if(O) O.on_life(seconds, times_fired) - else + else if(!QDELETED(src)) if(reagents.has_reagent(/datum/reagent/toxin/formaldehyde, 1) || reagents.has_reagent(/datum/reagent/preservahyde, 1)) // No organ decay if the body contains formaldehyde. Or preservahyde. return for(var/V in internal_organs) From fc2f85d52640a73bdda884a97ba63398106d1d9a Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sun, 31 Mar 2024 02:07:12 -0400 Subject: [PATCH 19/31] Rewrite and improve breast-size-related code --- code/modules/arousal/organs/breasts.dm | 37 ++-- .../interaction_datums/lewd/breasts.dm | 26 +-- .../interaction_datums/lewd/nipsuck.dm | 204 +++++++----------- .../interaction_datums/lewd/self/breasts.dm | 26 +-- .../code/_globalvars/lists/global_lewd.dm | 2 +- 5 files changed, 105 insertions(+), 190 deletions(-) diff --git a/code/modules/arousal/organs/breasts.dm b/code/modules/arousal/organs/breasts.dm index 83b1ddba67..f792d2e071 100644 --- a/code/modules/arousal/organs/breasts.dm +++ b/code/modules/arousal/organs/breasts.dm @@ -67,7 +67,7 @@ //this is far too lewd wah /obj/item/organ/genital/breasts/modify_size(modifier, min = -INFINITY, max = INFINITY) - var/new_value = clamp(size + modifier, max(min, min_size ? GLOB.breast_values[min_size] : -INFINITY), min(max_size ? GLOB.breast_values[max_size] : INFINITY, max)) + var/new_value = clamp(size + modifier, max(min, min_size || -INFINITY), min(max_size || INFINITY, max)) if(new_value == size) return prev_size = size @@ -76,24 +76,12 @@ ..() /obj/item/organ/genital/breasts/size_to_state() - var/rounded = round(size) - var/str_size - switch(rounded) - if(0) //flatchested - str_size = "flat" - if(1 to 8) //modest - str_size = GLOB.breast_values[rounded] - if(9 to 15) //massive - str_size = GLOB.breast_values[rounded] - if(16 to 17) //ridiculous - str_size = GLOB.breast_values[rounded] - if(18 to 24) //AWOOOOGAAAAAAA - str_size = "massive" - if(25 to 29) //AWOOOOOOGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA - str_size = "giga" - if(30 to INFINITY) //AWWWWWWWWWWWWWOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOGGGGGAAAAAAAAAAAAAAAAAAAAAA - str_size = "impossible" - return str_size + var/rounded = clamp(round(size), 0, INFINITY) + for(var/size_index in length(GLOB.breast_values) to 1 step -1) // This should go in the reverse of the defined order (i.e. greatest-to-least). + var/size_state = GLOB.breast_values[size_index] + if(GLOB.breast_values[size_state] <= rounded) // Return the greatest (last) size value that's less than or equal to our numerical size. + return size_state + return "flat" // Even flat was too large for you, I guess...? This should never happen. /obj/item/organ/genital/breasts/update_size()//wah var/rounded_size = round(size) @@ -131,5 +119,16 @@ if(D.features["breasts_accessible"]) toggle_accessibility(TRUE) +/obj/item/organ/genital/breasts/proc/get_lactation_amount_modifier() + switch(size) + if(-INFINITY to 3) + return 1 + if(3 to 5) + return 2 + if(5 to 8) + return 3 + else + return clamp(size - 5, 0, INFINITY) + #undef BREASTS_ICON_MIN_SIZE #undef BREASTS_ICON_MAX_SIZE diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/breasts.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/breasts.dm index b3d662ac75..68b6c262f2 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/breasts.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/breasts.dm @@ -13,7 +13,6 @@ var/t_His = target.p_their() var/obj/item/organ/genital/breasts/milkers = user.getorganslot(ORGAN_SLOT_BREASTS) var/milktype = milkers?.fluid_id - var/modifier var/list/lines if(!milkers || !milktype) @@ -34,17 +33,7 @@ playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/oral1.ogg', 'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1) - switch(milkers.size) - if("c", "d", "e") - modifier = 2 - if("f", "g", "h") - modifier = 3 - else - if(milkers.size in GLOB.breast_values) - modifier = clamp(GLOB.breast_values[milkers.size] - 5, 0, INFINITY) - else - modifier = 1 - target.reagents.add_reagent(milktype, rand(1,3 * modifier)) + target.reagents.add_reagent(milktype, rand(1,3 * milkers.get_lactation_amount_modifier())) /datum/interaction/lewd/titgrope description = "Grope their breasts." @@ -79,18 +68,7 @@ var/milktype = milkers?.fluid_id if(milkers && milktype) - var/modifier - switch(milkers.size) - if("c", "d", "e") - modifier = 2 - if("f", "g", "h") - modifier = 3 - else - if(milkers.size in GLOB.breast_values) //SPLURT edit - global breast values - modifier = clamp(GLOB.breast_values[milkers.size] - 5, 0, INFINITY) - else - modifier = 1 - liquid_container.reagents.add_reagent(milktype, rand(1,3 * modifier)) + liquid_container.reagents.add_reagent(milktype, rand(1,3 * milkers.get_lactation_amount_modifier())) user.visible_message(span_lewd("\The [user] milks [target]'s breasts into \the [liquid_container]."), ignored_mobs = user.get_unconsenting()) playlewdinteractionsound(get_turf(user), 'modular_sand/sound/interactions/squelch1.ogg', 50, 1, -1) diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/nipsuck.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/nipsuck.dm index 8b65b38272..7078074466 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/nipsuck.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/nipsuck.dm @@ -7,135 +7,95 @@ interaction_sound = null /datum/interaction/lewd/nipsuck/display_interaction(mob/living/carbon/human/user, mob/living/carbon/human/target) - if((user.a_intent == INTENT_HELP) || (user.a_intent == INTENT_DISARM)) - user.visible_message( - pick(span_lewd("\The [user] gently sucks on \the [target]'s [pick("nipple", "nipples")]."), - span_lewd("\The [user] gently nibs \the [target]'s [pick("nipple", "nipples")]."), - span_lewd("\The [user] licks \the [target]'s [pick("nipple", "nipples")]."))) - var/has_breasts = target.has_breasts() - if(has_breasts == TRUE || has_breasts == HAS_EXPOSED_GENITAL) - var/modifier = 1 - var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS) - switch(B.size) - if("c", "d", "e") - modifier = 2 - if("f", "g", "h") - modifier = 3 - else - if(B.size in GLOB.breast_values) - modifier = clamp(GLOB.breast_values[B.size] - 5, 0, INFINITY) - else - modifier = 1 - if(B.fluid_id) - user.reagents.add_reagent(B.fluid_id, rand(1,2 * modifier) * user.get_fluid_mod(B)) //SPLURT edit - - if(user.a_intent == INTENT_HARM) - user.visible_message( - pick(span_lewd("\The [user] bites \the [target]'s [pick("nipple", "nipples")]."), - span_lewd("\The [user] aggressively sucks \the [target]'s [pick("nipple", "nipples")]."))) - var/has_breasts = target.has_breasts() - if(has_breasts == TRUE || has_breasts == HAS_EXPOSED_GENITAL) - var/modifier = 1 - var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS) - switch(B.size) - if("c", "d", "e") - modifier = 2 - if("f", "g", "h") - modifier = 3 - else - if(B.size in GLOB.breast_values) - modifier = clamp(GLOB.breast_values[B.size] - 5, 0, INFINITY) - else - modifier = 1 - if(B.fluid_id) - user.reagents.add_reagent(B.fluid_id, rand(1,3 * modifier)) //aggressive sucking leads to high rewards - - if(user.a_intent == INTENT_GRAB) - user.visible_message( - pick(span_lewd("\The [user] sucks \the [target]'s [pick("nipple", "nipples")] intently."), - span_lewd("\The [user] feasts \the [target]'s [pick("nipple", "nipples")]."), - span_lewd("\The [user] glomps \the [target]'s [pick("nipple", "nipples")]."))) - var/has_breasts = target.has_breasts() - if(has_breasts == TRUE || has_breasts == HAS_EXPOSED_GENITAL) - var/modifier = 1 - var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS) - switch(B.size) - if("c", "d", "e") - modifier = 2 - if("f", "g", "h") - modifier = 3 - else - if(B.size in GLOB.breast_values) - modifier = clamp(GLOB.breast_values[B.size] - 5, 0, INFINITY) - else - modifier = 1 - if(B.fluid_id) - user.reagents.add_reagent(B.fluid_id, rand(1,3 * modifier)) //aggressive sucking leads to high rewards + var/user_message + var/amount_high = 2 + switch(user.a_intent) + if(INTENT_HELP, INTENT_DISARM) + user_message = pick(span_lewd("\The [user] gently sucks on \the [target]'s [pick("nipple", "nipples")]."), + span_lewd("\The [user] gently nibs \the [target]'s [pick("nipple", "nipples")]."), + span_lewd("\The [user] licks \the [target]'s [pick("nipple", "nipples")].")) + if(INTENT_HARM) + amount_high = 3 // aggressive sucking has higher rewards + user_message = pick(span_lewd("\The [user] bites \the [target]'s [pick("nipple", "nipples")]."), + span_lewd("\The [user] aggressively sucks \the [target]'s [pick("nipple", "nipples")].")) + if(INTENT_GRAB) + amount_high = 3 // aggressive sucking has higher rewards + user_message = pick(span_lewd("\The [user] sucks \the [target]'s [pick("nipple", "nipples")] intently."), + span_lewd("\The [user] feasts \the [target]'s [pick("nipple", "nipples")]."), + span_lewd("\The [user] glomps \the [target]'s [pick("nipple", "nipples")].")) + user.visible_message(user_message) + var/has_breasts = target.has_breasts() + if(has_breasts == TRUE || has_breasts == HAS_EXPOSED_GENITAL) + var/obj/item/organ/genital/breasts/B = target.getorganslot(ORGAN_SLOT_BREASTS) + var/modifier = B?.get_lactation_amount_modifier() || 1 + if(B.fluid_id) + user.reagents.add_reagent(B.fluid_id, rand(1,amount_high * modifier) * user.get_fluid_mod(B)) if(prob(5 + target.get_lust())) - if(target.a_intent == INTENT_HELP) - if(!target.has_breasts()) - user.visible_message( - pick(span_lewd("\The [target] shivers in arousal."), - span_lewd("\The [target] moans quietly."), - span_lewd("\The [target] breathes out a soft moan."), - span_lewd("\The [target] gasps."), - span_lewd("\The [target] shudders softly."), - span_lewd("\The [target] trembles as their chest gets molested."))) - else - user.visible_message( - pick(span_lewd("\The [target] shivers in arousal."), - span_lewd("\The [target] moans quietly."), - span_lewd("\The [target] breathes out a soft moan."), - span_lewd("\The [target] gasps."), - span_lewd("\The [target] shudders softly."), - span_lewd("\The [target] trembles as their breasts get molested."), - span_lewd("\The [target] quivers in arousal as \the [user] delights themselves on their milk."))) - if(target.get_lust() < 5) - target.handle_post_sex(5, CUM_TARGET_MOUTH, user, ORGAN_SLOT_BREASTS) //SPLURT edit - if(target.a_intent == INTENT_DISARM) - if (target.restrained()) + switch(target.a_intent) + if(INTENT_HELP) if(!target.has_breasts()) user.visible_message( - pick(span_lewd("\The [target] twists playfully against the restraints."), - span_lewd("\The [target] squirms away from \the [user]'s mouth."), - span_lewd("\The [target] slides back from \the [user]'s mouth."), - span_lewd("\The [target] thrusts their bare chest forward into \the [user]'s mouth."))) + pick(span_lewd("\The [target] shivers in arousal."), + span_lewd("\The [target] moans quietly."), + span_lewd("\The [target] breathes out a soft moan."), + span_lewd("\The [target] gasps."), + span_lewd("\The [target] shudders softly."), + span_lewd("\The [target] trembles as their chest gets molested."))) else user.visible_message( - pick(span_lewd("\The [target] twists playfully against the restraints."), - span_lewd("\The [target] squirms away from \the [user]'s mouth."), - span_lewd("\The [target] slides back from \the [user]'s mouth."), - span_lewd("\The [target] thrust their bare breasts forward into \the [user]'s mouth."))) - else - if(!target.has_breasts()) - user.visible_message( - pick(span_lewd("\The [target] playfully shoos away \the [user]'s head."), - span_lewd("\The [target] squirms away from \the [user]'s mouth."), - span_lewd("\The [target] holds \the [user]'s head against their chest."), - span_lewd("\The [target] teasingly caresses \the [user]'s neck."))) + pick(span_lewd("\The [target] shivers in arousal."), + span_lewd("\The [target] moans quietly."), + span_lewd("\The [target] breathes out a soft moan."), + span_lewd("\The [target] gasps."), + span_lewd("\The [target] shudders softly."), + span_lewd("\The [target] trembles as their breasts get molested."), + span_lewd("\The [target] quivers in arousal as \the [user] delights themselves on their milk."))) + if(target.get_lust() < 5) + target.handle_post_sex(5, CUM_TARGET_MOUTH, user, ORGAN_SLOT_BREASTS) //SPLURT edit + if(INTENT_DISARM) + if (target.restrained()) + if(!target.has_breasts()) + user.visible_message( + pick(span_lewd("\The [target] twists playfully against the restraints."), + span_lewd("\The [target] squirms away from \the [user]'s mouth."), + span_lewd("\The [target] slides back from \the [user]'s mouth."), + span_lewd("\The [target] thrusts their bare chest forward into \the [user]'s mouth."))) + else + user.visible_message( + pick(span_lewd("\The [target] twists playfully against the restraints."), + span_lewd("\The [target] squirms away from \the [user]'s mouth."), + span_lewd("\The [target] slides back from \the [user]'s mouth."), + span_lewd("\The [target] thrust their bare breasts forward into \the [user]'s mouth."))) else - user.visible_message( - pick(span_lewd("\The [target] playfully shoos away \the [user]'s head."), - span_lewd("\The [target] squirms away from \the [user]'s mouth."), - span_lewd("\The [target] holds \the [user]'s head against their breast."), - span_lewd("\The [target] teasingly caresses \the [user]'s neck."), - span_lewd("\The [target] rubs their breasts against \the [user]'s head."))) - if(target.get_lust() < 10) - target.handle_post_sex(NORMAL_LUST, CUM_TARGET_MOUTH, user, ORGAN_SLOT_BREASTS) //SPLURT edit - if(target.a_intent == INTENT_GRAB) - user.visible_message( - pick(span_lewd("\The [target] grips \the [user]'s head tight."), - span_lewd("\The [target] digs nails into \the [user]'s scalp."), - span_lewd("\The [target] grabs and shoves \the [user]'s head away."))) - if(target.a_intent == INTENT_HARM) - user.adjustBruteLoss(1) - user.visible_message( - pick(span_lewd("\The [target] slaps \the [user] away."), - span_lewd("\The [target] scratches [user]'s face."), - span_lewd("\The [target] fiercely struggles against [user]."), - span_lewd("\The [target] claws [user]'s face, drawing blood."), - span_lewd("\The [target] elbows [user]'s mouth away."))) + if(!target.has_breasts()) + user.visible_message( + pick(span_lewd("\The [target] playfully shoos away \the [user]'s head."), + span_lewd("\The [target] squirms away from \the [user]'s mouth."), + span_lewd("\The [target] holds \the [user]'s head against their chest."), + span_lewd("\The [target] teasingly caresses \the [user]'s neck."))) + else + user.visible_message( + pick(span_lewd("\The [target] playfully shoos away \the [user]'s head."), + span_lewd("\The [target] squirms away from \the [user]'s mouth."), + span_lewd("\The [target] holds \the [user]'s head against their breast."), + span_lewd("\The [target] teasingly caresses \the [user]'s neck."), + span_lewd("\The [target] rubs their breasts against \the [user]'s head."))) + if(target.get_lust() < 10) + target.handle_post_sex(NORMAL_LUST, CUM_TARGET_MOUTH, user, ORGAN_SLOT_BREASTS) //SPLURT edit + if(INTENT_GRAB) + user.visible_message( + pick(span_lewd("\The [target] grips \the [user]'s head tight."), + span_lewd("\The [target] digs nails into \the [user]'s scalp."), + span_lewd("\The [target] grabs and shoves \the [user]'s head away."))) + if(INTENT_HARM) + user.adjustBruteLoss(1) + user.visible_message( + pick(span_lewd("\The [target] slaps \the [user] away."), + span_lewd("\The [target] scratches [user]'s face."), + span_lewd("\The [target] fiercely struggles against [user]."), + span_lewd("\The [target] claws [user]'s face, drawing blood."), + span_lewd("\The [target] elbows [user]'s mouth away."))) target.dir = get_dir(target, user) user.dir = get_dir(user, target) playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/oral1.ogg', diff --git a/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm b/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm index 20927a02ae..7f5c37619c 100644 --- a/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm +++ b/modular_sand/code/datums/interactions/interaction_datums/lewd/self/breasts.dm @@ -61,18 +61,7 @@ var/milktype = milkers?.fluid_id if(milkers && milktype) - var/modifier - switch(milkers.size) - if(3 to 5) - modifier = 2 - if(6 to 8) - modifier = 3 - else - if(milkers.size_to_state() in GLOB.breast_values) - modifier = clamp(GLOB.breast_values[milkers.size_to_state()] - 5, 0, INFINITY) - else - modifier = 1 - liquid_container.reagents.add_reagent(milktype, rand(1,3 * modifier)) + liquid_container.reagents.add_reagent(milktype, rand(1,3 * milkers.get_lactation_amount_modifier())) user.visible_message(message = span_lewd("\The [user] [message]."), ignored_mobs = user.get_unconsenting()) playlewdinteractionsound(get_turf(user), 'modular_sand/sound/interactions/squelch1.ogg', 50, 1, -1) @@ -92,7 +81,6 @@ var/u_His = user.p_their() var/obj/item/organ/genital/breasts/milkers = user.getorganslot(ORGAN_SLOT_BREASTS) var/milktype = milkers?.fluid_id - var/modifier var/list/lines if(!milkers || !milktype) @@ -113,14 +101,4 @@ playlewdinteractionsound(get_turf(user), pick('modular_sand/sound/interactions/oral1.ogg', 'modular_sand/sound/interactions/oral2.ogg'), 70, 1, -1) - switch(milkers.size) - if("c", "d", "e") - modifier = 2 - if("f", "g", "h") - modifier = 3 - else - if(milkers.size in GLOB.breast_values) - modifier = clamp(GLOB.breast_values[milkers.size] - 5, 0, INFINITY) - else - modifier = 1 - user.reagents.add_reagent(milktype, rand(1,3 * modifier) * user.get_fluid_mod(milkers)) //SPLURT edit + user.reagents.add_reagent(milktype, rand(1,3 * milkers.get_lactation_amount_modifier()) * user.get_fluid_mod(milkers)) //SPLURT edit diff --git a/modular_splurt/code/_globalvars/lists/global_lewd.dm b/modular_splurt/code/_globalvars/lists/global_lewd.dm index 7883a8ecb4..a2b49a5e21 100644 --- a/modular_splurt/code/_globalvars/lists/global_lewd.dm +++ b/modular_splurt/code/_globalvars/lists/global_lewd.dm @@ -16,4 +16,4 @@ GLOBAL_LIST_INIT(balls_nouns, list("balls", "nuts", "ballsack", "testicles", "sa GLOBAL_LIST_INIT(butt_nouns, list("ass", "butt", "dumptruck", "tush", "badonk", "booty", "rump", "behind")) -GLOBAL_LIST_INIT(breast_values, list("a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5, "f" = 6, "g" = 7, "h" = 8, "i" = 9, "j" = 10, "k" = 11, "l" = 12, "m" = 13, "n" = 14, "o" = 15, "huge" = 16, "massive" = 17, "giga" = 25, "impossible" = 30, "flat" = 0)) +GLOBAL_LIST_INIT(breast_values, list("flat" = 0, "a" = 1, "b" = 2, "c" = 3, "d" = 4, "e" = 5, "f" = 6, "g" = 7, "h" = 8, "i" = 9, "j" = 10, "k" = 11, "l" = 12, "m" = 13, "n" = 14, "o" = 15, "huge" = 16, "massive" = 17, "giga" = 25, "impossible" = 30)) From 382cb28b15e716a67c95bfdb383f4e095f7029ae Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Sat, 30 Mar 2024 21:12:48 -0400 Subject: [PATCH 20/31] Fix a number of reported runtimes --- _maps/layeniastation.json | 2 +- code/datums/elements/photosynthesis.dm | 5 +++-- code/modules/mob/living/carbon/carbon.dm | 2 +- code/modules/recycling/disposal/holder.dm | 3 ++- code/modules/surgery/bodyparts/_bodyparts.dm | 1 - 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/_maps/layeniastation.json b/_maps/layeniastation.json index 8b1ea69047..99a22bbf66 100644 --- a/_maps/layeniastation.json +++ b/_maps/layeniastation.json @@ -12,7 +12,7 @@ "traits": [ { "Up": 1, - "Baseturf": "/area/space", + "Baseturf": "/turf/space", "Linkage": "Cross" }, { diff --git a/code/datums/elements/photosynthesis.dm b/code/datums/elements/photosynthesis.dm index a88a5d108c..1efe1d3597 100644 --- a/code/datums/elements/photosynthesis.dm +++ b/code/datums/elements/photosynthesis.dm @@ -49,8 +49,9 @@ return ..() /datum/element/photosynthesis/process() - for(var/A in attached_atoms) - var/atom/movable/AM = A + for(var/atom/movable/AM as anything in attached_atoms) + if(isnull(AM)) + continue var/light_amount = 0 //how much light there is in the place, affects receiving nutrition and healing if(isturf(AM.loc)) //else, there's considered to be no light var/turf/T = AM.loc diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index a8f43a5159..4e191b0819 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -103,7 +103,7 @@ . = ..() var/hurt = TRUE var/extra_speed = 0 - if(throwingdatum.thrower != src) + if(throwingdatum?.thrower != src) extra_speed = min(max(0, throwingdatum.speed - initial(throw_speed)), 3) if(GetComponent(/datum/component/tackler)) return diff --git a/code/modules/recycling/disposal/holder.dm b/code/modules/recycling/disposal/holder.dm index bce1b3d98d..4c6e79f6a2 100644 --- a/code/modules/recycling/disposal/holder.dm +++ b/code/modules/recycling/disposal/holder.dm @@ -22,7 +22,8 @@ // initialize a holder from the contents of a disposal unit /obj/structure/disposalholder/proc/init(obj/machinery/disposal/D) - gas = D.air_contents// transfer gas resv. into holder object + if(istype(D)) // This is sometimes called on non-machinery disposals system types. + gas = D.air_contents// transfer gas resv. into holder object //Check for any living mobs trigger hasmob. //hasmob effects whether the package goes to cargo or its tagged destination. diff --git a/code/modules/surgery/bodyparts/_bodyparts.dm b/code/modules/surgery/bodyparts/_bodyparts.dm index fc165c4fb0..17ab237b9f 100644 --- a/code/modules/surgery/bodyparts/_bodyparts.dm +++ b/code/modules/surgery/bodyparts/_bodyparts.dm @@ -636,7 +636,6 @@ /obj/item/bodypart/proc/update_limb(dropping_limb, mob/living/carbon/source) body_markings_list = list() var/mob/living/carbon/C - owner.create_weakref() if(source) C = source if(!original_owner) From d72fb0fe5e9553ea1d695d79824cd072e3cac4bb Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Mon, 1 Apr 2024 13:26:32 -0400 Subject: [PATCH 21/31] Fix runtime in overflow bureaucracy station trait --- code/controllers/subsystem/job.dm | 13 +++++++++++++ code/datums/station_traits/negative_traits.dm | 6 +++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm index b3ae905d0b..b382834157 100644 --- a/code/controllers/subsystem/job.dm +++ b/code/controllers/subsystem/job.dm @@ -26,6 +26,19 @@ SUBSYSTEM_DEF(job) set_overflow_role(CONFIG_GET(string/overflow_job)) return ..() +/// Returns a list of jobs that we are allowed to fuck with during random events +/datum/controller/subsystem/job/proc/get_valid_overflow_jobs() + var/static/list/overflow_jobs + if (!isnull(overflow_jobs)) + return overflow_jobs + + overflow_jobs = list() + for (var/datum/job/check_job in occupations) // TODO: Port joinable_occupations from upstream TG PR #60578. + if (!check_job.allow_bureaucratic_error) + continue + overflow_jobs += check_job + return overflow_jobs + /datum/controller/subsystem/job/proc/set_overflow_role(new_overflow_role) var/datum/job/new_overflow = GetJob(new_overflow_role) var/cap = CONFIG_GET(number/overflow_cap) diff --git a/code/datums/station_traits/negative_traits.dm b/code/datums/station_traits/negative_traits.dm index c24d93865c..3b3173b365 100644 --- a/code/datums/station_traits/negative_traits.dm +++ b/code/datums/station_traits/negative_traits.dm @@ -119,9 +119,9 @@ /datum/station_trait/overflow_job_bureaucracy/proc/set_overflow_job_override(datum/source) SIGNAL_HANDLER - var/datum/job/picked_job = pick(get_all_jobs()) - chosen_job_name = lowertext(picked_job.title) // like Chief Engineers vs like chief engineers - SSjob.set_overflow_role(picked_job.type) + var/picked_job_title = SSjob.get_valid_overflow_jobs() + chosen_job_name = lowertext(picked_job_title) // like Chief Engineers vs like chief engineers + SSjob.set_overflow_role(SSjob.GetJobType(picked_job_title)) // TODO: port a blacklist for this from upstream TG PR /datum/station_trait/slow_shuttle name = "Slow Shuttle" From 368cbd33c3f40e1e9271f53a8c573d6ebfe85f75 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Mon, 1 Apr 2024 13:48:10 -0400 Subject: [PATCH 22/31] Limit playerpanel smites to humantypes --- tgui/packages/tgui/interfaces/PlayerPanel2.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tgui/packages/tgui/interfaces/PlayerPanel2.js b/tgui/packages/tgui/interfaces/PlayerPanel2.js index b3178d959a..48ef7cae7c 100644 --- a/tgui/packages/tgui/interfaces/PlayerPanel2.js +++ b/tgui/packages/tgui/interfaces/PlayerPanel2.js @@ -459,7 +459,7 @@ const GeneralActions = (props, context) => { color="orange" content="Smite" confirmColor="average" - disabled={!mob_type.includes("/mob/living")} + disabled={!mob_type.includes("/mob/living/carbon/human")} onClick={() => act("smite")} /> From 6d580ba44f4a8c1724deeefc289531c1ff909630 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Mon, 1 Apr 2024 15:43:14 -0400 Subject: [PATCH 23/31] Limit genitals menu to carbontype mobs --- modular_splurt/code/datums/genitals/genitals_interface.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modular_splurt/code/datums/genitals/genitals_interface.dm b/modular_splurt/code/datums/genitals/genitals_interface.dm index 2c90652977..5505fa043e 100644 --- a/modular_splurt/code/datums/genitals/genitals_interface.dm +++ b/modular_splurt/code/datums/genitals/genitals_interface.dm @@ -1,5 +1,5 @@ /// Attempts to open the tgui menu -/mob/living/verb/genital_menu() +/mob/living/carbon/verb/genital_menu() set name = "Genitals Menu" set desc = "Manage your genital, or someone else's." set category = "IC" From 77058b4a6b40f87e8d85817ffea451983fd8c0d0 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Mon, 1 Apr 2024 16:05:35 -0400 Subject: [PATCH 24/31] Remove duplicated cyborg premium KA code --- .../objects/items/robot/robot_upgrades.dm | 19 +++++++++-- .../objects/items/robot/robot_upgrades.dm | 32 ------------------- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/code/game/objects/items/robot/robot_upgrades.dm b/code/game/objects/items/robot/robot_upgrades.dm index 3bef9b62e6..ba31456242 100644 --- a/code/game/objects/items/robot/robot_upgrades.dm +++ b/code/game/objects/items/robot/robot_upgrades.dm @@ -218,21 +218,36 @@ name = "mining cyborg premium KA" desc = "A premium kinetic accelerator replacement for the mining module's standard kinetic accelerator." icon_state = "cyborg_upgrade3" - require_module = 1 + require_module = TRUE module_type = list(/obj/item/robot_module/miner) + module_flags = BORG_MODULE_MINER // SANDSTORM EDIT /obj/item/borg/upgrade/premiumka/action(mob/living/silicon/robot/R, user = usr) . = ..() if(.) for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA in R.module) for(var/obj/item/borg/upgrade/modkit/M in KA.modkits) - M.uninstall(src) + M.uninstall(KA) R.module.remove_module(KA, TRUE) var/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg/PKA = new /obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg(R.module) R.module.basic_modules += PKA R.module.add_module(PKA, FALSE, TRUE) +// SANDSTORM EDIT START +/obj/item/borg/upgrade/premiumka/deactivate(mob/living/silicon/robot/R, user = usr) + . = ..() + if (.) + for(var/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg/PKA in R.module) + for(var/obj/item/borg/upgrade/modkit/M in PKA.modkits) + M.uninstall(PKA) + R.module.remove_module(PKA, TRUE) + + var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA = new (R.module) + R.module.basic_modules += KA + R.module.add_module(KA, FALSE, TRUE) +// SANDSTORM EDIT END + /obj/item/borg/upgrade/tboh name = "janitor cyborg trash bag of holding" desc = "A trash bag of holding replacement for the janiborg's standard trash bag." diff --git a/modular_sand/code/game/objects/items/robot/robot_upgrades.dm b/modular_sand/code/game/objects/items/robot/robot_upgrades.dm index 1dcdf6deff..83e4e15ab1 100644 --- a/modular_sand/code/game/objects/items/robot/robot_upgrades.dm +++ b/modular_sand/code/game/objects/items/robot/robot_upgrades.dm @@ -101,38 +101,6 @@ R.module.basic_modules += PD R.module.add_module(PD, FALSE, TRUE) -/obj/item/borg/upgrade/premiumka - name = "mining cyborg premium KA" - desc = "A premium kinetic accelerator replacement for the mining module's standard kinetic accelerator." - icon_state = "cyborg_upgrade3" - require_module = TRUE - module_type = list(/obj/item/robot_module/miner) - module_flags = BORG_MODULE_MINER - -/obj/item/borg/upgrade/premiumka/action(mob/living/silicon/robot/R, user = usr) - . = ..() - if(.) - for(var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA in R.module) - for(var/obj/item/borg/upgrade/modkit/M in KA.modkits) - M.uninstall(src) - R.module.remove_module(KA, TRUE) - - var/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg/PKA = new /obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg(R.module) - R.module.basic_modules += PKA - R.module.add_module(PKA, FALSE, TRUE) - -/obj/item/borg/upgrade/premiumka/deactivate(mob/living/silicon/robot/R, user = usr) - . = ..() - if (.) - for(var/obj/item/gun/energy/kinetic_accelerator/premiumka/cyborg/PKA in R.module) - for(var/obj/item/borg/upgrade/modkit/M in PKA.modkits) - M.uninstall(src) - R.module.remove_module(PKA, TRUE) - - var/obj/item/gun/energy/kinetic_accelerator/cyborg/KA = new (R.module) - R.module.basic_modules += KA - R.module.add_module(KA, FALSE, TRUE) - /obj/item/borg/upgrade/expand/action(mob/living/silicon/robot/R, user = usr) . = ..() if(.) From e3af7ec906df75c39f5f4a9033448640558ea8cd Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Mon, 1 Apr 2024 16:17:39 -0400 Subject: [PATCH 25/31] Fix mispathed screen alerts --- .../code/game/objects/items/lewd_items/leash.dm | 12 ++++++------ .../antagonists/wendigo/mob/metabolization.dm | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modular_splurt/code/game/objects/items/lewd_items/leash.dm b/modular_splurt/code/game/objects/items/lewd_items/leash.dm index 88ed837f87..dcb78d4144 100644 --- a/modular_splurt/code/game/objects/items/lewd_items/leash.dm +++ b/modular_splurt/code/game/objects/items/lewd_items/leash.dm @@ -14,9 +14,9 @@ Icons, maybe? /datum/status_effect/leash_dom status_type = STATUS_EFFECT_UNIQUE - alert_type = /obj/screen/alert/status_effect/leash_dom + alert_type = /atom/movable/screen/alert/status_effect/leash_dom -/obj/screen/alert/status_effect/leash_dom +/atom/movable/screen/alert/status_effect/leash_dom name = "Leash Master" desc = "You've got a leash, and a cute pet on the other end." icon_state = "leash_master" //These call icons that don't exist, so no icon comes up. Which is good. @@ -24,9 +24,9 @@ Icons, maybe? /datum/status_effect/leash_freepet status_type = STATUS_EFFECT_UNIQUE - alert_type = /obj/screen/alert/status_effect/leash_freepet + alert_type = /atom/movable/screen/alert/status_effect/leash_freepet -/obj/screen/alert/status_effect/leash_freepet +/atom/movable/screen/alert/status_effect/leash_freepet name = "Escaped Pet" desc = "You're on a leash, but you've no master. If anyone grabs the leash they'll gain control!" icon_state = "leash_freepet" @@ -36,9 +36,9 @@ Icons, maybe? id = "leashed" status_type = STATUS_EFFECT_UNIQUE var/mob/redirect_component - alert_type = /obj/screen/alert/status_effect/leash_pet + alert_type = /atom/movable/screen/alert/status_effect/leash_pet -/obj/screen/alert/status_effect/leash_pet +/atom/movable/screen/alert/status_effect/leash_pet name = "Leashed Pet" desc = "You're on the hook now! Be good for your master." icon_state = "leash_pet" diff --git a/modular_splurt/code/modules/antagonists/wendigo/mob/metabolization.dm b/modular_splurt/code/modules/antagonists/wendigo/mob/metabolization.dm index 7293047456..36784c9652 100644 --- a/modular_splurt/code/modules/antagonists/wendigo/mob/metabolization.dm +++ b/modular_splurt/code/modules/antagonists/wendigo/mob/metabolization.dm @@ -12,13 +12,13 @@ /* switch(nutrition) if(NUTRITION_LEVEL_FULL to INFINITY) - throw_alert("nutrition", /obj/screen/alert/fat) + throw_alert("nutrition", /atom/movable/screen/alert/fat) if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_FULL) clear_alert("nutrition") if(NUTRITION_LEVEL_HUNGRY to NUTRITION_LEVEL_STARVING) - throw_alert("nutrition", /obj/screen/alert/hungry) + throw_alert("nutrition", /atom/movable/screen/alert/hungry) if(0 to NUTRITION_LEVEL_STARVING) - throw_alert("nutrition", /obj/screen/alert/starving) + throw_alert("nutrition", /atom/movable/screen/alert/starving) */ /mob/living/carbon/wendigo/reagent_check(datum/reagent/R) From 176949efeff9f3a3b6a604c250338c6068309282 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Mon, 1 Apr 2024 18:06:51 -0400 Subject: [PATCH 26/31] Fix runtime from backpack hiding action --- .../game/objects/items/implants/implant_hide_backpack.dm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modular_splurt/code/game/objects/items/implants/implant_hide_backpack.dm b/modular_splurt/code/game/objects/items/implants/implant_hide_backpack.dm index 5a0d4ada8f..18cba47894 100644 --- a/modular_splurt/code/game/objects/items/implants/implant_hide_backpack.dm +++ b/modular_splurt/code/game/objects/items/implants/implant_hide_backpack.dm @@ -48,10 +48,9 @@ // Runs on losing the ability /datum/action/item_action/hide_backpack/Remove(mob/user) - . = ..() - - // Remove the trait + // Remove the trait (must be done before removal so that owner still exists) adjust_trait(FALSE) + return ..() // Function to update trait /datum/action/item_action/hide_backpack/proc/adjust_trait(state) From 6dcccb6a024223e6aa19fd706bc6d91f5104068d Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Mon, 1 Apr 2024 18:08:56 -0400 Subject: [PATCH 27/31] Fix kinetic crusher runtimes --- code/modules/mining/equipment/kinetic_crusher.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/mining/equipment/kinetic_crusher.dm b/code/modules/mining/equipment/kinetic_crusher.dm index f89b67d323..ac9882f0f5 100644 --- a/code/modules/mining/equipment/kinetic_crusher.dm +++ b/code/modules/mining/equipment/kinetic_crusher.dm @@ -94,7 +94,7 @@ if(!QDELETED(target)) var/obj/item/crusher_trophy/T = t T.on_melee_hit(target, user) - if(!QDELETED(C) && !QDELETED(target)) + if(C && !QDELING(C) && !QDELETED(target)) // C can be 0 here, and QDELETED will runtime if that's the case. C.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did /obj/item/kinetic_crusher/afterattack(atom/target, mob/living/user, proximity_flag, clickparams) @@ -132,18 +132,18 @@ var/obj/item/crusher_trophy/T = t T.on_mark_detonation(target, user) if(!QDELETED(L)) - if(!QDELETED(C)) + if(C && !QDELING(C)) // C can be 0 here, and QDELETED will runtime if that's the case. C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did new /obj/effect/temp_visual/kinetic_blast(get_turf(L)) var/backstab_dir = get_dir(user, L) var/def_check = L.getarmor(type = BOMB) if((user.dir & backstab_dir) && (L.dir & backstab_dir)) - if(!QDELETED(C)) + if(C && !QDELING(C)) // See above. C.total_damage += detonation_damage + backstab_bonus //cheat a little and add the total before killing it, so certain mobs don't have much lower chances of giving an item L.apply_damage(detonation_damage + backstab_bonus, BRUTE, blocked = def_check) playsound(user, 'sound/weapons/kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong else - if(!QDELETED(C)) + if(C && !QDELING(C)) // See above. C.total_damage += detonation_damage L.apply_damage(detonation_damage, BRUTE, blocked = def_check) From 61b42df4dfd3b4dc8021004582f3eaedeffd6527 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Mon, 1 Apr 2024 19:23:48 -0400 Subject: [PATCH 28/31] Rewrite leashes to have better code quality --- .../game/objects/items/lewd_items/leash.dm | 275 ++++++++---------- 1 file changed, 116 insertions(+), 159 deletions(-) diff --git a/modular_splurt/code/game/objects/items/lewd_items/leash.dm b/modular_splurt/code/game/objects/items/lewd_items/leash.dm index dcb78d4144..9915a6a240 100644 --- a/modular_splurt/code/game/objects/items/lewd_items/leash.dm +++ b/modular_splurt/code/game/objects/items/lewd_items/leash.dm @@ -45,8 +45,7 @@ Icons, maybe? /datum/status_effect/leash_pet/on_apply() - //redirect_component = WEAKREF(owner.AddComponent(/datum/component/redirect, list(COMSIG_LIVING_RESIST = CALLBACK(src, .proc/owner_resist)))) - RegisterSignal(owner, COMSIG_LIVING_RESIST, .proc/owner_resist) + RegisterSignal(owner, COMSIG_LIVING_RESIST, PROC_REF(owner_resist)) redirect_component = owner if(!owner.stat) to_chat(owner, span_userdanger("You have been leashed!")) @@ -79,13 +78,36 @@ Icons, maybe? force = 1 throwforce = 1 w_class = WEIGHT_CLASS_SMALL - var/leash_used = 0 //A flag to see if the leash has been used yet, because for some reason picking up an unused leash is weird - var/mob/living/leash_pet = "null" //Variable to store our pet later - var/mob/living/leash_master = "null" //And our master too + var/mob/living/leash_pet = null //Variable to store our pet later + var/mob/living/leash_master = null //And our master too var/mob/mobhook_leash_pet var/mob/mobhook_leash_master //Needed to watch for these entities to move var/mob/mobhook_leash_freepet - var/leash_location[3] //Three digit list for us to store coordinates later + +/obj/item/leash/process(delta_time) + if(!leash_pet) //No pet, break loop + return PROCESS_KILL + if(!(leash_pet.get_item_by_slot(ITEM_SLOT_NECK))) //The pet has slipped their collar and is not the pet anymore. + leash_pet.visible_message( + span_warning("[leash_pet] has slipped out of their collar!"), + span_warning("You have slipped out of your collar!"), + target = leash_master, + target_message = span_warning("[leash_pet] has slipped out of their collar!") + ) + leash_pet.remove_status_effect(/datum/status_effect/leash_pet) + + if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet)) //If there is no pet, there is no dom. Loop breaks. + //QDEL_NULL(mobhook_leash_master) + UnregisterSignal(mobhook_leash_master, COMSIG_MOVABLE_MOVED) + //QDEL_NULL(mobhook_leash_pet) + UnregisterSignal(mobhook_leash_pet, COMSIG_MOVABLE_MOVED) + //QDEL_NULL(mobhook_leash_freepet) + UnregisterSignal(mobhook_leash_freepet, COMSIG_MOVABLE_MOVED) + leash_pet.remove_status_effect(/datum/status_effect/leash_freepet) + leash_pet.remove_movespeed_modifier(/datum/movespeed_modifier/leash) + leash_master?.remove_status_effect(/datum/status_effect/leash_dom) + leash_pet = null + return PROCESS_KILL //Called when someone is clicked with the leash /obj/item/leash/attack(mob/living/carbon/C, mob/living/user, attackchain_flags, damage_multiplier) //C is the target, user is the one with the leash @@ -103,15 +125,12 @@ Icons, maybe? user.apply_status_effect(/datum/status_effect/leash_dom) //Is the leasher leash_pet = C //Save pet reference for later leash_master = user //Save dom reference for later - //mobhook_leash_pet = leash_pet.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_pet_move))) - RegisterSignal(leash_pet, COMSIG_MOVABLE_MOVED, .proc/on_pet_move) + RegisterSignal(leash_pet, COMSIG_MOVABLE_MOVED, PROC_REF(on_pet_move)) mobhook_leash_pet = leash_pet - //mobhook_leash_master = leash_master.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_master_move))) - RegisterSignal(leash_master, COMSIG_MOVABLE_MOVED, .proc/on_master_move) + RegisterSignal(leash_master, COMSIG_MOVABLE_MOVED, PROC_REF(on_master_move)) mobhook_leash_master = leash_master - leash_used = 1 if(!leash_pet.has_status_effect(/datum/status_effect/leash_dom)) //Add slowdown if the pet didn't leash themselves - leash_pet.add_movespeed_modifier(MOVESPEED_ID_LEASH) + leash_pet.add_movespeed_modifier(/datum/movespeed_modifier/leash) for(var/mob/viewing in viewers(user, null)) if(viewing == leash_master) to_chat(leash_master, span_warning("You have hooked a leash onto [leash_pet]!")) @@ -120,116 +139,90 @@ Icons, maybe? if(leash_pet.has_status_effect(/datum/status_effect/leash_dom)) //Pet leashed themself. They are not the dom leash_pet.apply_status_effect(/datum/status_effect/leash_freepet) leash_pet.remove_status_effect(/datum/status_effect/leash_dom) - while(1) //While true loop. The mark of a genius coder. ##MAINLOOP START - sleep(2) //Check every other tick - if(leash_pet == "null") //No pet, break loop - return - if(!(leash_pet.get_item_by_slot(ITEM_SLOT_NECK))) //The pet has slipped their collar and is not the pet anymore. - for(var/mob/viewing in viewers(user, null)) - viewing.show_message(span_notice("[leash_pet] has slipped out of their collar!!"), 1) - to_chat(leash_pet, span_notice("You have slipped out of your collar!")) - to_chat(loc, span_notice("[leash_pet] has slipped out of their collar!")) - leash_pet.remove_status_effect(/datum/status_effect/leash_pet) - - if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet)) //If there is no pet, there is no dom. Loop breaks. - //QDEL_NULL(mobhook_leash_master) - UnregisterSignal(mobhook_leash_master, COMSIG_MOVABLE_MOVED) - //QDEL_NULL(mobhook_leash_pet) - UnregisterSignal(mobhook_leash_pet, COMSIG_MOVABLE_MOVED) - //QDEL_NULL(mobhook_leash_freepet) - UnregisterSignal(mobhook_leash_freepet, COMSIG_MOVABLE_MOVED) - if(leash_pet.has_status_effect(/datum/status_effect/leash_freepet)) - leash_pet.remove_status_effect(/datum/status_effect/leash_freepet) - if(leash_pet.has_movespeed_modifier(MOVESPEED_ID_LEASH)) - leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH) - if(!leash_master == "null") - leash_master.remove_status_effect(/datum/status_effect/leash_dom) - leash_used = 0 //reset the leash to neutral - leash_pet = "null" - return - + START_PROCESSING(SSfastprocess, src) // The original while loop here ran every 2 deciseconds, and so does SSfastprocess. else //No collar, no fun - var/leash_message = pick("Your pet needs a collar") + var/leash_message = pick("[C] needs a collar before you can attach a leash to it.") to_chat(user, span_notice("[leash_message]")) //Called when the leash is used in hand //Tugs the pet closer /obj/item/leash/attack_self(mob/living/user) - if(!leash_pet == "null") //No pet, no tug. + if(!leash_pet) //No pet, no tug. return //Yank the pet. Yank em in close. apply_tug_mob_to_mob(leash_pet, leash_master, 1) /obj/item/leash/proc/on_master_move() + SIGNAL_HANDLER //Make sure the dom still has a pet - if(leash_master == "null") //There must be a master + if(!leash_master) //There must be a master return - if(leash_pet == "null") //There must be a pet + if(!leash_pet) //There must be a pet return if(leash_pet == leash_master) //Pet is the master return if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet)) - //QDEL_NULL(mobhook_leash_master) //Probably redundant, but it's nice to be safe UnregisterSignal(mobhook_leash_master, COMSIG_MOVABLE_MOVED) + mobhook_leash_master = null leash_master.remove_status_effect(/datum/status_effect/leash_dom) return + addtimer(CALLBACK(src, PROC_REF(after_master_move)), 0.2 SECONDS) +/obj/item/leash/proc/after_master_move() //If the master moves, pull the pet in behind - sleep(2) //A small sleep so the pet kind of bounces back after they make the step - //Also, the sleep means that the distance check for master happens before the pet, to prevent both from proccing. + //Also, the timer means that the distance check for master happens before the pet, to prevent both from proccing. - if(leash_master == "null") //Just to stop error messages + if(!leash_master) //Just to stop error messages return - if(leash_pet == "null") + if(!leash_pet) return apply_tug_mob_to_mob(leash_pet, leash_master, 2) //Knock the pet over if they get further behind. Shouldn't happen too often. sleep(3) //This way running normally won't just yank the pet to the ground. - if(leash_master == "null") //Just to stop error messages. Break the loop early if something removed the master + if(!leash_master) //Just to stop error messages. Break the loop early if something removed the master return - if(leash_pet == "null") + if(!leash_pet) return - if(leash_pet.x > leash_master.x + 3 || leash_pet.x < leash_master.x - 3 || leash_pet.y > leash_master.y + 3 || leash_pet.y < leash_master.y - 3) - //var/leash_knockdown_message = "[leash_pet] got pulled to the ground by their leash!" - //to_chat(leash_master, span_notice("[leash_knockdown_message]")) - //to_chat(leash_pet, span_notice("[leash_knockdown_message]")) + if(get_dist(leash_pet, leash_master) > 3) + leash_pet.visible_message( + span_warning("[leash_pet] is pulled to the ground by their leash!"), + span_warning("You are pulled to the ground by your leash!") + ) leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0) //This code is to check if the pet has gotten too far away, and then break the leash. sleep(3) //Wait to snap the leash - if(leash_master == "null") //Just to stop error messages + if(!leash_master) //Just to stop error messages return - if(leash_pet == "null") + if(!leash_pet) return - if(leash_pet.x > leash_master.x + 5 || leash_pet.x < leash_master.x - 5 || leash_pet.y > leash_master.y + 5 || leash_pet.y < leash_master.y - 5) - var/leash_break_message = "The leash snapped free from [leash_pet]!" - for(var/mob/viewing in viewers(leash_pet, null)) - if(viewing == leash_master) - to_chat(leash_master, span_warning("The leash snapped free from your pet!")) - if(viewing == leash_pet) - to_chat(leash_pet, span_warning("Your leash has popped from your collar!")) - else - viewing.show_message(span_warning("[leash_break_message]"), 1) + if(get_dist(leash_pet, leash_master) > 5) + leash_pet.visible_message( + span_warning("The leash snaps free from [leash_pet]'s collar!"), + span_warning("Your leash pops from your collar!"), + target = leash_master, + target_message = span_warning("The leash snaps free from your pet's collar!") + ) leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0) leash_pet.adjustOxyLoss(5) leash_pet.remove_status_effect(/datum/status_effect/leash_pet) - leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH) + leash_pet.remove_movespeed_modifier(/datum/movespeed_modifier/leash) leash_master.remove_status_effect(/datum/status_effect/leash_dom) - //QDEL_NULL(mobhook_leash_master) UnregisterSignal(mobhook_leash_master, COMSIG_MOVABLE_MOVED) - //QDEL_NULL(mobhook_leash_pet) UnregisterSignal(mobhook_leash_pet, COMSIG_MOVABLE_MOVED) - leash_pet = "null" - leash_master = "null" - leash_used = 0 + mobhook_leash_master = null + mobhook_leash_pet = null + leash_pet = null + leash_master = null /obj/item/leash/proc/on_pet_move() + SIGNAL_HANDLER //This should only work if there is a pet and a master. //This is here pretty much just to stop the console from flooding with errors - if(leash_master == "null") + if(!leash_master) return - if(leash_pet == "null") + if(!leash_pet) return //Make sure the pet is still a pet if(!leash_pet.has_status_effect(/datum/status_effect/leash_pet)) @@ -240,84 +233,43 @@ Icons, maybe? //The pet has escaped. There is no DOM. GO PET RUN. if(leash_pet.has_status_effect(/datum/status_effect/leash_freepet))//If the pet is free, break return - //If the pet gets too far away, they get tugged back - sleep(3)//A small sleep so the pet kind of bounces back after they make the step - if(leash_master == "null") + addtimer(CALLBACK(src, PROC_REF(after_pet_move)), 0.3 SECONDS) //A short timer so the pet kind of bounces back after they make the step + +/obj/item/leash/proc/after_pet_move() + if(!leash_master) return - if(leash_pet == "null") + if(!leash_pet) return - //West tug - if(leash_pet.x > leash_master.x + 2) - step(leash_pet, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed. - //East tug - if(leash_pet.x < leash_master.x - 2) - step(leash_pet, EAST, 1) - //South tug - if(leash_pet.y > leash_master.y + 2) - step(leash_pet, SOUTH, 1) - //North tug - if(leash_pet.y < leash_master.y - 2) - step(leash_pet, NORTH, 1) + for(var/i in 3 to get_dist(leash_pet, leash_master)) // Move the pet to a minimum of 2 tiles away from the master, so the pet trails behind them. + step_towards(leash_pet, leash_master) /obj/item/leash/proc/on_freepet_move() + SIGNAL_HANDLER //Pet is on the run. Let's drag the leash behind them. - if(!leash_master == "null") //If there is a master, don't do this + if(leash_master) //If there is a master, don't do this return - if(leash_pet == "null") //If there is no pet, don't do this + if(!leash_pet) //If there is no pet, don't do this return - if(leash_pet.is_holding_item_of_type(/obj/item/leash)) //If the pet is holding the leash, don't do this + if(leash_pet.is_holding(src)) //If the pet is holding the leash, don't do this return - sleep(2) - if(leash_pet == "null") + //If the pet gets too far away, we get tugged to them. + addtimer(CALLBACK(src, PROC_REF(after_freepet_move)), 0.2 SECONDS, TIMER_UNIQUE) //A short timer so the leash trails behind us. + +/obj/item/leash/proc/after_freepet_move() + if(!leash_pet) return - //Double move to catch the leash up to the pet - if(src.x > leash_pet.x + 2) - . = step(src, WEST, 1) - if(src.x < leash_pet.x - 2) - . = step(src, EAST, 1) - if(src.y > leash_pet.y + 2) - . = step(src, SOUTH, 1) - if(src.y < leash_pet.y - 2) - . = step(src, NORTH, 1) - //Primary dragging code - if(src.x > leash_pet.x + 1) - . = step(src, WEST, 1) //"1" is the speed of movement. We want the tug to be faster than their slow current walk speed. - if(src.y > leash_pet.y)//Check the other axis, and tug them into alignment so they are behind the pet - . = step(src, SOUTH, 1) - if(src.y < leash_pet.y) - . = step(src, NORTH, 1) - if(src.x < leash_pet.x - 1) - . = step(src, EAST, 1) - if(src.y > leash_pet.y) - . = step(src, SOUTH, 1) - if(src.y < leash_pet.y) - . = step(src, NORTH, 1) - if(src.y > leash_pet.y + 1) - . = step(src, SOUTH, 1) - if(src.x > leash_pet.x) - . = step(src, WEST, 1) - if(src.x < leash_pet.x) - . = step(src, EAST, 1) - if(src.y < leash_pet.y - 1) - . = step(src, NORTH, 1) - if(src.x > leash_pet.x) - . = step(src, WEST, 1) - if(src.x < leash_pet.x) - . = step(src, EAST, 1) + + for(var/i in 3 to get_dist(src, leash_pet)) // Move us to a minimum of 2 tiles away from the pet, so we trail behind them. + step_towards(src, leash_pet) sleep(1) //Just to prevent error messages - if(leash_pet == "null") + if(!leash_pet) return - if(src.x > leash_pet.x + 5 || src.x < leash_pet.x - 5 || src.y > leash_pet.y + 5 || src.y < leash_pet.y - 5) - var/leash_break_message = "The leash snapped free from [leash_pet]!" - for(var/mob/viewing in viewers(leash_pet, null)) - if(viewing == leash_pet) - to_chat(leash_pet, span_warning("Your leash has popped from your collar!")) - else - viewing.show_message(span_warning("[leash_break_message]"), 1) + if(get_dist(src, leash_pet) > 5) + leash_pet.visible_message(span_warning("\The [src] snaps free from \the [leash_pet]!"), span_warning("Your leash pops free from your collar!")) leash_pet.apply_effect(20, EFFECT_KNOCKDOWN, 0) leash_pet.adjustOxyLoss(5) leash_pet.remove_status_effect(/datum/status_effect/leash_pet) @@ -326,57 +278,62 @@ Icons, maybe? UnregisterSignal(mobhook_leash_pet, COMSIG_MOVABLE_MOVED) //QDEL_NULL(mobhook_leash_freepet) UnregisterSignal(mobhook_leash_freepet, COMSIG_MOVABLE_MOVED) - leash_pet = "null" - leash_used = 0 + leash_pet = null //The proc below in question is the one causing all the errors apparently /obj/item/leash/dropped(mob/user, silent) //Drop the leash, and the leash effects stop . = ..() - if(leash_pet == "null") //There is no pet. Stop this silliness + if(!leash_pet) //There is no pet. Stop this silliness return - if(leash_master == "null") + if(!leash_master) return //Dropping procs any time the leash changes slots. So, we will wait a tick and see if the leash was actually dropped - addtimer(CALLBACK(src, .proc/drop_effects, user, silent), 1) + addtimer(CALLBACK(src, PROC_REF(drop_effects), user, silent), 1) /obj/item/leash/proc/drop_effects(mob/user, silent) - if(leash_master.is_holding_item_of_type(/obj/item/leash) || istype(leash_master.get_item_by_slot(ITEM_SLOT_BELT), /obj/item/leash)) + SIGNAL_HANDLER + if(leash_master.is_holding(src) || leash_master.get_item_by_slot(ITEM_SLOT_BELT) == src) return //Dom still has the leash as it turns out. Cancel the proc. - for(var/mob/viewing in viewers(leash_master, null)) - viewing.show_message(span_notice("[leash_master] has dropped the leash."), 1) + leash_master.visible_message(span_notice("\The [leash_master] drops \the [src]."), span_notice("You drop \the [src].")) //DOM HAS DROPPED LEASH. PET IS FREE. SCP HAS BREACHED CONTAINMENT. - leash_pet.remove_movespeed_modifier(MOVESPEED_ID_LEASH) - //mobhook_leash_freepet = leash_pet.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_freepet_move))) - RegisterSignal(leash_pet, COMSIG_MOVABLE_MOVED, .proc/on_freepet_move) + leash_pet.remove_movespeed_modifier(/datum/movespeed_modifier/leash) + UnregisterSignal(leash_pet, COMSIG_MOVABLE_MOVED) mobhook_leash_freepet = leash_pet + RegisterSignal(mobhook_leash_freepet, COMSIG_MOVABLE_MOVED, PROC_REF(on_freepet_move)) leash_master.remove_status_effect(/datum/status_effect/leash_dom) //No dom with no leash. We will get a new dom if the leash is picked back up. - leash_master = "null" + leash_master = null //QDEL_NULL(mobhook_leash_master) UnregisterSignal(mobhook_leash_master, COMSIG_MOVABLE_MOVED) /obj/item/leash/equipped(mob/user) . = ..() - if(leash_used == 0) //Don't apply statuses with a fresh leash. Keeps things clean on the backend. + if(!leash_pet) //Don't apply statuses with a petless leash. return - addtimer(CALLBACK(src, .proc/equip_effects, user), 2) + addtimer(CALLBACK(src, PROC_REF(equip_effects), user), 2) /obj/item/leash/proc/equip_effects(mob/user) - if(leash_pet == "null") + if(!leash_pet) + return + if(leash_master == user) + return // Don't double-register. + if(leash_pet == user) //Pet picked up their own leash. + leash_master = null return leash_master = user - if(leash_master.has_status_effect(/datum/status_effect/leash_freepet) || leash_master.has_status_effect(/datum/status_effect/leash_pet)) //Pet picked up their own leash. - leash_master = "null" - return leash_master.apply_status_effect(/datum/status_effect/leash_dom) - //mobhook_leash_master = leash_master.AddComponent(/datum/component/redirect, list(COMSIG_MOVABLE_MOVED = CALLBACK(src, .proc/on_master_move))) - RegisterSignal(leash_master, COMSIG_MOVABLE_MOVED, .proc/on_master_move) + RegisterSignal(leash_master, COMSIG_MOVABLE_MOVED, PROC_REF(on_master_move)) mobhook_leash_master = leash_master leash_pet.remove_status_effect(/datum/status_effect/leash_freepet) //QDEL_NULL(mobhook_leash_freepet) - UnregisterSignal(mobhook_leash_freepet, COMSIG_MOVABLE_MOVED) - leash_pet.add_movespeed_modifier(MOVESPEED_ID_LEASH) + if(mobhook_leash_freepet) + UnregisterSignal(mobhook_leash_freepet, COMSIG_MOVABLE_MOVED) + leash_pet.add_movespeed_modifier(/datum/movespeed_modifier/leash) + +/datum/movespeed_modifier/leash + id = MOVESPEED_ID_LEASH + multiplicative_slowdown = 5 /*/datum/crafting_recipe/leash name = "Leash" From 9befbb33b3e32db28467f51a18d056eb7fe0ad6f Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Mon, 1 Apr 2024 19:25:42 -0400 Subject: [PATCH 29/31] Fix runtime with plant harvester circuit --- code/modules/integrated_electronics/subtypes/manipulation.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/integrated_electronics/subtypes/manipulation.dm b/code/modules/integrated_electronics/subtypes/manipulation.dm index 8be909163d..1aebe11bee 100644 --- a/code/modules/integrated_electronics/subtypes/manipulation.dm +++ b/code/modules/integrated_electronics/subtypes/manipulation.dm @@ -119,7 +119,7 @@ TR.harvest_dead() return list() else - return TR.myseed.harvest_userless() + return TR.myseed?.harvest_userless() /obj/item/integrated_circuit/manipulation/seed_extractor name = "seed extractor module" From ebe7818d1faaa37103928847665206701ca72a78 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Mon, 1 Apr 2024 20:12:11 -0400 Subject: [PATCH 30/31] Fix thrown items runtiming in defense --- code/game/objects/items/shields.dm | 8 ++++---- code/modules/mob/living/living_defense.dm | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/code/game/objects/items/shields.dm b/code/game/objects/items/shields.dm index 1363f0994c..777fe1af8f 100644 --- a/code/game/objects/items/shields.dm +++ b/code/game/objects/items/shields.dm @@ -246,7 +246,7 @@ /obj/item/shield/riot/on_shield_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return) var/final_damage = damage - if(attack_type & ATTACK_TYPE_MELEE) + if(attack_type & (ATTACK_TYPE_MELEE | ATTACK_TYPE_THROWN)) if(istype(object, /obj)) //Assumption: non-object attackers are a meleeing mob. Therefore: Assuming physical attack in this case. var/obj/hittingthing = object if(hittingthing.damtype == BURN) @@ -269,15 +269,15 @@ else if((shield_flags & SHIELD_KINETIC_STRONG)) final_damage *= 0.5 - if(attack_type & ATTACK_TYPE_PROJECTILE) - var/obj/item/projectile/shootingthing = object + var/obj/item/projectile/shootingthing = object + if(attack_type & ATTACK_TYPE_PROJECTILE && istype(shootingthing)) if(is_energy_reflectable_projectile(shootingthing)) if((shield_flags & SHIELD_ENERGY_WEAK)) final_damage *= 2 else if((shield_flags & SHIELD_ENERGY_STRONG)) final_damage *= 0.5 - if(!is_energy_reflectable_projectile(object)) + if(!is_energy_reflectable_projectile(shootingthing)) if((shield_flags & SHIELD_KINETIC_WEAK)) final_damage *= 2 else if((shield_flags & SHIELD_KINETIC_STRONG)) diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index 00cf418e0c..986440b598 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -109,7 +109,7 @@ /mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum) if(!isitem(AM)) // Filled with made up numbers for non-items. - if(mob_run_block(AM, 30, "\the [AM.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum?.thrower, throwingdatum?.thrower?.zone_selected, list())) + if(mob_run_block(AM, 30, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, throwingdatum?.thrower?.zone_selected, list())) hitpush = FALSE skipcatch = TRUE blocked = TRUE @@ -121,7 +121,7 @@ if(thrown_item.thrownby == WEAKREF(src)) //No throwing stuff at yourself to trigger hit reactions return ..() - if(mob_run_block(AM, thrown_item.throwforce, "\the [thrown_item.name]", ATTACK_TYPE_PROJECTILE, 0, throwingdatum?.thrower, throwingdatum?.thrower?.zone_selected, list())) + if(mob_run_block(AM, thrown_item.throwforce, "\the [thrown_item.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, throwingdatum?.thrower?.zone_selected, list())) hitpush = FALSE skipcatch = TRUE blocked = TRUE From d50794333faf73ca2461637c351752a4a5691f15 Mon Sep 17 00:00:00 2001 From: Elizabeth Lavenza Date: Mon, 1 Apr 2024 23:32:38 -0400 Subject: [PATCH 31/31] Fix zweihander kinetic crusher runtimes --- .../code/modules/mining/equipment/kinetic_crusher.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modular_sand/code/modules/mining/equipment/kinetic_crusher.dm b/modular_sand/code/modules/mining/equipment/kinetic_crusher.dm index 7cedccf6ff..5bd8d5815f 100644 --- a/modular_sand/code/modules/mining/equipment/kinetic_crusher.dm +++ b/modular_sand/code/modules/mining/equipment/kinetic_crusher.dm @@ -374,7 +374,7 @@ if(!QDELETED(target)) var/obj/item/crusher_trophy/T = t T.on_melee_hit(target, user) - if(!QDELETED(C) && !QDELETED(target)) + if(C && !QDELING(C) && !QDELETED(target)) // C can be 0 here, and QDELETED will runtime if that's the case. C.total_damage += target_health - target.health //we did some damage, but let's not assume how much we did /obj/item/melee/zweihander/afterattack(atom/target, mob/living/user, proximity_flag, clickparams) @@ -410,18 +410,18 @@ var/obj/item/crusher_trophy/T = t T.on_mark_detonation(target, user) if(!QDELETED(L)) - if(!QDELETED(C)) + if(C && !QDELING(C)) // C can be 0 here, and QDELETED will runtime if that's the case. C.total_damage += target_health - L.health //we did some damage, but let's not assume how much we did new /obj/effect/temp_visual/kinetic_blast(get_turf(L)) var/backstab_dir = get_dir(user, L) var/def_check = L.getarmor(type = "bomb") if((user.dir & backstab_dir) && (L.dir & backstab_dir)) - if(!QDELETED(C)) + if(C && !QDELING(C)) // See above. C.total_damage += detonation_damage + backstab_bonus //cheat a little and add the total before killing it, so certain mobs don't have much lower chances of giving an item L.apply_damage(detonation_damage + backstab_bonus, BRUTE, blocked = def_check) playsound(user, 'sound/weapons/kenetic_accel.ogg', 100, 1) //Seriously who spelled it wrong else - if(!QDELETED(C)) + if(C && !QDELING(C)) // See above. C.total_damage += detonation_damage L.apply_damage(detonation_damage, BRUTE, blocked = def_check)