From 0b3ae62833e80b682cad7b8841a144490744664d Mon Sep 17 00:00:00 2001
From: ariaworld <143797359+ariaworld@users.noreply.github.com>
Date: Mon, 1 Apr 2024 01:11:03 +0200
Subject: [PATCH 01/37] Hopefully fix monkey and slime hard-dels
---
code/game/objects/items/devices/scanners.dm | 3 +--
.../kitchen_machinery/monkeyrecycler.dm | 11 +++++++++++
code/modules/mob/living/simple_animal/slime/death.dm | 7 ++++---
code/modules/mob/living/simple_animal/slime/powers.dm | 5 ++++-
code/modules/mob/living/simple_animal/slime/slime.dm | 5 +++++
5 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/code/game/objects/items/devices/scanners.dm b/code/game/objects/items/devices/scanners.dm
index 34c0b809c4..389c835d1f 100644
--- a/code/game/objects/items/devices/scanners.dm
+++ b/code/game/objects/items/devices/scanners.dm
@@ -861,8 +861,7 @@ GENETICS SCANNER
if (!isslime(M))
to_chat(user, "This device can only scan slimes!")
return
- var/mob/living/simple_animal/slime/T = M
- slime_scan(T, user)
+ slime_scan(M, user)
/proc/slime_scan(mob/living/simple_animal/slime/T, mob/living/user)
var/output = "Slime scan results:"
diff --git a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
index 1f01f1f5eb..2006262b6d 100644
--- a/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
+++ b/code/modules/food_and_drinks/kitchen_machinery/monkeyrecycler.dm
@@ -19,6 +19,7 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
. = ..()
if (mapload)
GLOB.monkey_recyclers += src
+ locate_camera_console()
/obj/machinery/monkey_recycler/Destroy()
GLOB.monkey_recyclers -= src
@@ -28,6 +29,15 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
connected.Cut()
return ..()
+/obj/machinery/monkey_recycler/proc/locate_camera_console()
+ if(length(connected))
+ return // we're already connected!
+ for(var/obj/machinery/computer/camera_advanced/xenobio/xeno_camera in GLOB.machines)
+ if(get_area(xeno_camera) == get_area(loc))
+ xeno_camera.connected_recycler = src
+ connected |= xeno_camera
+ break
+
/obj/machinery/monkey_recycler/RefreshParts() //Ranges from 0.2 to 0.8 per monkey recycled
cube_production = 0
for(var/obj/item/stock_parts/manipulator/B in component_parts)
@@ -75,6 +85,7 @@ GLOBAL_LIST_EMPTY(monkey_recyclers)
to_chat(user, "The monkey is attached to something.")
return
qdel(target)
+ target = null //we sleep in this proc, clear reference NOW
to_chat(user, "You stuff the monkey into the machine.")
playsound(src.loc, 'sound/machines/juicer.ogg', 50, 1)
var/offset = prob(50) ? -2 : 2
diff --git a/code/modules/mob/living/simple_animal/slime/death.dm b/code/modules/mob/living/simple_animal/slime/death.dm
index 5cac0c630c..e23a0383c7 100644
--- a/code/modules/mob/living/simple_animal/slime/death.dm
+++ b/code/modules/mob/living/simple_animal/slime/death.dm
@@ -1,6 +1,10 @@
/mob/living/simple_animal/slime/death(gibbed)
if(stat == DEAD)
return
+
+ if(buckled)
+ Feedstop(silent = TRUE) //releases ourselves from the mob we fed on.
+
if(!gibbed)
if(is_adult)
var/mob/living/simple_animal/slime/M = new(loc, colour)
@@ -18,9 +22,6 @@
update_name()
return
- if(buckled)
- Feedstop(silent = TRUE) //releases ourselves from the mob we fed on.
-
stat = DEAD
cut_overlays()
diff --git a/code/modules/mob/living/simple_animal/slime/powers.dm b/code/modules/mob/living/simple_animal/slime/powers.dm
index d93993bf1f..d4e1cee0d0 100644
--- a/code/modules/mob/living/simple_animal/slime/powers.dm
+++ b/code/modules/mob/living/simple_animal/slime/powers.dm
@@ -170,6 +170,9 @@
to_chat(src, "I must be conscious to do this...")
return
+ if(istype(loc, /obj/machinery/computer/camera_advanced/xenobio))
+ return //no you cannot split while you're in the matrix (this prevents GC issues and slimes disappearing)
+
var/list/babies = list()
var/new_nutrition = round(nutrition * 0.9)
var/new_powerlevel = round(powerlevel / 4)
@@ -187,7 +190,7 @@
M.set_nutrition(new_nutrition) //Player slimes are more robust at spliting. Once an oversight of poor copypasta, now a feature!
M.powerlevel = new_powerlevel
if(i != 1)
- step_away(M,src)
+ step_away(M, get_turf(src))
M.Friends = Friends.Copy()
babies += M
M.mutation_chance = clamp(mutation_chance+(rand(5,-5)),0,100)
diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm
index 5bf1aa858d..d0b8446f50 100644
--- a/code/modules/mob/living/simple_animal/slime/slime.dm
+++ b/code/modules/mob/living/simple_animal/slime/slime.dm
@@ -353,6 +353,7 @@
++Friends[user]
else
Friends[user] = 1
+ RegisterSignal(user, COMSIG_PARENT_QDELETING, PROC_REF(clear_friend))
to_chat(user, "You feed the slime the plasma. It chirps happily.")
var/obj/item/stack/sheet/mineral/plasma/S = W
S.use(1)
@@ -416,6 +417,10 @@
visible_message("The mutated core shudders, and collapses into a puddle, unable to maintain its form.")
qdel(src)
+/mob/living/simple_animal/slime/proc/clear_friend(mob/living/friend)
+ UnregisterSignal(friend, COMSIG_PARENT_QDELETING)
+ Friends -= friend
+
/mob/living/simple_animal/slime/proc/apply_water()
adjustBruteLoss(rand(15,20))
if(!client)
From ccfc08b7a8a555db89ec2dd60def908298401a14 Mon Sep 17 00:00:00 2001
From: Elizabeth Lavenza
Date: Sat, 30 Mar 2024 23:15:50 -0400
Subject: [PATCH 02/37] 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 03/37] 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 04/37] 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 05/37] 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 06/37] 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 07/37] 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 08/37] 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 09/37] 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 10/37] 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 11/37] 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 12/37] 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 13/37] 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 14/37] 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 15/37] 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 16/37] 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 17/37] 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 18/37] 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 19/37] 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 20/37] 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 21/37] 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 22/37] 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 23/37] 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 24/37] 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 25/37] 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 26/37] 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 27/37] 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 28/37] 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 29/37] 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 30/37] 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 31/37] 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 32/37] 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)
From fecf8d1b0257bff6e6ba08333bf6e7cdd87ed3ba Mon Sep 17 00:00:00 2001
From: ariaworld <143797359+ariaworld@users.noreply.github.com>
Date: Wed, 3 Apr 2024 00:38:28 +0200
Subject: [PATCH 33/37] Fix sleep dealing damage
---
code/datums/status_effects/debuffs.dm | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm
index af32731d93..0806f09b72 100644
--- a/code/datums/status_effects/debuffs.dm
+++ b/code/datums/status_effects/debuffs.dm
@@ -1,5 +1,5 @@
/// The damage healed per tick while sleeping without any modifiers
-#define HEALING_SLEEP_DEFAULT 0.005
+#define HEALING_SLEEP_DEFAULT -0.005
//Largely negative status effects go here, even if they have small benificial effects
//STUN EFFECTS
@@ -90,7 +90,7 @@
else if((locate(/obj/structure/chair) in owner.loc))
healing -= 0.0025
if(locate(/obj/item/bedsheet) in owner.loc)
- healing -= 0.005
+ healing -= 0.005
if(health_ratio > 0.75) // Only heal when above 75% health
owner.adjustBruteLoss(healing)
owner.adjustFireLoss(healing)
From 0824f0d768d9cbc2355f3c550ccf79a9265f4076 Mon Sep 17 00:00:00 2001
From: SPLURT Bot <97993072+SPLURT-Station-Bot@users.noreply.github.com>
Date: Tue, 2 Apr 2024 23:31:56 +0000
Subject: [PATCH 34/37] Automatic changelog generation for PR #1133 [ci skip]
---
html/changelogs/AutoChangeLog-pr-1133.yml | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-1133.yml
diff --git a/html/changelogs/AutoChangeLog-pr-1133.yml b/html/changelogs/AutoChangeLog-pr-1133.yml
new file mode 100644
index 0000000000..4c7c834400
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1133.yml
@@ -0,0 +1,4 @@
+author: ariaworld
+delete-after: true
+changes:
+ - bugfix: Sleep now heals instead of dealing damage.
From 7ea53b1ba5c7a16f0ca745ccff306b86bcd39d0d Mon Sep 17 00:00:00 2001
From: Changelogs
Date: Tue, 2 Apr 2024 23:33:28 +0000
Subject: [PATCH 35/37] Automatic changelog compile [ci skip]
---
.../{AutoChangeLog-pr-1133.yml => archive/2024-04.yml} | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
rename html/changelogs/{AutoChangeLog-pr-1133.yml => archive/2024-04.yml} (54%)
diff --git a/html/changelogs/AutoChangeLog-pr-1133.yml b/html/changelogs/archive/2024-04.yml
similarity index 54%
rename from html/changelogs/AutoChangeLog-pr-1133.yml
rename to html/changelogs/archive/2024-04.yml
index 4c7c834400..1e0802fba4 100644
--- a/html/changelogs/AutoChangeLog-pr-1133.yml
+++ b/html/changelogs/archive/2024-04.yml
@@ -1,4 +1,3 @@
-author: ariaworld
-delete-after: true
-changes:
+2024-04-02:
+ ariaworld:
- bugfix: Sleep now heals instead of dealing damage.
From cf9500e9d9f67119527dc2f4add2cd899e49f705 Mon Sep 17 00:00:00 2001
From: SPLURT Bot <97993072+SPLURT-Station-Bot@users.noreply.github.com>
Date: Sat, 6 Apr 2024 17:28:31 +0000
Subject: [PATCH 36/37] Automatic changelog generation for PR #1132 [ci skip]
---
html/changelogs/AutoChangeLog-pr-1132.yml | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 html/changelogs/AutoChangeLog-pr-1132.yml
diff --git a/html/changelogs/AutoChangeLog-pr-1132.yml b/html/changelogs/AutoChangeLog-pr-1132.yml
new file mode 100644
index 0000000000..6e9c94d086
--- /dev/null
+++ b/html/changelogs/AutoChangeLog-pr-1132.yml
@@ -0,0 +1,4 @@
+author: ariaworld
+delete-after: true
+changes:
+ - bugfix: Ported monkey and slime xenobio GC fixes from Paradise Station.
From 84f230b8898bff37c22f56a7ca07f360aa2ca69c Mon Sep 17 00:00:00 2001
From: Changelogs
Date: Sat, 6 Apr 2024 17:29:46 +0000
Subject: [PATCH 37/37] Automatic changelog compile [ci skip]
---
html/changelogs/AutoChangeLog-pr-1132.yml | 4 ----
html/changelogs/archive/2024-04.yml | 3 +++
2 files changed, 3 insertions(+), 4 deletions(-)
delete mode 100644 html/changelogs/AutoChangeLog-pr-1132.yml
diff --git a/html/changelogs/AutoChangeLog-pr-1132.yml b/html/changelogs/AutoChangeLog-pr-1132.yml
deleted file mode 100644
index 6e9c94d086..0000000000
--- a/html/changelogs/AutoChangeLog-pr-1132.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-author: ariaworld
-delete-after: true
-changes:
- - bugfix: Ported monkey and slime xenobio GC fixes from Paradise Station.
diff --git a/html/changelogs/archive/2024-04.yml b/html/changelogs/archive/2024-04.yml
index 1e0802fba4..82df78f725 100644
--- a/html/changelogs/archive/2024-04.yml
+++ b/html/changelogs/archive/2024-04.yml
@@ -1,3 +1,6 @@
2024-04-02:
ariaworld:
- bugfix: Sleep now heals instead of dealing damage.
+2024-04-06:
+ ariaworld:
+ - bugfix: Ported monkey and slime xenobio GC fixes from Paradise Station.